[PIX-13257] Scheduler повторно проверяет terminal status issue перед стартом adapter #211
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "agent/cto/pix-13257"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Что сделано
Scheduler теперь повторно проверяет terminal status целевого issue прямо перед стартом adapter/process, а не только один раз при claim очереди.
shouldStopCancelledExecution()(вызывается перед resolve runtime-skills, перед environment lease и перед стартом adapter) новой функциейcancelRunIfIssueReachedTerminalStatus().done/cancelledуже ПОСЛЕ claim run'а (например, workspace/environment realization заняли несколько секунд, и issue за это время закрыл другой run), run отменяется сerrorCode: issue_terminal_status, execution-lock issue освобождается, отложенные wake промоутятся — по аналогии с уже существующей pre-claim проверкой вevaluateQueuedRunStaleness().resumeIntent/followUpRequestedв contextSnapshot) по-прежнему разрешён — не блокируется.Зачем
CEO heartbeat 2026-07-07 обнаружил live run по уже done issue (PIX-13247): run стартовал через 14 секунд ПОСЛЕ того как issue стал done. Hermes вручную остановил процесс. Корневая причина: между claim (запись run.status=running) и фактическим вызовом adapter.execute() проходит workspace/environment realization (может занимать секунды из-за git worktree + embedded postgres), и в это окно issue мог уже закрыться другим run'ом — но ничего это не перепроверяло.
План тестирования
server/src/__tests__/heartbeat-issue-terminal-status-before-adapter-start.test.ts: мокаетrealizeExecutionWorkspaceуправляемой паузой, переводит issue вdoneпока run "застрял" внутри workspace realization, снимает паузу и проверяет что run отменяется сissue_terminal_status, а adapter НИКОГДА не вызывается. Второй тест подтверждает что explicit resume (resumeIntent: true) всё ещё нормально доходит до adapter. Оба теста зелёные.pnpm run typecheck(полный, все пакеты) — 0 ошибок.pnpm exec vitest run server/src/__tests__/heartbeat-stale-queue-invalidation.test.ts— 12/14 passed; 2 падения предсуществующие и НЕ связаны с этим PR (подтверждено черезgit stashbisect моего diff — падают идентично с фиксом и без него). Заведена отдельная задача PIX-13260 на эти 2 теста с root-cause анализом.scripts/check-not-shared-root-push.mjs(PIX-12727, отсутствовал в package.json этой ветки) и помечена как allowed одна ложно-положительная строка вgit-delivery-gate.ts(человекочитаемый текст инструкции внутри error message, не реальный вызов git push).Где могу ошибаться
before_adapter_startи фактическим вызовомadapter.execute()(ensureRuntimeServicesForRun + несколько DB-записей) — не перекрыто новой проверкой, т.к. потребовало бы отдельной cleanup-логики для уже запущенных runtime-сервисов. Основной инцидент (14-секундная задержка) приходится на workspace realization, которая перекрывается новой проверкой полностью.check-no-git-push.mjs (adapter/runtime code must never call git push itself) flagged this file's human-readable remediation string ("1. git push origin <branch>...") surfaced inside an error message for an operator/agent to run manually. It is not an actual git push invocation, so annotate it with the script's own documented paperclip:allow-git-push opt-in instead of leaving every push from this branch blocked by a false positive.Доп. коммит
62e4ec607: чиню heartbeat-static-regression.test.ts —337d252faдобавил аргумент issueId в вызовы shouldStopCancelledExecution("before_adapter_start"/"before_environment_lease"), а этот тест проверял точный текст вызова без нового аргумента (2 из 3 упавших ассертов). Заодно поправил 1 несвязанный pre-existing разъезд в том же файле (promoteDueScheduledRetries(now) vs ожидаемый new Date()) — подтверждено идентично на чистом origin/master, не моя регрессия.Локально зелено: heartbeat-issue-terminal-status-before-adapter-start.test.ts 2/2, heartbeat-static-regression.test.ts 81/81, pnpm exec tsc --noEmit — 0 ошибок. CI на раннерах сейчас подвисает в очереди (waiting/blocked) по всему репозиторию, не специфично для этого PR — подтверждено через forgejo_actions_queue_sweeper.py (0 orphaned/stale кандидатов). Смержу как только CI дойдёт до success.