# run_js: отдельный аудит упрощения

Снимок аудита: 28–29.10.2026. Обновлённая основа — `7032f4aa`.
Поставленные другим чатом Silero/batch и расширение 2.0.0 сохранены; их удаления не входят в наши результаты.
Изменения выполняются в `codex/chat-agent-run-js`, отдельно от параллельной аудиоработы.
Это промежуточный отчёт по исходникам и локальным проверкам, а не подтверждение поставки run_js.

## Метод и границы

Проверены исходники приложения, расширения, Monitor, SQL-схема, регистрации команд,
тесты, зависимости и ссылки из CI/Compose. 29.10 построен отдельный структурный индекс
Repowise 0.55.0 этого checkout (без LLM, editor setup и hooks); использованы overview,
context, risk и dead_code через MCP данного каталога. Выводы сверены с исходниками. Отсутствие статического вызова
само по себе не использовалось как основание для удаления.

В рабочем Monitor 28.10.2026 в 14:20–14:21 UTC прочитан каталог из 16 таблиц и заголовки
127 столбцов. Имена и типы полей 15 прикладных таблиц совпали с локально созданной схемой.
Шестнадцатая таблица — системная `spatial_ref_sys` PostGIS; она не является мусором приложения.
Пользовательские строки в отчёт и fixtures не копировались.

Индексы и триггеры перечислены по исходникам и проверены на отдельной PostgreSQL 16.
Их фактический состав и статистика использования в production через интерфейс Monitor
не доступны; отсутствие production-обращений к индексу здесь не утверждается.
Накопленные данные, таблицы, поля, индексы и триггеры не удаляются.

## Перечень кандидатов и решений

| Кандидат | Назначение и потребители | Стоимость / риск | Решение и проверка |
|---|---|---|---|
| Метаданные столбцов каталога Monitor | `src_api_gateway/monitor.py`, действие `catalog`; UI «Все таблицы» | Один полный запрос метаданных на каждую таблицу, хотя нужны только два временных столбца | **Реализовано:** один общий запрос нужных имён. Состав таблиц, даты, описания и счётчики сохранены; парный benchmark и PostgreSQL regression test |
| `Database.fetchrow`, `fetch`, `transaction` | Обёртка Agent `src_agent/utils/db.py`; реальные владельцы используют `_pool`, `execute`, `fetchval` и fencing | Три невостребованных метода поверх asyncpg | **Удалено:** поиском проверены класс, импорты и его потребители; owner recovery integration прошёл |
| `docker/cpp/Dockerfile`, `docker/whisper/Dockerfile` | Ссылались на уже отсутствующие `src_whisper_c` и `src_whisper.main` | Два неиспользуемых рецепта сборки | **Удалено:** CI, build labels и оба Compose не используют эти Dockerfile; действующие ASR Dockerfile сохранены |
| Девять неиспользуемых имён import | Восемь файлов Agent/Core/Gateway/LLM/shared | Мёртвые локальные имена; удаление публичных re-export было бы регрессией | **Удалены только локальные имена:** реэкспорты контрактов сохранены; Python suite и проверки frontend-ссылок на исходники |
| `NatsPublisher` в LLM | Нет импортов или динамической регистрации; действующий NatsLogger использует `to_json_safe` напрямую | Неиспользуемая обёртка отправки, 17 строк | **Удалён файл**, общий `to_json_safe` сохранён |
| `audioTrackFields`, `readAsrBackend`, `aviation.distance` | Нет локальных/межмодульных вызовов; настройки микрофона, выбор модели и geodesy имеют действующих владельцев | Три невостребованные функции | **Удалены**; алгоритмы ASR и геодезии сохранены |
| `voiceLabels`, `FORMS_ORIGIN` | Используются внутри своих модулей, не импортируются снаружи | Лишние export | **Сделаны локальными**, значения и проверки origin сохранены |
| Кандидаты Repowise с непрямыми входами | Gateway domain_api/browser_api, VAD worker, release probes | Статический граф пропускает module import, Worker URL и передачу файла в контейнер | **Сохранены:** startup/shutdown main.py; BrowserVad Worker; chat_nats_release.rb:448; preflight.sh:24 |
| Два реестра DOM-целей | `form-collector.js` и `domCommands.ts` | Повторные ссылки/обходы; разные условия жизненного цикла | **Реализовано:** один реестр collector, максимум 1000 ссылок; прежние ref не переназначаются другим узлам |
| Полный обход collector | Формы, ручной сбор, `input_list` | Полный список до ограничения ответа | **Реализовано:** ленивый поиск останавливается после порции + одного совпадения; ручной сбор ограничен общим реестром и сообщает о неполном результате |
| Два пути выполнения инструментов | `content.ts` напрямую вызывает PageTools, отдельные команды используют LocalMcp | Дублирование ошибок, trace и жизненного цикла | **Реализовано:** один LocalMcp/run_js; удалены PageTools, DomCommands и их отдельный реестр |
| Результаты между вопросами | `widget_cache.results`, `WidgetStore.cache_result`, Agent instructions | Чтение и запись результатов старых read-tools | **Реализовано в исходниках:** удалены cache_result, PageCachePart, обновление кэша в истории и его пересылка Core. Запрос читает только каталог. Физический столбец и старые данные сохранены |
| Повторная инициализация timestamp-схемы | `WidgetStore.initialize` из Gateway и Agent; `monitor_schema.initialize` | Повторные DDL, lock, проверка таблиц, пересоздание триггеров | **Отложено:** порядок создания таблиц различается; простое удаление одного вызова оставит часть новых таблиц без временных полей. Нужна отдельная проверка владельца миграции |
| `chat_agent_touch_times` | 11 прикладных таблиц, фильтр «Изменения» в Monitor | JSON-сравнение строк при UPDATE | **Сохранён:** отличает фактическое изменение от повторной записи, не выдумывает даты старых строк |
| `monitor_*_updated_idx` | Интервал `created_at OR updated_at`, в том числе динамический Monitor | Дополнительные записи в индекс | **Не удалять без plan/statistics:** малый размер fixture не доказывает ненужность индекса на production |
| `audio_recordings.id` / `stream_id` | Текущее хранение и внешний аудиопротокол | Исторический кандидат на дублирование | **Уже упрощено до нашей работы:** физического `stream_id` в таблице нет; повторно это улучшение не засчитывается |
| `manifest` / `pending_receipt` | Независимая проверка браузерных блоков и позднее подтверждение фразы | Промежуточные строки | **Уже очищаются текущим AudioStore:** после применения и при инициализации. Защиту независимых хешей не удалять |
| История и события перед пагинацией | `TrafficStore.history`, `monitor_requests`, `monitor_details` | SQL агрегации большой сессии; полная предзагрузка в браузер не нужна | **Сохранено:** page/limit применяется в SQL. Рекурсивная привязка события к запросу нужна для причинной цепочки; нельзя заменять её совпадением времени |
| Очереди, timeout, owner и квитанции | `execution`, Agent owner, browser receipts, аудиодопуск | Ограничивают RAM и повторное исполнение | **Сохранены:** это работающие защиты, а не лишние состояния |
| Frontend-зависимости | MCP, NATS, markdown, MapLibre, buffer, ONNX и resampler имеют реальные импорты | Удаление ломает чат, карту либо новый аудиопуть | **Сохранены:** аудиозависимости принадлежат параллельной работе |
| Python-зависимости | HTTP/NATS, Pydantic AI, telemetry, токенизация и архив | Возможны транзитивные потребители, в том числе корпоративный `otel` | **Не удалены по одному grep:** отсутствие прямого импорта не доказывает отсутствие runtime-зависимости |
| Старые ручные release/retirement jobs | Штатные delivery scripts, проверки и runbooks | Потенциально устаревшие сценарии | **Сохранены:** текущая параллельная поставка использует release-контур. Удалять без проверки всех процедур восстановления нельзя |

## Проверка схемы и владельцев

Идентификаторы ниже принадлежат разным границам: `session_id` — общая история,
`context_id` — конкретная страница, `client_id` — подключение, `request_id` — вопрос,
`tool_call_id` — инструмент. Их объединение потеряет изоляцию вкладок или защиту повторной доставки.

| Таблица | Запись / чтение и причина сохранения |
|---|---|
| `audio_recordings` | AudioStore, архив/список потоков/replay; параметры и состояние полной записи |
| `audio_chunks` | AudioStore, порционное чтение PCM/waveform/экспорт; неизменяемые блоки и проверка manifest/hash |
| `audio_phrases` | AudioStore, запросы/диагностика/receipt; границы и сопоставление запроса с исходной фразой |
| `audio_recording_events` | AudioStore, журнал записи; параметры, события и неприменённые подтверждения |
| `nats_log` | TrafficStore, Monitor, read-only проекция общей истории; payload_ref предотвращает дублирование тела |
| `widget_cache` | WidgetStore, регистрация каталога; старый results больше не читается приложением; ключ `(session_id, context_id)` необходим |
| `browser_command_receipts` | WidgetStore/AviationStore/ChatNotes; идемпотентность, результат и статус запроса |
| `browser_access` | BrowserApi/bootstrap/auth/maintain; сроки транспорта и lease решают разные задачи |
| `browser_connect_tickets` | BrowserApi.redeem/maintain; одноразовые билеты, просроченные очищаются |
| `chat_agent_owner` | Database/Agent и owner recovery; эпоха единственного владельца |
| `chat_notes` | ChatNotes и пользовательская заметка; текст и version защищают от потери обновления |
| `aviation_demo` | AviationStore, карта/справочник; общий каталог с revision |
| `aviation_positions` | AviationStore, карта/действия; положение и revision по сессии |
| `aviation_plans` | AviationStore, план по `(session_id,name)`; optimistic revision |
| `aviation_weather` | AviationStore, карта/погода; успешные данные, последняя попытка и её ошибка различаются |
| `spatial_ref_sys` | Системная таблица PostGIS; отдельный владелец схемы |

Все поля доступны также через динамический Monitor. Это дополнительный потребитель,
но не самостоятельное доказательство полезности любого поля: для удаления нужен разбор
прикладного назначения и накопленных данных. Такого доказанного удаления на этом этапе нет.

## Измерение каталога Monitor

Отдельный PostgreSQL 16, 16 таблиц (15 прикладных + таблица fixture без дат), 10 000
вымышленных событий. Один pool/процесс, фиксированный интервал, чередование старой
и новой реализации: 3 прогрева и 20 учитываемых повторов каждой. Ответы совпали во всех
23 парах. Считаются SQL каталога, без одинаковых BEGIN/SET LOCAL/COMMIT обёртки MonitorReads.

| Метрика | Было | Стало | Разница | Изменение |
|---|---:|---:|---:|---:|
| SQL на каталог | 32 | 17 | −15 | −46,88% |
| Медиана | 9,8115 мс | 5,063 мс | −4,7485 мс | −48,40% |
| p95, nearest rank, n=20 | 11,261 мс | 5,630 мс | −5,631 мс | −50,00% |
| Ошибки | 0 | 0 | 0 | — |

Это локальное измерение. Время открытия страницы production, CPU, память, ASR, LLM-токены
и размер production-БД этим экспериментом не измерялись. Данные не удалены, будущая
запись аудио не изменена. Удаление строк кода не объявляется ускорением.

Воспроизводимый скрипт, исходный модуль до изменения и сырые 20 результатов находятся
в локальном evidence-каталоге `run-js-p0-20261028` рядом с изолированной страницей P0.

## Проверки и граница поставки

- Native P0 **PASS** в основном Chat Agent 2.1.0: Chrome USER_SCRIPT, Promise,
  строгий JSON и точный документ при CSP тестовой страницы без unsafe-eval.
- Коммит совместимости `0b8ed121`: пять обязательных checks pipeline 5500 **PASS**;
  backend job 26343 **PASS**, проверены revisions/digests пяти адресных сервисов.
- Удаление временной совместимости проверено локально: 28 Python/PG tests + 2 subtests;
  43 frontend tests истории, панели и source links; 10 DOM runtime tests, включая
  общий предел реестра. Исторические результаты в PostgreSQL не изменяются.
- Полный модельный сценарий и поставка окончательного SHA фиксируются отдельным
  итоговым отчётом после обновления основного пакета в Chrome.
- По просьбе владельца от 29.10 ручные проверки сокращены до необходимого пути
  run_js; микрофон не проверяется. Соседняя Silero/audio работа сохранена.

Новые сервисы, NATS-соединения, таблицы, зависимости и отдельные хранилища не добавлены.
Старые результаты остаются доступны динамическому Monitor. Физическое удаление
столбца results и накопленных значений требует отдельного согласования.
