[epic] Стабилизация AI-пайплайна и смежных подсистем — зонтик итераций #497

Open
opened 2026-07-11 02:08:30 +03:00 by agent_vscode · 0 comments
Collaborator

Зонтик цикла стабилизации: ~70 правок, скомпонованных в 11 итераций. Каждая итерация = один PR в develop, каждая фича внутри — отдельный коммит (состав и порядок коммитов — в теле соответствующего ишью). Спеки прошли adversarial-ревью (3 независимых критика × 3 раунда, convergence-validation, cold-reader гейт внешней моделью — список вопросов пуст).

Диагноз (4 системных корня)

  1. Нет дисциплины объёма данных: полный реплей истории провайдеру каждый ход, полная перезапись jsonb-строки на каждом шаге с ДУБЛИРОВАНИЕМ tool-outputs (127–510 МБ записи за марафонский ран), 32–64 МБ реестр-буфер на ран, full-refetch поллинга, full-reparse markdown — «тормозит», а длинный чат терминально умирает об контекст-окно. → #490, #491, #492.
  2. Терминальный жизненный цикл размазан по best-effort-фолбэкам: finalizeRun с ретраями, finalizeAssistant без; свипы boot-only с разными окнами; legacy вообще без гейта конкурентности; фолбэк beginRun даёт неостанавливаемый ран — «глючит», раны/строки застревают. → #486 (к.4), #487.
  3. Клиентская FSM — аккреция: 26 useRef c one-shot-флагами; комбинации без владельца (обрыв до первого кадра, второй обрыв, истёкший кап поллинга, user-tail) молча замораживают UI. → #488.
  4. Процессный корень «локально верно — интеграционно не проверено»: тестировались чистые функции, а не наблюдаемые свойства (реальный WAL, реальные SSE-байты, реальные error-шейпы) — правило для всех итераций: интеграционный тест наблюдаемого свойства обязателен для кэшей/заголовков/буферов/FSM-переходов; тест прокси-величины тестом не считается.

Итерации и порядок

Волна А (прод горит, можно параллельно):

  • #486 — итерация 1: прод-пожары и безопасность (ELK-воркер, redis-leak, metrics bind, beginRun fail-fast, share-утечка → closes #394, drain-патч ai, пакет мелочи)

Волна B (корректность стриминга, строго по порядку):

  • #487 — итерация 2: терминальный жизненный цикл (race-on-abort тулов → зомби/settledPromise/условные UPDATE → единый гейт + supersede CAS → reconcile) — после #486
  • #488 — итерация 3: клиентский FSM (каркас+приложение → обрыв до первого кадра, второй обрыв, stalled, классификация) — после #487
  • #489 — итерация 4: устойчивость тулов (валидация parts, MCP-кэш per-server, ретраи по write-классу) — после #487, параллельно #488

Волна C (дисциплина данных):

  • #490 — итерация 5: дедуп tool-outputs (трейс v2), токен-бюджет + реактивная ветка — независима
  • #491 — итерация 6: resume-стек (дельта-поллинг, step-маркер, step-aligned registry + tail-only attach) — после #488, желательно #490
  • #492 — итерация 7: инкрементальный рендер + append-персист — после #491

Волна D (целостность данных и хвосты, независимы):

  • #493 — итерация 8: конвертер (block-escape, атрибутный contract-тест, дедуп зеркал, resolved-якоря)
  • #494 — итерация 9: MCP-гарды зеркал + write-целостность — после #489
  • #495 — итерация 10: хвосты (AI-транспорт gemini/ollama, вендорные патчи, guard'ы петель, мелкая безопасность, S51–S61) — коммит 2 после #486
  • #496 — итерация 11: suggestions/комментарии (audit trail, expectedText, marks при apply, orphan-reconcile)

Волна E (агентский фидбек-пакет 11.07, обсуждён с владельцем; #501 прошёл полный adversarial-designer цикл — 3 критика × re-attack):

  • #501 — API-ключи для агентов, фаза 1 (сервер): выдача (REST) + приём api_key на /mcp вместо bcrypt-Basic + fail-closed дискриминатор collab-токенов + kill-switch. Независим от всех волн. Провенанс-пункт пересекается с #486 к.11 (если смержен — схлопывается в тест)
  • #506 — API-ключи, фаза 2 (UI): страница настроек список/создание/показ-один-раз/revoke. Blocked by #501
  • #503 — hardBreak непредставим в markdown-каноне (сериализатор + импортер, обе стороны). Пересекается по файлам с #493 (markdown-converter.ts, importer): делать ПОСЛЕ #493 или тем же PR, не параллельно
  • #502 — убрать math/автолинк голых доменов из MCP-markdown-записи (без флагов; формулы — через JSON) + format:"text" для машинного диффа. Тот же конвертер-стек: после #493/#503 (text-режим зависит от \n-семантики hardBreak из #503)

Связанные существующие: #394 (закрывается итерацией 1), #347 (клиентский конвертер — уточнение объёма в комментарии там), #450/#449 (распил client.ts и инварианты конкурентности — вне этого зонтика), #479/#480 (getPage-кэш — закрыт до зонтика).

Сквозные правила для всех итераций

  1. Координаты file:line в ишью сняты с develop@363f20ab — перед работой перегенерировать по текущему develop.
  2. Каждая фича = отдельный коммит с тестом; ни один PR не смешивает итерации.
  3. После мержа #488: новые ref-флаги в chat-thread.tsx запрещены — новое поведение = состояние/переход автомата с unit-тестом.
  4. Все in-memory механизмы (реестр, active-map, зомби/settledPromise, лизы) — single-process по допущению фазы 1; допущение повторяется в комментарии у каждого механизма; multi-instance — отдельная фаза 2.
  5. Каждое «известное ограничение» в комментарии кода — с номером issue; комментарий без issue фиксацией долга не считается.
  6. «Mirror this»-комментарий гардом не считается: ручное зеркало — либо деривация, либо parity-тест в CI (#494 — образец).
Зонтик цикла стабилизации: ~70 правок, скомпонованных в 11 итераций. Каждая итерация = один PR в develop, каждая фича внутри — отдельный коммит (состав и порядок коммитов — в теле соответствующего ишью). Спеки прошли adversarial-ревью (3 независимых критика × 3 раунда, convergence-validation, cold-reader гейт внешней моделью — список вопросов пуст). ## Диагноз (4 системных корня) 1. **Нет дисциплины объёма данных**: полный реплей истории провайдеру каждый ход, полная перезапись jsonb-строки на каждом шаге с ДУБЛИРОВАНИЕМ tool-outputs (127–510 МБ записи за марафонский ран), 32–64 МБ реестр-буфер на ран, full-refetch поллинга, full-reparse markdown — «тормозит», а длинный чат терминально умирает об контекст-окно. → #490, #491, #492. 2. **Терминальный жизненный цикл размазан по best-effort-фолбэкам**: finalizeRun с ретраями, finalizeAssistant без; свипы boot-only с разными окнами; legacy вообще без гейта конкурентности; фолбэк beginRun даёт неостанавливаемый ран — «глючит», раны/строки застревают. → #486 (к.4), #487. 3. **Клиентская FSM — аккреция**: 26 useRef c one-shot-флагами; комбинации без владельца (обрыв до первого кадра, второй обрыв, истёкший кап поллинга, user-tail) молча замораживают UI. → #488. 4. **Процессный корень «локально верно — интеграционно не проверено»**: тестировались чистые функции, а не наблюдаемые свойства (реальный WAL, реальные SSE-байты, реальные error-шейпы) — правило для всех итераций: интеграционный тест наблюдаемого свойства обязателен для кэшей/заголовков/буферов/FSM-переходов; тест прокси-величины тестом не считается. ## Итерации и порядок **Волна А (прод горит, можно параллельно):** - [ ] #486 — итерация 1: прод-пожары и безопасность (ELK-воркер, redis-leak, metrics bind, beginRun fail-fast, share-утечка → closes #394, drain-патч ai, пакет мелочи) **Волна B (корректность стриминга, строго по порядку):** - [ ] #487 — итерация 2: терминальный жизненный цикл (race-on-abort тулов → зомби/settledPromise/условные UPDATE → единый гейт + supersede CAS → reconcile) — после #486 - [ ] #488 — итерация 3: клиентский FSM (каркас+приложение → обрыв до первого кадра, второй обрыв, stalled, классификация) — после #487 - [ ] #489 — итерация 4: устойчивость тулов (валидация parts, MCP-кэш per-server, ретраи по write-классу) — после #487, параллельно #488 **Волна C (дисциплина данных):** - [ ] #490 — итерация 5: дедуп tool-outputs (трейс v2), токен-бюджет + реактивная ветка — независима - [ ] #491 — итерация 6: resume-стек (дельта-поллинг, step-маркер, step-aligned registry + tail-only attach) — после #488, желательно #490 - [ ] #492 — итерация 7: инкрементальный рендер + append-персист — после #491 **Волна D (целостность данных и хвосты, независимы):** - [ ] #493 — итерация 8: конвертер (block-escape, атрибутный contract-тест, дедуп зеркал, resolved-якоря) - [ ] #494 — итерация 9: MCP-гарды зеркал + write-целостность — после #489 - [ ] #495 — итерация 10: хвосты (AI-транспорт gemini/ollama, вендорные патчи, guard'ы петель, мелкая безопасность, S51–S61) — коммит 2 после #486 - [ ] #496 — итерация 11: suggestions/комментарии (audit trail, expectedText, marks при apply, orphan-reconcile) **Волна E (агентский фидбек-пакет 11.07, обсуждён с владельцем; #501 прошёл полный adversarial-designer цикл — 3 критика × re-attack):** - [ ] #501 — API-ключи для агентов, фаза 1 (сервер): выдача (REST) + приём api_key на /mcp вместо bcrypt-Basic + fail-closed дискриминатор collab-токенов + kill-switch. Независим от всех волн. Провенанс-пункт пересекается с #486 к.11 (если смержен — схлопывается в тест) - [ ] #506 — API-ключи, фаза 2 (UI): страница настроек список/создание/показ-один-раз/revoke. **Blocked by #501** - [ ] #503 — hardBreak непредставим в markdown-каноне (сериализатор + импортер, обе стороны). **Пересекается по файлам с #493** (`markdown-converter.ts`, importer): делать ПОСЛЕ #493 или тем же PR, не параллельно - [ ] #502 — убрать math/автолинк голых доменов из MCP-markdown-записи (без флагов; формулы — через JSON) + `format:"text"` для машинного диффа. Тот же конвертер-стек: после #493/#503 (text-режим зависит от `\n`-семантики hardBreak из #503) **Связанные существующие:** #394 (закрывается итерацией 1), #347 (клиентский конвертер — уточнение объёма в комментарии там), #450/#449 (распил client.ts и инварианты конкурентности — вне этого зонтика), #479/#480 (getPage-кэш — закрыт до зонтика). ## Сквозные правила для всех итераций 1. Координаты file:line в ишью сняты с develop@363f20ab — перед работой перегенерировать по текущему develop. 2. Каждая фича = отдельный коммит с тестом; ни один PR не смешивает итерации. 3. После мержа #488: новые ref-флаги в chat-thread.tsx запрещены — новое поведение = состояние/переход автомата с unit-тестом. 4. Все in-memory механизмы (реестр, active-map, зомби/settledPromise, лизы) — single-process по допущению фазы 1; допущение повторяется в комментарии у каждого механизма; multi-instance — отдельная фаза 2. 5. Каждое «известное ограничение» в комментарии кода — с номером issue; комментарий без issue фиксацией долга не считается. 6. «Mirror this»-комментарий гардом не считается: ручное зеркало — либо деривация, либо parity-тест в CI (#494 — образец).
agent_vscode added the epic label 2026-07-11 02:08:31 +03:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: vvzvlad/gitmost#497