Ребейз на обновлённый feat/490 (PR #510, Option-A): стек #491 перенесён с
6e872f2d на 6e42752a; run-fsm.ts/chat-thread.tsx приехали из develop-версии
(W1/S4: RUN_ALREADY_ACTIVE несёт activeRunId + supersede-CAS адопция) — мои
#491-правки легли сверху без конфликтов, W1 НЕ откачен (run-fsm.ts == develop
байт-в-байт; RUN_ALREADY_ACTIVE диспатчит activeRunId).
1. [CI-fidelity] Дельта-курсор спек падал в CI unit-лейне: `.spec.ts` дефолтил
на НЕмигрированный docmost → 5/6 ERROR relation does not exist (skip-гард ловит
только connection-fail). Переименован в `*.int-spec.ts` (исключается из unit-
regex `.spec.ts$`, гоняется в test:int, чей global-setup мигрирует docmost_test)
+ DSN по умолчанию → docmost_test. Теперь 6/6 реально исполняются в CI-верном
окружении; overlap-мутация роняет RACE-тесты (не вакуумен).
2. [regression #137/#161] attach: отсутствие `n` схлопывалось в frontier 0 →
finished-неротированный ран (coverageFloor 0) отдавал ВЕСЬ tail вместо 204;
парамслесс/легаси-вкладка допишет полный replay → дубль. Различаем ОТСУТСТВИЕ
`n` (null — не tail-aware) от `n=0` (tail-aware): контроллер шлёт null при
missing/invalid; registry.attach(n: number|null) 204-ит finished-ран при
n===null (старый `finished && !expectLive` гейт), n=0 по-прежнему отдаёт хвост.
Тесты (registry + controller) + mutation-verify: нейтрализация гейта роняет их.
4. [conventions] Ring-кап env-var переименован RUN_STREAM_MAX_BUFFER_BYTES →
AI_CHAT_RUN_STREAM_MAX_BUFFER_BYTES (префикс как у сиблингов) + запись в
.env.example (дефолт 4MB, 0/invalid→дефолт, subscriber-cap=2×).
5. [docs] run-fsm.spec.md: item4 переписан («реализовано в #491 — дельта несёт
run:{id,status}|null; клиент run-поле ещё не потребляет») + добавлена строка
перехода POLL_IDLE_CAP stopping→idle (Review #4, редьюсер это делает).
6. [simplification] Удалена мёртвая цепочка reconstructRunParts /
reconstructPartsFromRow (ноль прод-вызовов) + опц. messageRepo-инъекция в
AiChatRunService + спек-блоки; вернётся с первым реальным вызывателем. Маркер
metadata.stepsPersisted (реально используемый) сохранён.
DROP-пункты ревьюера (осиротевший import, DELTA_POLL_MAX_ROWS) не трогаю.
Прогон: server tsc 0, ai-chat unit 202, delta-int 6/6 (int-lane), int attach 6/6,
client vitest 403, tsc client 0 ai-chat, mcp 834/0. FSM-инварианты #488 сохранены.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -302,6 +302,16 @@ MCP_DOCMOST_PASSWORD=
|
||||
# enabled for a workspace, and the same single-instance constraint applies (the
|
||||
# registry is process-local).
|
||||
# AI_CHAT_RESUMABLE_STREAM=false
|
||||
#
|
||||
# Per-run replay ring cap (#491), in BYTES, for the resumable-stream registry
|
||||
# above. The registry buffers the run's recent SSE tail so a reopened tab can
|
||||
# attach and continue from the step it already persisted; the ring is bounded and
|
||||
# rotates on every confirmed step-persist. This caps the un-persisted tail between
|
||||
# rotations — an overflow evicts the oldest frames and a late attach falls back to
|
||||
# 204 -> degraded poll, so correctness never depends on the size. Default 4194304
|
||||
# (4MB); a 0/invalid value falls back to the default. The per-subscriber backpressure
|
||||
# cap is derived as 2x this value. Only meaningful with AI_CHAT_RESUMABLE_STREAM on.
|
||||
# AI_CHAT_RUN_STREAM_MAX_BUFFER_BYTES=4194304
|
||||
|
||||
# --- Run lifecycle tunables (#487) ---
|
||||
# These govern the universal run machinery (every turn is now a first-class run,
|
||||
|
||||
Reference in New Issue
Block a user