gsd-opencode 1.33.2 → 1.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/agents/gsd-advisor-researcher.md +23 -0
  2. package/agents/gsd-ai-researcher.md +142 -0
  3. package/agents/gsd-code-fixer.md +523 -0
  4. package/agents/gsd-code-reviewer.md +361 -0
  5. package/agents/gsd-debugger.md +14 -1
  6. package/agents/gsd-domain-researcher.md +162 -0
  7. package/agents/gsd-eval-auditor.md +170 -0
  8. package/agents/gsd-eval-planner.md +161 -0
  9. package/agents/gsd-executor.md +70 -7
  10. package/agents/gsd-framework-selector.md +167 -0
  11. package/agents/gsd-intel-updater.md +320 -0
  12. package/agents/gsd-phase-researcher.md +26 -0
  13. package/agents/gsd-plan-checker.md +12 -0
  14. package/agents/gsd-planner.md +16 -6
  15. package/agents/gsd-project-researcher.md +23 -0
  16. package/agents/gsd-ui-researcher.md +23 -0
  17. package/agents/gsd-verifier.md +55 -1
  18. package/commands/gsd/gsd-add-backlog.md +1 -1
  19. package/commands/gsd/gsd-add-phase.md +1 -1
  20. package/commands/gsd/gsd-add-todo.md +1 -1
  21. package/commands/gsd/gsd-ai-integration-phase.md +36 -0
  22. package/commands/gsd/gsd-audit-fix.md +33 -0
  23. package/commands/gsd/gsd-autonomous.md +1 -0
  24. package/commands/gsd/gsd-check-todos.md +1 -1
  25. package/commands/gsd/gsd-code-review-fix.md +52 -0
  26. package/commands/gsd/gsd-code-review.md +55 -0
  27. package/commands/gsd/gsd-complete-milestone.md +1 -1
  28. package/commands/gsd/gsd-debug.md +1 -1
  29. package/commands/gsd/gsd-eval-review.md +32 -0
  30. package/commands/gsd/gsd-explore.md +27 -0
  31. package/commands/gsd/gsd-from-gsd2.md +45 -0
  32. package/commands/gsd/gsd-health.md +1 -1
  33. package/commands/gsd/gsd-import.md +36 -0
  34. package/commands/gsd/gsd-insert-phase.md +1 -1
  35. package/commands/gsd/gsd-intel.md +183 -0
  36. package/commands/gsd/gsd-manager.md +1 -1
  37. package/commands/gsd/gsd-next.md +2 -0
  38. package/commands/gsd/gsd-reapply-patches.md +58 -3
  39. package/commands/gsd/gsd-remove-phase.md +1 -1
  40. package/commands/gsd/gsd-review.md +4 -2
  41. package/commands/gsd/gsd-scan.md +26 -0
  42. package/commands/gsd/gsd-set-profile.md +1 -1
  43. package/commands/gsd/gsd-thread.md +1 -1
  44. package/commands/gsd/gsd-undo.md +34 -0
  45. package/commands/gsd/gsd-workstreams.md +6 -6
  46. package/get-shit-done/bin/gsd-tools.cjs +143 -5
  47. package/get-shit-done/bin/lib/commands.cjs +10 -2
  48. package/get-shit-done/bin/lib/config.cjs +71 -37
  49. package/get-shit-done/bin/lib/core.cjs +70 -8
  50. package/get-shit-done/bin/lib/gsd2-import.cjs +511 -0
  51. package/get-shit-done/bin/lib/init.cjs +20 -6
  52. package/get-shit-done/bin/lib/intel.cjs +660 -0
  53. package/get-shit-done/bin/lib/learnings.cjs +378 -0
  54. package/get-shit-done/bin/lib/milestone.cjs +25 -15
  55. package/get-shit-done/bin/lib/model-profiles.cjs +17 -17
  56. package/get-shit-done/bin/lib/phase.cjs +148 -112
  57. package/get-shit-done/bin/lib/roadmap.cjs +12 -5
  58. package/get-shit-done/bin/lib/security.cjs +119 -0
  59. package/get-shit-done/bin/lib/state.cjs +283 -221
  60. package/get-shit-done/bin/lib/template.cjs +8 -4
  61. package/get-shit-done/bin/lib/verify.cjs +42 -5
  62. package/get-shit-done/references/ai-evals.md +156 -0
  63. package/get-shit-done/references/ai-frameworks.md +186 -0
  64. package/get-shit-done/references/common-bug-patterns.md +114 -0
  65. package/get-shit-done/references/few-shot-examples/plan-checker.md +73 -0
  66. package/get-shit-done/references/few-shot-examples/verifier.md +109 -0
  67. package/get-shit-done/references/gates.md +70 -0
  68. package/get-shit-done/references/ios-scaffold.md +123 -0
  69. package/get-shit-done/references/model-profile-resolution.md +6 -7
  70. package/get-shit-done/references/model-profiles.md +20 -14
  71. package/get-shit-done/references/planning-config.md +237 -0
  72. package/get-shit-done/references/thinking-models-debug.md +44 -0
  73. package/get-shit-done/references/thinking-models-execution.md +50 -0
  74. package/get-shit-done/references/thinking-models-planning.md +62 -0
  75. package/get-shit-done/references/thinking-models-research.md +50 -0
  76. package/get-shit-done/references/thinking-models-verification.md +55 -0
  77. package/get-shit-done/references/thinking-partner.md +96 -0
  78. package/get-shit-done/references/universal-anti-patterns.md +6 -1
  79. package/get-shit-done/references/verification-overrides.md +227 -0
  80. package/get-shit-done/templates/AI-SPEC.md +246 -0
  81. package/get-shit-done/workflows/add-tests.md +3 -0
  82. package/get-shit-done/workflows/add-todo.md +2 -0
  83. package/get-shit-done/workflows/ai-integration-phase.md +284 -0
  84. package/get-shit-done/workflows/audit-fix.md +154 -0
  85. package/get-shit-done/workflows/autonomous.md +33 -2
  86. package/get-shit-done/workflows/check-todos.md +2 -0
  87. package/get-shit-done/workflows/cleanup.md +2 -0
  88. package/get-shit-done/workflows/code-review-fix.md +497 -0
  89. package/get-shit-done/workflows/code-review.md +515 -0
  90. package/get-shit-done/workflows/complete-milestone.md +40 -15
  91. package/get-shit-done/workflows/diagnose-issues.md +1 -1
  92. package/get-shit-done/workflows/discovery-phase.md +3 -1
  93. package/get-shit-done/workflows/discuss-phase-assumptions.md +1 -1
  94. package/get-shit-done/workflows/discuss-phase.md +21 -7
  95. package/get-shit-done/workflows/do.md +2 -0
  96. package/get-shit-done/workflows/docs-update.md +2 -0
  97. package/get-shit-done/workflows/eval-review.md +155 -0
  98. package/get-shit-done/workflows/execute-phase.md +307 -57
  99. package/get-shit-done/workflows/execute-plan.md +64 -93
  100. package/get-shit-done/workflows/explore.md +136 -0
  101. package/get-shit-done/workflows/help.md +1 -1
  102. package/get-shit-done/workflows/import.md +273 -0
  103. package/get-shit-done/workflows/inbox.md +387 -0
  104. package/get-shit-done/workflows/manager.md +4 -10
  105. package/get-shit-done/workflows/new-milestone.md +3 -1
  106. package/get-shit-done/workflows/new-project.md +2 -0
  107. package/get-shit-done/workflows/new-workspace.md +2 -0
  108. package/get-shit-done/workflows/next.md +56 -0
  109. package/get-shit-done/workflows/note.md +2 -0
  110. package/get-shit-done/workflows/plan-phase.md +97 -17
  111. package/get-shit-done/workflows/plant-seed.md +3 -0
  112. package/get-shit-done/workflows/pr-branch.md +41 -13
  113. package/get-shit-done/workflows/profile-user.md +4 -2
  114. package/get-shit-done/workflows/quick.md +99 -4
  115. package/get-shit-done/workflows/remove-workspace.md +2 -0
  116. package/get-shit-done/workflows/review.md +53 -6
  117. package/get-shit-done/workflows/scan.md +98 -0
  118. package/get-shit-done/workflows/secure-phase.md +2 -0
  119. package/get-shit-done/workflows/settings.md +18 -3
  120. package/get-shit-done/workflows/ship.md +3 -0
  121. package/get-shit-done/workflows/ui-phase.md +10 -2
  122. package/get-shit-done/workflows/ui-review.md +2 -0
  123. package/get-shit-done/workflows/undo.md +314 -0
  124. package/get-shit-done/workflows/update.md +2 -0
  125. package/get-shit-done/workflows/validate-phase.md +2 -0
  126. package/get-shit-done/workflows/verify-phase.md +83 -0
  127. package/get-shit-done/workflows/verify-work.md +12 -1
  128. package/package.json +1 -1
  129. package/skills/gsd-code-review/SKILL.md +48 -0
  130. package/skills/gsd-code-review-fix/SKILL.md +44 -0
@@ -28,6 +28,7 @@ read STATE.md before any operation to load project context.
28
28
 
29
29
  @$HOME/.config/opencode/get-shit-done/references/agent-contracts.md
30
30
  @$HOME/.config/opencode/get-shit-done/references/context-budget.md
31
+ @$HOME/.config/opencode/get-shit-done/references/gates.md
31
32
  </required_reading>
32
33
 
33
34
  <available_agent_types>
@@ -328,8 +329,8 @@ Execute each selected wave in sequence. Within a wave: parallel if `PARALLELIZAT
328
329
  # → simultaneous git worktree add → .git/config.lock contention → failures
329
330
  ```
330
331
 
331
- ```
332
- @gsd-executor "
332
+ ```
333
+ @gsd-executor "
333
334
  <objective>
334
335
  Execute plan {plan_number} of phase {phase_number}-{phase_name}.
335
336
  Commit each task atomically. Create SUMMARY.md.
@@ -338,33 +339,49 @@ Execute each selected wave in sequence. Within a wave: parallel if `PARALLELIZAT
338
339
 
339
340
  <worktree_branch_check>
340
341
  FIRST ACTION before any other work: verify this worktree's branch is based on the correct commit.
341
-
342
342
  Run:
343
343
  ```bash
344
344
  ACTUAL_BASE=$(git merge-base HEAD {EXPECTED_BASE})
345
- CURRENT_HEAD=$(git rev-parse HEAD)
346
345
  ```
347
346
 
348
347
  If `ACTUAL_BASE` != `{EXPECTED_BASE}` (i.e. the worktree branch was created from an older
349
- base such as `main` instead of the feature branch HEAD), rebase onto the correct base:
348
+ base such as `main` instead of the feature branch HEAD), hard-reset to the correct base:
350
349
  ```bash
351
- git rebase --onto {EXPECTED_BASE} $(git rev-parse --abbrev-ref HEAD~1 2>/dev/null || git rev-parse HEAD^) HEAD 2>/dev/null || true
352
- # If rebase fails or is a no-op, reset the branch to start from the correct base:
353
- git reset --soft {EXPECTED_BASE}
350
+ # Safe: this runs before any agent work, so no uncommitted changes to lose
351
+ git reset --hard {EXPECTED_BASE}
352
+ # Verify correction succeeded
353
+ if [ "$(git rev-parse HEAD)" != "{EXPECTED_BASE}" ]; then
354
+ echo "ERROR: Could not correct worktree base — aborting to prevent data loss"
355
+ exit 1
356
+ fi
354
357
  ```
355
358
 
359
+ `reset --hard` is safe here because this is a fresh worktree with no user changes. It
360
+ resets both the HEAD pointer AND the working tree to the correct base commit (#2015).
361
+
356
362
  If `ACTUAL_BASE` == `{EXPECTED_BASE}`: the branch base is correct, proceed immediately.
357
363
 
358
- This check fixes a known issue on Windows where `EnterWorktree` creates branches from
359
- `main` instead of the current feature branch HEAD.
364
+ This check fixes a known issue where `EnterWorktree` creates branches from
365
+ `main` instead of the current feature branch HEAD (affects all platforms).
360
366
  </worktree_branch_check>
361
367
 
362
368
  <parallel_execution>
363
- You are running as a PARALLEL executor agent. Use --no-verify on all git
364
- commits to avoid pre-commit hook contention with other agents. The
365
- orchestrator validates hooks once after all agents complete.
369
+ You are running as a PARALLEL executor agent in a git worktree.
370
+ Use --no-verify on all git commits to avoid pre-commit hook contention
371
+ with other agents. The orchestrator validates hooks once after all agents complete.
366
372
  For gsd-tools commits: add --no-verify flag.
367
373
  For direct git commits: use git commit --no-verify -m "..."
374
+
375
+ IMPORTANT: Do NOT modify STATE.md or ROADMAP.md. execute-plan.md
376
+ auto-detects worktree mode (`.git` is a file, not a directory) and skips
377
+ shared file updates automatically. The orchestrator updates them centrally
378
+ after merge.
379
+
380
+ REQUIRED: SUMMARY.md MUST be committed before you return. In worktree mode the
381
+ git_commit_metadata step in execute-plan.md commits SUMMARY.md and REQUIREMENTS.md
382
+ only (STATE.md and ROADMAP.md are excluded automatically). Do NOT skip or defer
383
+ this commit — the orchestrator force-removes the worktree after you return, and
384
+ any uncommitted SUMMARY.md will be permanently lost (#2070).
368
385
  </parallel_execution>
369
386
 
370
387
  <execution_context>
@@ -372,39 +389,40 @@ Execute each selected wave in sequence. Within a wave: parallel if `PARALLELIZAT
372
389
  @$HOME/.config/opencode/get-shit-done/templates/summary.md
373
390
  @$HOME/.config/opencode/get-shit-done/references/checkpoints.md
374
391
  @$HOME/.config/opencode/get-shit-done/references/tdd.md
375
- </execution_context>
376
-
377
- <files_to_read>
378
- read these files at execution start using the read tool:
379
- - {phase_dir}/{plan_file} (Plan)
380
- - .planning/PROJECT.md (Project context — core value, requirements, evolution rules)
381
- - .planning/STATE.md (State)
382
- - .planning/config.json (Config, if exists)
383
- ${CONTEXT_WINDOW >= 500000 ? `
384
- - ${phase_dir}/*-CONTEXT.md (User decisions from discuss-phase — honors locked choices)
385
- - ${phase_dir}/*-RESEARCH.md (Technical research — pitfalls and patterns to follow)
386
- - ${prior_wave_summaries} (SUMMARY.md files from earlier waves in this phase — what was already built)
387
- ` : ''}
388
- - ./AGENTS.md (Project instructions, if exists — follow project-specific guidelines and coding conventions)
389
- - .OpenCode/skills/ or .agents/skills/ (Project skills, if either exists — list skills, read SKILL.md for each, follow relevant rules during implementation)
390
- </files_to_read>
391
-
392
- ${AGENT_SKILLS}
393
-
394
- <mcp_tools>
395
- If AGENTS.md or project instructions reference MCP tools (e.g. jCodeMunch, context7,
396
- or other MCP servers), prefer those tools over grep/glob for code navigation when available.
397
- MCP tools often save significant tokens by providing structured code indexes.
398
- Check tool availability first — if MCP tools are not accessible, fall back to grep/glob.
399
- </mcp_tools>
400
-
401
- <success_criteria>
402
- - [ ] All tasks executed
403
- - [ ] Each task committed individually
404
- - [ ] SUMMARY.md created in plan directory
392
+ </execution_context>
393
+
394
+ <files_to_read>
395
+ read these files at execution start using the read tool:
396
+ - {phase_dir}/{plan_file} (Plan)
397
+ - .planning/PROJECT.md (Project context — core value, requirements, evolution rules)
398
+ - .planning/STATE.md (State)
399
+ - .planning/config.json (Config, if exists)
400
+ ${CONTEXT_WINDOW >= 500000 ? `
401
+ - ${phase_dir}/*-CONTEXT.md (User decisions from discuss-phase — honors locked choices)
402
+ - ${phase_dir}/*-RESEARCH.md (Technical research — pitfalls and patterns to follow)
403
+ - ${prior_wave_summaries} (SUMMARY.md files from earlier waves in this phase — what was already built)
404
+ ` : ''}
405
+ - ./AGENTS.md (Project instructions, if exists — follow project-specific guidelines and coding conventions)
406
+ - .OpenCode/skills/ or .agents/skills/ (Project skills, if either exists — list skills, read SKILL.md for each, follow relevant rules during implementation)
407
+ </files_to_read>
408
+
409
+ ${AGENT_SKILLS}
410
+
411
+ <mcp_tools>
412
+ If AGENTS.md or project instructions reference MCP tools (e.g. jCodeMunch, context7,
413
+ or other MCP servers), prefer those tools over grep/glob for code navigation when available.
414
+ MCP tools often save significant tokens by providing structured code indexes.
415
+ Check tool availability first — if MCP tools are not accessible, fall back to grep/glob.
416
+ </mcp_tools>
417
+
418
+ <success_criteria>
419
+ - [ ] All tasks executed
420
+ - [ ] Each task committed individually
421
+ - [ ] SUMMARY.md created in plan directory
422
+ - [ ] No modifications to shared orchestrator artifacts (the orchestrator handles all post-wave shared-file writes)
405
423
  </success_criteria>
406
424
  "
407
- ```
425
+ ```
408
426
 
409
427
  **Sequential mode** (`USE_WORKTREES` is `false`):
410
428
 
@@ -479,12 +497,75 @@ Execute each selected wave in sequence. Within a wave: parallel if `PARALLELIZAT
479
497
  if [ -n "$WT_BRANCH" ] && [ "$WT_BRANCH" != "HEAD" ]; then
480
498
  CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
481
499
 
500
+ # --- Orchestrator file protection (#1756) ---
501
+ # Snapshot orchestrator-owned files BEFORE merge. If the worktree
502
+ # branch outlived a milestone transition, its versions of STATE.md
503
+ # and ROADMAP.md are stale. Main always wins for these files.
504
+ STATE_BACKUP=$(mktemp)
505
+ ROADMAP_BACKUP=$(mktemp)
506
+ git show HEAD:.planning/STATE.md > "$STATE_BACKUP" 2>/dev/null || true
507
+ git show HEAD:.planning/ROADMAP.md > "$ROADMAP_BACKUP" 2>/dev/null || true
508
+
509
+ # Snapshot list of files on main BEFORE merge to detect resurrections
510
+ PRE_MERGE_FILES=$(git ls-files .planning/)
511
+
512
+ # Pre-merge deletion check: warn if the worktree branch deletes tracked files
513
+ DELETIONS=$(git diff --diff-filter=D --name-only HEAD..."$WT_BRANCH" 2>/dev/null || true)
514
+ if [ -n "$DELETIONS" ]; then
515
+ echo "BLOCKED: Worktree branch $WT_BRANCH contains file deletions: $DELETIONS"
516
+ echo "Review these deletions before merging. If intentional, remove this guard and re-run."
517
+ rm -f "$STATE_BACKUP" "$ROADMAP_BACKUP"
518
+ continue
519
+ fi
520
+
482
521
  # Merge the worktree branch into the current branch
483
522
  git merge "$WT_BRANCH" --no-edit -m "chore: merge executor worktree ($WT_BRANCH)" 2>&1 || {
484
523
  echo "⚠ Merge conflict from worktree $WT_BRANCH — resolve manually"
524
+ rm -f "$STATE_BACKUP" "$ROADMAP_BACKUP"
485
525
  continue
486
526
  }
487
527
 
528
+ # Restore orchestrator-owned files (main always wins)
529
+ if [ -s "$STATE_BACKUP" ]; then
530
+ cp "$STATE_BACKUP" .planning/STATE.md
531
+ fi
532
+ if [ -s "$ROADMAP_BACKUP" ]; then
533
+ cp "$ROADMAP_BACKUP" .planning/ROADMAP.md
534
+ fi
535
+ rm -f "$STATE_BACKUP" "$ROADMAP_BACKUP"
536
+
537
+ # Detect files deleted on main but re-added by worktree merge
538
+ # (e.g., archived phase directories that were intentionally removed)
539
+ DELETED_FILES=$(git diff --diff-filter=A --name-only HEAD~1 -- .planning/ 2>/dev/null || true)
540
+ for RESURRECTED in $DELETED_FILES; do
541
+ # Check if this file was NOT in main's pre-merge tree
542
+ if ! echo "$PRE_MERGE_FILES" | grep -qxF "$RESURRECTED"; then
543
+ git rm -f "$RESURRECTED" 2>/dev/null || true
544
+ fi
545
+ done
546
+
547
+ # Amend merge commit with restored files if any changed
548
+ if ! git diff --quiet .planning/STATE.md .planning/ROADMAP.md 2>/dev/null || \
549
+ [ -n "$DELETED_FILES" ]; then
550
+ # Only amend the commit with .planning/ files if commit_docs is enabled (#1783)
551
+ COMMIT_DOCS=$(node "$HOME/.config/opencode/get-shit-done/bin/gsd-tools.cjs" config-get commit_docs 2>/dev/null || echo "true")
552
+ if [ "$COMMIT_DOCS" != "false" ]; then
553
+ git add .planning/STATE.md .planning/ROADMAP.md 2>/dev/null || true
554
+ git commit --amend --no-edit 2>/dev/null || true
555
+ fi
556
+ fi
557
+
558
+ # Safety net: commit any uncommitted SUMMARY.md before force-removing the worktree.
559
+ # This guards against executors that skipped the git_commit_metadata step (#2070).
560
+ UNCOMMITTED_SUMMARY=$(git -C "$WT" ls-files --modified --others --exclude-standard -- "*SUMMARY.md" 2>/dev/null || true)
561
+ if [ -n "$UNCOMMITTED_SUMMARY" ]; then
562
+ echo "⚠ SUMMARY.md was not committed by executor — committing now to prevent data loss"
563
+ git -C "$WT" add -- "*SUMMARY.md" 2>/dev/null || true
564
+ git -C "$WT" commit --no-verify -m "docs(recovery): rescue uncommitted SUMMARY.md before worktree removal (#2070)" 2>/dev/null || true
565
+ # Re-merge the recovery commit
566
+ git merge "$WT_BRANCH" --no-edit -m "chore: merge rescued SUMMARY.md from executor worktree ($WT_BRANCH)" 2>/dev/null || true
567
+ fi
568
+
488
569
  # Remove the worktree
489
570
  git worktree remove "$WT" --force 2>/dev/null || true
490
571
 
@@ -498,22 +579,113 @@ Execute each selected wave in sequence. Within a wave: parallel if `PARALLELIZAT
498
579
 
499
580
  **If no worktrees found:** Skip silently — agents may have been spawned without worktree isolation.
500
581
 
501
- 5.6. **Post-wave shared artifact update (worktree mode only):**
582
+ 5.6. **Post-merge test gate (parallel mode only):**
583
+
584
+ After merging all worktrees in a wave, run the project's test suite to catch
585
+ cross-plan integration issues that individual worktree self-checks cannot detect
586
+ (e.g., conflicting type definitions, removed exports, import changes).
502
587
 
503
- When executor agents ran with `isolation="worktree"`, they skipped STATE.md and ROADMAP.md updates to avoid last-merge-wins overwrites. The orchestrator is the single writer for these files. After worktrees are merged back, update shared artifacts once:
588
+ This addresses the Generator self-evaluation blind spot identified in Anthropic's
589
+ harness engineering research: agents reliably report Self-Check: PASSED even when
590
+ merging their work creates failures.
504
591
 
505
592
  ```bash
506
- # Update ROADMAP.md for each completed plan in this wave
507
- for PLAN_ID in ${WAVE_PLAN_IDS}; do
508
- node "$HOME/.config/opencode/get-shit-done/bin/gsd-tools.cjs" roadmap update-plan-progress "${PHASE_NUMBER}" "${PLAN_ID}" completed
509
- done
593
+ # Detect test runner and run quick smoke test (timeout: 5 minutes)
594
+ TEST_EXIT=0
595
+ timeout 300 bash -c '
596
+ if [ -f "package.json" ]; then
597
+ npm test 2>&1
598
+ elif [ -f "Cargo.toml" ]; then
599
+ cargo test 2>&1
600
+ elif [ -f "go.mod" ]; then
601
+ go test ./... 2>&1
602
+ elif [ -f "pyproject.toml" ] || [ -f "requirements.txt" ]; then
603
+ python -m pytest -x -q --tb=short 2>&1 || uv run python -m pytest -x -q --tb=short 2>&1
604
+ else
605
+ echo "⚠ No test runner detected — skipping post-merge test gate"
606
+ exit 0
607
+ fi
608
+ '
609
+ TEST_EXIT=$?
610
+ if [ "${TEST_EXIT}" -eq 0 ]; then
611
+ echo "✓ Post-merge test gate passed — no cross-plan conflicts"
612
+ elif [ "${TEST_EXIT}" -eq 124 ]; then
613
+ echo "⚠ Post-merge test gate timed out after 5 minutes"
614
+ else
615
+ echo "✗ Post-merge test gate failed (exit code ${TEST_EXIT})"
616
+ WAVE_FAILURE_COUNT=$((WAVE_FAILURE_COUNT + 1))
617
+ fi
618
+ ```
619
+
620
+ **If `TEST_EXIT` is 0 (pass):** `✓ Post-merge test gate: {N} tests passed — no cross-plan conflicts` → continue to orchestrator tracking update.
510
621
 
622
+ **If `TEST_EXIT` is 124 (timeout):** Log warning, treat as non-blocking, continue. Tests may need a longer budget or manual run.
623
+
624
+ **If `TEST_EXIT` is non-zero (test failure):** Increment `WAVE_FAILURE_COUNT` to track
625
+ cumulative failures across waves. Subsequent waves should report:
626
+ `⚠ Note: ${WAVE_FAILURE_COUNT} prior wave(s) had test failures`
627
+
628
+ 5.7. **Post-wave shared artifact update (worktree mode only, skip if tests failed):**
629
+
630
+ When executor agents ran with `isolation="worktree"`, they skipped STATE.md and ROADMAP.md updates to avoid last-merge-wins overwrites. The orchestrator is the single writer for these files. After worktrees are merged back, update shared artifacts once.
631
+
632
+ **Only update tracking when tests passed (TEST_EXIT=0).**
633
+ If tests failed or timed out, skip the tracking update — plans should
634
+ not be marked as complete when integration tests are failing or inconclusive.
635
+
636
+ ```bash
637
+ # Guard: only update tracking if post-merge tests passed
638
+ # Timeout (124) is treated as inconclusive — do NOT mark plans complete
639
+ if [ "${TEST_EXIT}" -eq 0 ]; then
640
+ # Update ROADMAP plan progress for each completed plan in this wave
641
+ for plan_id in {completed_plan_ids}; do
642
+ node "$HOME/.config/opencode/get-shit-done/bin/gsd-tools.cjs" roadmap update-plan-progress "${PHASE_NUMBER}" "${plan_id}" "complete"
643
+ done
644
+
645
+ # Only commit tracking files if they actually changed
646
+ if ! git diff --quiet .planning/ROADMAP.md .planning/STATE.md 2>/dev/null; then
647
+ node "$HOME/.config/opencode/get-shit-done/bin/gsd-tools.cjs" commit "docs(phase-${PHASE_NUMBER}): update tracking after wave ${N}" --files .planning/ROADMAP.md .planning/STATE.md
648
+ fi
649
+ elif [ "${TEST_EXIT}" -eq 124 ]; then
650
+ echo "⚠ Skipping tracking update — test suite timed out. Plans remain in-progress. Run tests manually to confirm."
651
+ else
652
+ echo "⚠ Skipping tracking update — post-merge tests failed (exit ${TEST_EXIT}). Plans remain in-progress until tests pass."
653
+ fi
511
654
  ```
512
655
 
513
656
  Where `WAVE_PLAN_IDS` is the space-separated list of plan IDs that completed in this wave.
514
657
 
515
658
  **If `workflow.use_worktrees` is `false`:** Sequential agents already updated STATE.md and ROADMAP.md themselves — skip this step.
516
659
 
660
+ 5.8. **Handle test gate failures (when `WAVE_FAILURE_COUNT > 0`):**
661
+
662
+ ```
663
+ ## ⚠ Post-Merge Test Failure (cumulative failures: ${WAVE_FAILURE_COUNT})
664
+
665
+ Wave {N} worktrees merged successfully, but {M} tests fail after merge.
666
+ This typically indicates conflicting changes across parallel plans
667
+ (e.g., type definitions, shared imports, API contracts).
668
+
669
+ Failed tests:
670
+ {first 10 lines of failure output}
671
+
672
+ Options:
673
+ 1. Fix now (recommended) — resolve conflicts before next wave
674
+ 2. Continue — failures may compound in subsequent waves
675
+ ```
676
+
677
+ Note: If `WAVE_FAILURE_COUNT > 1`, strongly recommend "Fix now" — compounding
678
+ failures across multiple waves become exponentially harder to diagnose.
679
+
680
+ If "Fix now": diagnose failures (typically import conflicts, missing types,
681
+ or changed function signatures from parallel plans modifying the same module).
682
+ Fix, commit as `fix: resolve post-merge conflicts from wave {N}`, re-run tests.
683
+
684
+ **Why this matters:** Worktree isolation means each agent's Self-Check passes
685
+ in isolation. But when merged, add/add conflicts in shared files (models, registries,
686
+ CLI entry points) can silently drop code. The post-merge gate catches this before
687
+ the next wave builds on a broken foundation.
688
+
517
689
  6. **Report completion — spot-check claims first:**
518
690
 
519
691
  For each SUMMARY.md:
@@ -691,6 +863,39 @@ Selected wave finished successfully. This phase still has incomplete plans, so p
691
863
  - this means the selected wave happened to be the last remaining work in the phase
692
864
  </step>
693
865
 
866
+ <step name="code_review_gate" required="true">
867
+ **This step is REQUIRED and must not be skipped.** Auto-invoke code review on the phase's source changes. Advisory only — never blocks execution flow.
868
+
869
+ **Config gate:**
870
+ ```bash
871
+ CODE_REVIEW_ENABLED=$(node "$HOME/.config/opencode/get-shit-done/bin/gsd-tools.cjs" config-get workflow.code_review 2>/dev/null || echo "true")
872
+ ```
873
+
874
+ If `CODE_REVIEW_ENABLED` is `"false"`: display "Code review skipped (workflow.code_review=false)" and proceed to next step.
875
+
876
+ **Invoke review:**
877
+ ```
878
+ skill(skill="gsd-code-review", args="${PHASE_NUMBER}")
879
+ ```
880
+
881
+ **Check results using deterministic path (not glob):**
882
+ ```bash
883
+ PADDED=$(printf "%02d" "${PHASE_NUMBER}")
884
+ REVIEW_FILE="${PHASE_DIR}/${PADDED}-REVIEW.md"
885
+ REVIEW_STATUS=$(sed -n '/^---$/,/^---$/p' "$REVIEW_FILE" | grep "^status:" | head -1 | cut -d: -f2 | tr -d ' ')
886
+ ```
887
+
888
+ If REVIEW_STATUS is not "clean" and not "skipped" and not empty, display:
889
+ ```
890
+ Code review found issues. Consider running:
891
+ /gsd-code-review-fix ${PHASE_NUMBER}
892
+ ```
893
+
894
+ **Error handling:** If the skill invocation fails or throws, catch the error, display "Code review encountered an error (non-blocking): {error}" and proceed to next step. Review failures must never block execution.
895
+
896
+ Regardless of review result, ALWAYS proceed to close_parent_artifacts → regression_gate → verify_phase_goal.
897
+ </step>
898
+
694
899
  <step name="close_parent_artifacts">
695
900
  **For decimal/polish phases only (X.Y pattern):** Close the feedback loop by resolving parent UAT and debug artifacts.
696
901
 
@@ -766,10 +971,11 @@ Collect all unique test file paths into `REGRESSION_FILES`.
766
971
  ```bash
767
972
  # Detect test runner and run prior phase tests
768
973
  if [ -f "package.json" ]; then
769
- # Node.js — use project's test runner
770
- npx jest ${REGRESSION_FILES} --passWithNoTests --no-coverage -q 2>&1 || npx vitest run ${REGRESSION_FILES} 2>&1
974
+ npm test 2>&1
771
975
  elif [ -f "Cargo.toml" ]; then
772
976
  cargo test 2>&1
977
+ elif [ -f "go.mod" ]; then
978
+ go test ./... 2>&1
773
979
  elif [ -f "requirements.txt" ] || [ -f "pyproject.toml" ]; then
774
980
  python -m pytest ${REGRESSION_FILES} -q --tb=short 2>&1
775
981
  fi
@@ -876,7 +1082,8 @@ VERIFIER_SKILLS=$(node "$HOME/.config/opencode/get-shit-done/bin/gsd-tools.cjs"
876
1082
  ```
877
1083
 
878
1084
  ```
879
- @gsd-verifier "Verify phase {phase_number} goal achievement.
1085
+ @gsd-verifier "
1086
+ Verify phase {phase_number} goal achievement.
880
1087
  Phase directory: {phase_dir}
881
1088
  Phase goal: {goal from ROADMAP.md}
882
1089
  Phase requirement IDs: {phase_req_ids}
@@ -895,7 +1102,8 @@ ${CONTEXT_WINDOW >= 500000 ? `- {phase_dir}/*-CONTEXT.md (User decisions — ver
895
1102
  ` : ''}
896
1103
  </files_to_read>
897
1104
 
898
- ${VERIFIER_SKILLS}"
1105
+ ${VERIFIER_SKILLS}
1106
+ "
899
1107
  ```
900
1108
 
901
1109
  read status:
@@ -1026,6 +1234,29 @@ node "$HOME/.config/opencode/get-shit-done/bin/gsd-tools.cjs" commit "docs(phase
1026
1234
  ```
1027
1235
  </step>
1028
1236
 
1237
+ <step name="auto_copy_learnings">
1238
+ **Auto-copy phase learnings to global store (when enabled).**
1239
+
1240
+ This step runs AFTER phase completion and SUMMARY.md is written. It copies any LEARNINGS.md
1241
+ entries from the completed phase to the global learnings store at `~/.gsd/knowledge/`.
1242
+
1243
+ **Check config gate:**
1244
+ ```bash
1245
+ GL_ENABLED=$(node "$HOME/.config/opencode/get-shit-done/bin/gsd-tools.cjs" config-get features.global_learnings --raw 2>/dev/null || echo "false")
1246
+ ```
1247
+
1248
+ **If `GL_ENABLED` is not `true`:** Skip this step entirely (feature disabled by default).
1249
+
1250
+ **If enabled:**
1251
+
1252
+ 1. Check if LEARNINGS.md exists in the phase directory (use the `phase_dir` value from init context)
1253
+ 2. If found, copy to global store:
1254
+ ```bash
1255
+ node "$HOME/.config/opencode/get-shit-done/bin/gsd-tools.cjs" learnings copy 2>/dev/null || echo "⚠ Learnings copy failed — continuing"
1256
+ ```
1257
+ Copy failure must NOT block phase completion.
1258
+ </step>
1259
+
1029
1260
  <step name="update_project_md">
1030
1261
  **Evolve PROJECT.md to reflect phase completion (prevents planning document drift — #956):**
1031
1262
 
@@ -1103,13 +1334,32 @@ read and follow `$HOME/.config/opencode/get-shit-done/workflows/transition.md`,
1103
1334
 
1104
1335
  **IMPORTANT: There is NO `/gsd-transition` command. Never suggest it. The transition workflow is internal only.**
1105
1336
 
1337
+ Check whether CONTEXT.md already exists for the next phase:
1338
+
1339
+ ```bash
1340
+ ls .planning/phases/*{next}*/{next}-CONTEXT.md 2>/dev/null || echo "no-context"
1341
+ ```
1342
+
1343
+ If CONTEXT.md does **not** exist for the next phase, present:
1344
+
1345
+ ```
1346
+ ## ✓ Phase {X}: {Name} Complete
1347
+
1348
+ /gsd-progress ${GSD_WS} — see updated roadmap
1349
+ /gsd-discuss-phase {next} ${GSD_WS} — start here: discuss next phase before planning ← recommended
1350
+ /gsd-plan-phase {next} ${GSD_WS} — plan next phase (skip discuss)
1351
+ /gsd-execute-phase {next} ${GSD_WS} — execute next phase (skip discuss and plan)
1352
+ ```
1353
+
1354
+ If CONTEXT.md **exists** for the next phase, present:
1355
+
1106
1356
  ```
1107
1357
  ## ✓ Phase {X}: {Name} Complete
1108
1358
 
1109
1359
  /gsd-progress ${GSD_WS} — see updated roadmap
1110
- /gsd-discuss-phase {next} ${GSD_WS} — discuss next phase before planning
1111
- /gsd-plan-phase {next} ${GSD_WS} — plan next phase
1112
- /gsd-execute-phase {next} ${GSD_WS} — execute next phase
1360
+ /gsd-plan-phase {next} ${GSD_WS} — start here: plan next phase (CONTEXT.md already present) ← recommended
1361
+ /gsd-discuss-phase {next} ${GSD_WS} — re-discuss next phase
1362
+ /gsd-execute-phase {next} ${GSD_WS} — execute next phase (skip planning)
1113
1363
  ```
1114
1364
 
1115
1365
  Only suggest the commands listed above. Do not invent or hallucinate command names.