Skip to content

fix(gsd): make auto mode complete a milestone end to end - #1605

Merged
jeremymcs merged 2 commits into
mainfrom
fix/gsd-auto-milestone-completion-pr
Aug 7, 2026
Merged

fix(gsd): make auto mode complete a milestone end to end#1605
jeremymcs merged 2 commits into
mainfrom
fix/gsd-auto-milestone-completion-pr

Conversation

@jeremymcs

@jeremymcs jeremymcs commented Aug 6, 2026

Copy link
Copy Markdown
Member

Auto mode could not finish a planned milestone. Nine defects, each found by running a real milestone against a scratch project and measuring the result, each with a test that fails without its fix.

Progress across acceptance runs

run outcome
1 exit 10, zero files, zero commits — died at startup migration
2 stuck 25 min on one task, looping on a bogus verification failure
5 4/4 files, S01 closed — stalled at S02 close and exited 0 anyway
8 milestone complete, but 4 HARD BLOCKs per run
14 milestone complete, 0 blocks, 0 pauses, 17k events (fastest)

What was broken

Startup and dispatch

  • migrateToFlatPhase held no cross-process lock. Headless runs the extension in two processes and both fire session_start, so two migrations raced and the loser died on ENOENT. Repro went 3/3 fail → 5/5 clean.
  • Dispatch raced that migration's move-aside window — when slice plans exist in neither layout — and re-planned an already-planned milestone on every run. Scoped to a migration actually in flight so a settled legacy project still reaches the rule (#4671).

Verification and gates

  • The verification gate executed a task's prose verify field as a shell command: greet/hello.txt exists and contains "hello" tried to run the .txt file, exited 126, and failed a task that had succeeded. The prose detector only caught capitalised prose.
  • Browser-UAT escalation fired on a negated mention — no runtime behavior, server, UI, or browser interaction is involved reads as a browser requirement when the negator is a list away.

Reporting

  • Blocked stops exited 0, reporting success over an unfinished milestone. Two independent breaks in stop-notice.ts — the module written to keep emitter and detector in lockstep. Either alone loses the exit code.

Projection and identity

  • Slice plans now state their DB identity; under flat-phase layout an agent inferred milestoneId: "01-m001" from the directory name and was hard-blocked.

Unit tool contracts

  • Contracts were enforced but not advertised: 15 of 24 units with an allowedGsdTools list had no tool guidance at all. The allowed set is now derived from the same table the enforcer reads, and repeated at the dispatch seam — the ## Tool Surface section alone sat 4% into a 14K-character prompt and had no measurable effect. HARD BLOCKs went 4 → 0.
  • The reminder is phrased as a reference, not a menu: an earlier iteration advertising gsd_reassess_roadmap invited validate-milestone to add slices to a completed milestone until runs stopped terminating.

Worktree closeout

  • Under git.isolation=worktree the closeout gate computed the verification source revision from the project root while validation ran in the worktree — different trees by design — so a milestone the DB had marked complete was refused at merge. Measured: worktree sha256:074a8c04… matched the recorded authorization exactly; root sha256:a86aa329… did not.

Verification

  • A 2-slice/4-task milestone completes unattended: exit=0, both slices and the milestone complete in the DB, byte-exact artifacts, 0 HARD BLOCKs.
  • Each fix has a test that fails without it.
  • Full gsd suite: 137 failures both with and without these changes — no regressions introduced.

Known limits

  • The worktree merge is not confirmed end-to-end. The closeout gate fix is verified against the exact blocked project (gate flips to ok) and introduces no regressions, but every full acceptance attempt under worktree isolation was cut short. The gate fix also has no regression test — one needs a project with a registered git worktree plus recorded validation events.
  • Two of the nine fixes were wrong on first attempt and corrected after measurement (a dispatch guard that broke 5 tests; a prompt fix that changed nothing). Both are noted here so reviewers know where to look hardest.
  • A tenth fix — stamp-insensitive projection drift comparison — is deliberately excluded: it depends on the state-version stamping mechanism, which does not exist on main.

View with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is enabled.

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

🔴 PR Risk Report — CRITICAL

Files changed 15
Systems affected 3
Overall risk 🔴 CRITICAL

Affected Systems

Risk System
🔴 critical Auto Engine
🟠 high GSD Workflow
🟢 low Headless Mode
File Breakdown
Risk File Systems
🔴 src/resources/extensions/gsd/auto-dispatch.ts Auto Engine
🔴 src/resources/extensions/gsd/auto/loop.ts Auto Engine
🔴 src/resources/extensions/gsd/stop-notice.ts Auto Engine, Headless Mode
🟠 src/resources/extensions/gsd/verification-gate.ts GSD Workflow
src/resources/extensions/gsd/browser-evidence.ts (unclassified)
src/resources/extensions/gsd/closeout-consistency-gate.ts (unclassified)
src/resources/extensions/gsd/flat-phase-migration.ts (unclassified)
src/resources/extensions/gsd/markdown-renderer.ts (unclassified)
src/resources/extensions/gsd/tests/browser-evidence.test.ts (unclassified)
src/resources/extensions/gsd/tests/dispatch-during-migration.test.ts (unclassified)
src/resources/extensions/gsd/tests/flat-phase-migration.test.ts (unclassified)
src/resources/extensions/gsd/tests/stop-notice.test.ts (unclassified)
src/resources/extensions/gsd/tests/tool-surface-affordance.test.ts (unclassified)
src/resources/extensions/gsd/tests/verification-gate.test.ts (unclassified)
src/resources/extensions/gsd/unit-context-composer.ts (unclassified)

⚠️ 🔴 Critical risk — the following systems require verification before merge:

  • 🔴 Auto Engine: validate auto-mode trigger conditions and loop termination
  • 🟠 GSD Workflow: verify GSD workflow state transitions end-to-end

⛔ This PR should not be merged without executing this follow-up prompt.

Ask your coding agent to verify before submitting:

Review this PR for risks in: Auto Engine, GSD Workflow. Verify:

1. validate auto-mode trigger conditions and loop termination
2. verify GSD workflow state transitions end-to-end

Before modifying any code, assess the scope of this fix:

- Identify the root cause, not just the reported symptom.
- Search the codebase for other call sites, similar patterns, or duplicated logic that may share the same bug.
- List affected tests, documentation, and any downstream consumers that depend on the current behavior.
- Flag any changes that extend beyond the immediate file or function.

Report findings first. Then propose a fix scoped to the actual root cause, and wait for confirmation before applying changes outside the originally reported location.

💡 Have a Codex subscription? Get an independent second opinion: codex review --adversarial

jeremymcs and others added 2 commits August 7, 2026 18:51
Auto mode could not finish a planned milestone. Nine defects, each found by
running a real milestone against a scratch project and measuring, each with a
test that fails without its fix.

Startup and dispatch:
- migrateToFlatPhase held no cross-process lock. Headless runs the extension in
  two processes and both fire session_start, so two migrations raced and the
  loser died on ENOENT. Repro went 3/3 fail to 5/5 clean.
- Dispatch raced that migration's move-aside window, when slice plans exist in
  neither layout, and re-planned an already-planned milestone on every run.
  Scoped to a migration actually in flight so a settled legacy project still
  reaches the rule (#4671).

Verification and gates:
- The verification gate executed a task's prose `verify` field as a shell
  command: `greet/hello.txt exists and contains "hello"` ran the .txt file and
  exited 126, failing a task that had succeeded. The prose detector only caught
  capitalised prose; lowercase fell through.
- Browser-UAT escalation fired on a negated mention. "no runtime behavior,
  server, UI, or browser interaction is involved" reads as a browser
  requirement when the negator is a list away.

Reporting:
- Blocked stops exited 0, reporting success over an unfinished milestone. Two
  independent breaks in stop-notice.ts, the module written to keep emitter and
  detector in lockstep: the reason reached stopAuto unmarked, and the detector
  tested for "blocked:" while the formatter emits "Auto-mode blocked -" with no
  colon. Blocked prefixes were also absent from TERMINAL_NOTICE_PREFIXES.

Projection and identity:
- Slice plans now state their DB identity. Under flat-phase layout an agent
  inferred milestoneId "01-m001" from the directory name and was hard-blocked.

Unit tool contracts:
- Contracts were enforced but not advertised: 15 of 24 units with an
  allowedGsdTools list had no tool guidance. The allowed set is now derived
  from the same table the enforcer reads, and repeated as a one-line reminder
  at the dispatch seam - the Tool Surface section alone sat 4% into a 14K
  prompt and had no effect. HARD BLOCKs went 4 to 0.
- That reminder is phrased as a reference, not a menu: advertising
  gsd_reassess_roadmap invited validate-milestone to add slices to a completed
  milestone until the run stopped terminating.

Worktree closeout:
- Under git.isolation=worktree the closeout consistency gate computed the
  verification source revision from the project root while validation had run
  in the worktree - two different trees by design - so a milestone the DB had
  marked complete was refused at merge with "validation authorization is not
  current". Measured: worktree sha256:074a8c04 matched the recorded value
  exactly; root sha256:a86aa329 did not.

Verified: a 2-slice/4-task milestone completes unattended with exit 0, both
slices and the milestone complete in the DB, and byte-exact artifacts.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ordance

Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
@jeremymcs
jeremymcs force-pushed the fix/gsd-auto-milestone-completion-pr branch from a916deb to f836b5c Compare August 7, 2026 18:55
@jeremymcs
jeremymcs merged commit 6aea68b into main Aug 7, 2026
9 checks passed
@jeremymcs
jeremymcs deleted the fix/gsd-auto-milestone-completion-pr branch August 7, 2026 19:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant