You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Context — field experience (kntnt-extractor, 2026-07-22, orchestrate 0.16.1; and earlier larger runs)
A 3-issue merge-mode run was killed mid-run by a Claude Code session restart (field trigger, reproducible across several runs: entering the agent view with arrow-left to check progress, then leaving it → a "compact memory?" prompt appears → the background workflow is already dead; the TUI behavior itself is a harness matter outside this plugin, but the plugin must survive it). The completion notification suggested relaunching with resumeFromRunId. That was done — with byte-identical script and args — but Workflow resume is same-session-only, and nothing detected the mismatch: the "resume" silently got zero cache hits and re-ran the entire plan from scratch.
Consequences observed: the engine re-implemented issue #15 — already independently verified and landed on the default branch — from zero on a new branch; the verifier panel flagged the duplication (high severity), a fix round made the branch tree-identical to main, integrate hit a conflict, reconcile rebased, and three redundant commits landed anyway. The engine was in the middle of the same expensive dance for the also-already-landed #16 when the run was manually stopped and a hand-scoped #17-only run finished the job. In an earlier, larger field run the same failure mode compounded across restarts into 50+ agents and 50+ branches, all wasted.
Root cause
A dead resume degrades silently to a full re-run.resumeFromRunId is same-session-only, but neither the skill nor the engine detects a cross-session resume; the launch proceeds with an empty cache and no warning.
The engine has no idempotence guard. It never checks whether an issue's work already landed before dispatching an implementer. "Landed" exists only in the orchestrator session's memory — lost with the session — and in git history no agent is told to consult.
GitHub state cannot disambiguate. Issues are closed only at finalize, so after a mid-run crash a fully-landed issue is indistinguishable from an untouched one by its open/closed state.
Proposed fix
Durable per-issue landed-marker (shared mechanism with orchestrate: continuous out-of-band progress reporting for multi-hour runs (status command + durable milestone markers) #48). At integrate time, record the landing durably and machine-readably — recommended: a structured comment on the GitHub issue (e.g. orchestrate: landed <sha> on <default-branch>, run <runId>), posted by the integrate step (already the authorized mutator). Decision D1: additionally close the issue at integrate time instead of finalize — the inviolable floor ("close only after independent verification and integration") is already satisfied per issue at that moment, and closed-at-integrate makes GitHub state reflect durable progress; the cost is losing the single close-them-together finalize moment.
Engine preflight guard (idempotence). Before dispatching an implementer, the engine checks the issue for a landed-marker / closed state (a cheap mechanical-tier dispatch, or folded into the implement prompt's mandatory first step with a distinct status: "already-landed" early return). An already-landed issue is skipped with that distinct status — never parked, never re-implemented, never given a second branch. This bounds the damage of any blind restart, whatever caused it.
Skill restart protocol. SKILL.md documents loudly that resumeFromRunId is same-session-only, and prescribes the cross-session restart: never blind-resume — re-run orchestrate.py plan against reality (open issues minus landed-markers), launch a fresh run scoped to the remainder, and hand the new implementers the prior state as context (the recovery that worked by hand on 2026-07-22). If the engine can detect an impossible resume (e.g. an args flag carrying the original session id), it should refuse or park loudly rather than re-run — "detect that the preconditions to continue are gone, then hand over or abort; never start over from zero."
Acceptance criteria
An engine run whose plan contains an already-landed issue (landed-marker present, or issue closed) dispatches no implementer for it and reports it with a distinct already-landed status — engine-helpers unit-testable.
After a mid-run kill, a fresh orchestrate invocation scopes only the un-landed remainder: no duplicate implementation branch, no duplicate commits, for any previously-landed issue.
SKILL.md states that Workflow resume is same-session-only and specifies the restart protocol; the completion-notification advice can no longer lead a cross-session operator into a silent full re-run.
Context — field experience (kntnt-extractor, 2026-07-22, orchestrate 0.16.1; and earlier larger runs)
A 3-issue merge-mode run was killed mid-run by a Claude Code session restart (field trigger, reproducible across several runs: entering the agent view with arrow-left to check progress, then leaving it → a "compact memory?" prompt appears → the background workflow is already dead; the TUI behavior itself is a harness matter outside this plugin, but the plugin must survive it). The completion notification suggested relaunching with
resumeFromRunId. That was done — with byte-identical script and args — but Workflow resume is same-session-only, and nothing detected the mismatch: the "resume" silently got zero cache hits and re-ran the entire plan from scratch.Consequences observed: the engine re-implemented issue #15 — already independently verified and landed on the default branch — from zero on a new branch; the verifier panel flagged the duplication (high severity), a fix round made the branch tree-identical to main, integrate hit a conflict, reconcile rebased, and three redundant commits landed anyway. The engine was in the middle of the same expensive dance for the also-already-landed #16 when the run was manually stopped and a hand-scoped #17-only run finished the job. In an earlier, larger field run the same failure mode compounded across restarts into 50+ agents and 50+ branches, all wasted.
Root cause
resumeFromRunIdis same-session-only, but neither the skill nor the engine detects a cross-session resume; the launch proceeds with an empty cache and no warning.Proposed fix
orchestrate: landed <sha> on <default-branch>, run <runId>), posted by the integrate step (already the authorized mutator). Decision D1: additionally close the issue at integrate time instead of finalize — the inviolable floor ("close only after independent verification and integration") is already satisfied per issue at that moment, and closed-at-integrate makes GitHub state reflect durable progress; the cost is losing the single close-them-together finalize moment.status: "already-landed"early return). An already-landed issue is skipped with that distinct status — never parked, never re-implemented, never given a second branch. This bounds the damage of any blind restart, whatever caused it.resumeFromRunIdis same-session-only, and prescribes the cross-session restart: never blind-resume — re-runorchestrate.py planagainst reality (open issues minus landed-markers), launch a fresh run scoped to the remainder, and hand the new implementers the prior state as context (the recovery that worked by hand on 2026-07-22). If the engine can detect an impossible resume (e.g. an args flag carrying the original session id), it should refuse or park loudly rather than re-run — "detect that the preconditions to continue are gone, then hand over or abort; never start over from zero."Acceptance criteria
already-landedstatus — engine-helpers unit-testable.Companion ticket: #48 (continuous out-of-band progress reporting — the milestone/landed-marker mechanism serves both).
🤖 Generated with Claude Code