@opengsd/gsd-core 1.6.0-rc.2 → 1.6.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 (157) hide show
  1. package/.claude-plugin/plugin.json +2 -1
  2. package/agents/gsd-advisor-researcher.md +2 -0
  3. package/agents/gsd-ai-researcher.md +2 -0
  4. package/agents/gsd-assumptions-analyzer.md +2 -0
  5. package/agents/gsd-doc-classifier.md +2 -0
  6. package/agents/gsd-doc-synthesizer.md +2 -0
  7. package/agents/gsd-domain-researcher.md +2 -0
  8. package/agents/gsd-eval-auditor.md +6 -9
  9. package/agents/gsd-phase-researcher.md +2 -0
  10. package/agents/gsd-planner.md +8 -57
  11. package/agents/gsd-project-researcher.md +2 -0
  12. package/agents/gsd-research-synthesizer.md +2 -0
  13. package/agents/gsd-security-auditor.md +37 -18
  14. package/agents/gsd-ui-researcher.md +2 -0
  15. package/bin/install.js +370 -18
  16. package/gemini-extension.json +1 -1
  17. package/gsd-core/bin/gsd-tools.cjs +46 -4
  18. package/gsd-core/bin/lib/audit-command-router.cjs +52 -14
  19. package/gsd-core/bin/lib/capability-lifecycle.cjs +30 -7
  20. package/gsd-core/bin/lib/capability-registry.cjs +96 -83
  21. package/gsd-core/bin/lib/capability-validator.cjs +22 -0
  22. package/gsd-core/bin/lib/cjs-command-router-adapter.cjs +40 -2
  23. package/gsd-core/bin/lib/command-aliases.cjs +10 -1
  24. package/gsd-core/bin/lib/command-routing-hub.cjs +10 -3
  25. package/gsd-core/bin/lib/config-schema.cjs +1 -0
  26. package/gsd-core/bin/lib/config.cjs +67 -24
  27. package/gsd-core/bin/lib/coverage.cjs +464 -0
  28. package/gsd-core/bin/lib/decisions.cjs +27 -0
  29. package/gsd-core/bin/lib/eval-command-router.cjs +21 -0
  30. package/gsd-core/bin/lib/eval.cjs +60 -0
  31. package/gsd-core/bin/lib/frontmatter.cjs +132 -13
  32. package/gsd-core/bin/lib/graphify-command-router.cjs +53 -36
  33. package/gsd-core/bin/lib/init.cjs +139 -30
  34. package/gsd-core/bin/lib/install-profiles.cjs +6 -3
  35. package/gsd-core/bin/lib/intel-command-router.cjs +79 -60
  36. package/gsd-core/bin/lib/io.cjs +1 -0
  37. package/gsd-core/bin/lib/phase.cjs +16 -2
  38. package/gsd-core/bin/lib/plan-scan.cjs +2 -2
  39. package/gsd-core/bin/lib/planning-workspace.cjs +157 -13
  40. package/gsd-core/bin/lib/profile-output.cjs +18 -6
  41. package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +53 -16
  42. package/gsd-core/bin/lib/runtime-artifact-layout.cjs +21 -3
  43. package/gsd-core/bin/lib/runtime-hooks-surface.cjs +15 -0
  44. package/gsd-core/bin/lib/runtime-name-policy.cjs +47 -2
  45. package/gsd-core/bin/lib/shell-command-projection.cjs +10 -0
  46. package/gsd-core/bin/lib/state.cjs +398 -60
  47. package/gsd-core/bin/lib/surface.cjs +42 -10
  48. package/gsd-core/bin/lib/uat-predicate.cjs +13 -6
  49. package/gsd-core/bin/lib/update-context.cjs +2 -2
  50. package/gsd-core/bin/lib/verification.cjs +67 -6
  51. package/gsd-core/bin/lib/verify.cjs +8 -1
  52. package/gsd-core/bin/shared/config-defaults.manifest.json +3 -0
  53. package/gsd-core/bin/shared/config-schema.manifest.json +2 -1
  54. package/gsd-core/references/planner-guidance.md +66 -0
  55. package/gsd-core/references/planning-config.md +2 -2
  56. package/gsd-core/references/security-asvs-levels.md +27 -0
  57. package/gsd-core/references/untrusted-input-boundary.md +13 -0
  58. package/gsd-core/templates/SECURITY.md +6 -4
  59. package/gsd-core/templates/summary-complex.md +4 -0
  60. package/gsd-core/templates/summary-minimal.md +3 -0
  61. package/gsd-core/templates/summary-standard.md +4 -0
  62. package/gsd-core/templates/summary.md +41 -0
  63. package/gsd-core/workflows/autonomous.md +53 -46
  64. package/gsd-core/workflows/complete-milestone.md +27 -8
  65. package/gsd-core/workflows/execute-phase.md +1 -1
  66. package/gsd-core/workflows/execute-plan.md +5 -0
  67. package/gsd-core/workflows/manager.md +17 -7
  68. package/gsd-core/workflows/new-project.md +82 -16
  69. package/gsd-core/workflows/plan-phase.md +15 -0
  70. package/gsd-core/workflows/profile-user.md +6 -2
  71. package/gsd-core/workflows/progress.md +37 -4
  72. package/gsd-core/workflows/quick.md +3 -1
  73. package/gsd-core/workflows/secure-phase.md +13 -7
  74. package/gsd-core/workflows/ship.md +3 -1
  75. package/gsd-core/workflows/spec-phase.md +3 -1
  76. package/gsd-core/workflows/transition.md +14 -12
  77. package/gsd-core/workflows/ui-review.md +2 -6
  78. package/gsd-core/workflows/verify-work.md +74 -1
  79. package/hooks/dist/gsd-read-injection-scanner.js +49 -25
  80. package/hooks/gsd-read-injection-scanner.js +49 -25
  81. package/hooks/hooks.json +1 -1
  82. package/package.json +4 -2
  83. package/scripts/check-alias-drift.cjs +5 -0
  84. package/scripts/gen-plugin-skills.cjs +117 -0
  85. package/scripts/lint-test-file-count.allowlist.json +2 -1
  86. package/scripts/prompt-injection-scan.sh +9 -0
  87. package/scripts/release-notes/conventional-title.cjs +88 -0
  88. package/scripts/release-notes/format-github-release-notes.cjs +4 -3
  89. package/skills/gsd-add-tests/SKILL.md +38 -0
  90. package/skills/gsd-ai-integration-phase/SKILL.md +37 -0
  91. package/skills/gsd-audit-fix/SKILL.md +33 -0
  92. package/skills/gsd-audit-milestone/SKILL.md +37 -0
  93. package/skills/gsd-audit-uat/SKILL.md +25 -0
  94. package/skills/gsd-autonomous/SKILL.md +51 -0
  95. package/skills/gsd-capture/SKILL.md +67 -0
  96. package/skills/gsd-cleanup/SKILL.md +24 -0
  97. package/skills/gsd-code-review/SKILL.md +59 -0
  98. package/skills/gsd-complete-milestone/SKILL.md +142 -0
  99. package/skills/gsd-config/SKILL.md +56 -0
  100. package/skills/gsd-debug/SKILL.md +53 -0
  101. package/skills/gsd-discuss-phase/SKILL.md +77 -0
  102. package/skills/gsd-docs-update/SKILL.md +49 -0
  103. package/skills/gsd-eval-review/SKILL.md +33 -0
  104. package/skills/gsd-execute-phase/SKILL.md +65 -0
  105. package/skills/gsd-explore/SKILL.md +28 -0
  106. package/skills/gsd-extract-learnings/SKILL.md +22 -0
  107. package/skills/gsd-fast/SKILL.md +31 -0
  108. package/skills/gsd-forensics/SKILL.md +56 -0
  109. package/skills/gsd-graphify/SKILL.md +204 -0
  110. package/skills/gsd-health/SKILL.md +31 -0
  111. package/skills/gsd-help/SKILL.md +29 -0
  112. package/skills/gsd-import/SKILL.md +46 -0
  113. package/skills/gsd-inbox/SKILL.md +39 -0
  114. package/skills/gsd-ingest-docs/SKILL.md +43 -0
  115. package/skills/gsd-manager/SKILL.md +45 -0
  116. package/skills/gsd-map-codebase/SKILL.md +83 -0
  117. package/skills/gsd-mempalace-capture/SKILL.md +71 -0
  118. package/skills/gsd-mempalace-recall/SKILL.md +102 -0
  119. package/skills/gsd-milestone-summary/SKILL.md +51 -0
  120. package/skills/gsd-mvp-phase/SKILL.md +45 -0
  121. package/skills/gsd-new-milestone/SKILL.md +45 -0
  122. package/skills/gsd-new-project/SKILL.md +47 -0
  123. package/skills/gsd-ns-context/SKILL.md +24 -0
  124. package/skills/gsd-ns-ideate/SKILL.md +23 -0
  125. package/skills/gsd-ns-manage/SKILL.md +35 -0
  126. package/skills/gsd-ns-project/SKILL.md +26 -0
  127. package/skills/gsd-ns-review/SKILL.md +28 -0
  128. package/skills/gsd-ns-workflow/SKILL.md +33 -0
  129. package/skills/gsd-pause-work/SKILL.md +43 -0
  130. package/skills/gsd-phase/SKILL.md +57 -0
  131. package/skills/gsd-plan-phase/SKILL.md +63 -0
  132. package/skills/gsd-plan-review-convergence/SKILL.md +60 -0
  133. package/skills/gsd-pr-branch/SKILL.md +26 -0
  134. package/skills/gsd-profile-user/SKILL.md +47 -0
  135. package/skills/gsd-progress/SKILL.md +49 -0
  136. package/skills/gsd-quick/SKILL.md +174 -0
  137. package/skills/gsd-resume-work/SKILL.md +31 -0
  138. package/skills/gsd-review/SKILL.md +42 -0
  139. package/skills/gsd-review-backlog/SKILL.md +63 -0
  140. package/skills/gsd-secure-phase/SKILL.md +36 -0
  141. package/skills/gsd-settings/SKILL.md +29 -0
  142. package/skills/gsd-ship/SKILL.md +24 -0
  143. package/skills/gsd-sketch/SKILL.md +60 -0
  144. package/skills/gsd-spec-phase/SKILL.md +63 -0
  145. package/skills/gsd-spike/SKILL.md +57 -0
  146. package/skills/gsd-stats/SKILL.md +20 -0
  147. package/skills/gsd-surface/SKILL.md +162 -0
  148. package/skills/gsd-thread/SKILL.md +24 -0
  149. package/skills/gsd-ui-phase/SKILL.md +35 -0
  150. package/skills/gsd-ui-review/SKILL.md +33 -0
  151. package/skills/gsd-ultraplan-phase/SKILL.md +34 -0
  152. package/skills/gsd-undo/SKILL.md +35 -0
  153. package/skills/gsd-update/SKILL.md +50 -0
  154. package/skills/gsd-validate-phase/SKILL.md +36 -0
  155. package/skills/gsd-verify-work/SKILL.md +39 -0
  156. package/skills/gsd-workspace/SKILL.md +53 -0
  157. package/skills/gsd-workstreams/SKILL.md +70 -0
@@ -61,7 +61,7 @@ fi
61
61
 
62
62
  When `--only` is set, also set `FROM_PHASE` to the same value so existing filter logic applies.
63
63
 
64
- When `--interactive` is set, discuss runs inline with questions (not auto-answered). On Codex, where a backgrounded agent can still spawn subagents, plan and execute are dispatched as background agents — keeping the main context lean (only discuss conversations accumulate) and enabling overlap. On every other runtime (Claude Code and all other non-Codex runtimes), backgrounded agents cannot reliably nest subagents, so plan and execute run inline to preserve worktree isolation and independent verification, and phases run sequentially with their work accumulating in the main context. Either way, user input is preserved on all design decisions.
64
+ When `--interactive` is set, discuss runs inline with questions. On Codex, where a backgrounded agent can still spawn subagents, plan and execute are dispatched as background agents — keeping the main context lean (only discuss conversations accumulate) and enabling overlap. On every other runtime (Claude Code and all other non-Codex runtimes), backgrounded agents cannot reliably nest subagents, so plan and execute run inline to preserve worktree isolation and independent verification, and phases run sequentially with their work accumulating in the main context. Either way, user input is preserved on all design decisions.
65
65
 
66
66
  When `PLAN_STRATEGY=converge`, the planning step MUST invoke the plan-review convergence workflow instead of `gsd-plan-phase`. `--cross-ai` is an alias for `--converge`. Forward `CONVERGENCE_ARGS` exactly as parsed so reviewer flags and `--max-cycles N` retain the same meaning as they have on `/gsd:plan-review-convergence`.
67
67
 
@@ -123,18 +123,19 @@ If `PLAN_STRATEGY` is `converge`, display: `Planning: Plan-review convergence en
123
123
  Run phase discovery:
124
124
 
125
125
  ```bash
126
- ROADMAP=$(gsd_run query roadmap.analyze)
126
+ INIT_MANAGER=$(gsd_run query init.manager)
127
+ if [[ "$INIT_MANAGER" == @file:* ]]; then INIT_MANAGER=$(cat "${INIT_MANAGER#@file:}"); fi
127
128
  ```
128
129
 
129
130
  Parse the JSON `phases` array.
130
131
 
131
- **Filter to incomplete phases:** Keep only phases where `disk_status !== "complete"` OR `roadmap_complete === false`.
132
+ **Filter to incomplete phases:** Keep `phase_complete !== true`, including implemented phases with `verification_status !== "passed"`.
132
133
 
133
- **Apply `--from N` filter:** If `FROM_PHASE` was provided, additionally filter out phases where `number < FROM_PHASE` (use numeric comparison — handles decimal phases like "5.1").
134
+ **Apply `--from N`:** If set, filter out phases where `number < FROM_PHASE` (numeric compare; handles "5.1").
134
135
 
135
- **Apply `--to N` filter:** If `TO_PHASE` was provided, additionally filter out phases where `number > TO_PHASE` (use numeric comparison). This limits execution to phases up through the target phase.
136
+ **Apply `--to N`:** If set, filter out phases where `number > TO_PHASE` (numeric compare).
136
137
 
137
- **Apply `--only N` filter:** If `ONLY_PHASE` was provided, additionally filter OUT phases where `number != ONLY_PHASE`. This means the phase list will contain exactly one phase (or zero if already complete).
138
+ **Apply `--only N`:** If set, filter out phases where `number != ONLY_PHASE`.
138
139
 
139
140
  **If `TO_PHASE` is set and no phases remain** (all phases up to N are already completed):
140
141
 
@@ -477,58 +478,51 @@ Skill(skill="gsd-code-review", args="${PHASE_NUM} --fix --auto")
477
478
 
478
479
  **3d. Post-Execution Routing**
479
480
 
480
- **If `INTERACTIVE` is set:** Wait for the execute agent to complete before reading verification results.
481
-
482
- After execute-phase returns (or the execute agent completes), read the verification result:
483
-
484
- ```bash
485
- VERIFY_STATUS=$(grep "^status:" "${PHASE_DIR}"/*-VERIFICATION.md 2>/dev/null | head -1 | cut -d: -f2 | tr -d ' ')
486
- ```
487
-
488
- Where `PHASE_DIR` comes from the `init phase-op` call already made in step 3a. If the variable is not in scope, re-fetch:
481
+ After execute, read canonical verification:
489
482
 
490
483
  ```bash
491
- PHASE_STATE=$(gsd_run query init.phase-op ${PHASE_NUM})
484
+ VERIFY_STATUS=$(gsd_run query verification.status "${PHASE_DIR}" 2>/dev/null | jq -r '.status//empty')
492
485
  ```
493
486
 
494
- Parse `phase_dir` from the JSON.
487
+ If `PHASE_DIR` is absent, re-fetch `init.phase-op ${PHASE_NUM}` and parse `phase_dir`.
495
488
 
496
- **If VERIFY_STATUS is empty** (no VERIFICATION.md or no status field):
497
-
498
- Go to handle_blocker: "Execute phase ${PHASE_NUM} did not produce verification results."
489
+ If `VERIFY_STATUS` is empty, handle_blocker: "No verification results for phase ${PHASE_NUM}."
499
490
 
500
491
  **If `passed`:**
501
492
 
502
- Display:
503
- ```
504
- Phase ${PHASE_NUM} ✅ ${PHASE_NAME} — Verification passed
505
- ```
493
+ Display `Phase ${PHASE_NUM} ✅ ${PHASE_NAME} — Verification passed`, run `@~/.claude/gsd-core/workflows/transition.md`, then Proceed to iterate step.
506
494
 
507
- Proceed to iterate step.
495
+ **If `stale`:** handle_blocker: "Stale verification for phase ${PHASE_NUM}."
508
496
 
509
497
  **If `human_needed`:**
510
498
 
511
- Read the human_verification section from VERIFICATION.md to get the count and items requiring manual testing.
512
-
513
-
514
- **Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
515
- Display the items, then ask user via AskUserQuestion:
499
+ Read `human_verification` items. In text mode (`--text` or init `text_mode=true`), replace AskUserQuestion with a numbered list and typed choice. Otherwise display items and ask:
516
500
  - **question:** "Phase ${PHASE_NUM} has items needing manual verification. Validate now or continue to next phase?"
517
501
  - **options:** "Validate now" / "Continue without validation"
518
502
 
519
- On **"Validate now"**: Present the specific items from VERIFICATION.md's human_verification section. After user reviews, ask:
503
+ On **"Validate now"**: Present items, then ask:
520
504
  - **question:** "Validation result?"
521
505
  - **options:** "All good — continue" / "Found issues"
522
506
 
523
- On "All good — continue": Display `Phase ${PHASE_NUM} ✅ Human validation passed` and proceed to iterate step.
507
+ On "All good — continue": set VERIFICATION frontmatter `status: passed`, display `Phase ${PHASE_NUM} ✅ Human validation passed`, run `@~/.claude/gsd-core/workflows/transition.md`, then iterate.
524
508
 
525
509
  On "Found issues": Go to handle_blocker with the user's reported issues as the description.
526
510
 
527
- On **"Continue without validation"**: Display `Phase ${PHASE_NUM} ⏭ Human validation deferred` and proceed to iterate step.
511
+ On **"Continue without validation"**: record an explicit deferred state and stop autonomous mode:
512
+
513
+ ```markdown
514
+ ## Deferred Verification
515
+
516
+ | Phase | State | Resume |
517
+ |-------|-------|--------|
518
+ | ${PHASE_NUM} | verification_deferred_human | /gsd:verify-work ${PHASE_NUM} |
519
+ ```
520
+
521
+ Append/update this STATE.md section, display `Phase ${PHASE_NUM} ⏭ verification_deferred_human — resume with /gsd:verify-work ${PHASE_NUM}`, then handle_blocker: "Human verification deferred for phase ${PHASE_NUM}."
528
522
 
529
523
  **If `gaps_found`:**
530
524
 
531
- Read gap summary from VERIFICATION.md (score and missing items). Display:
525
+ Read gap score/items from VERIFICATION.md. Display:
532
526
  ```
533
527
  ⚠ Phase ${PHASE_NUM}: ${PHASE_NAME} — Gaps Found
534
528
  Score: {N}/{M} must-haves verified
@@ -538,13 +532,13 @@ Ask user via AskUserQuestion:
538
532
  - **question:** "Gaps found in phase ${PHASE_NUM}. How to proceed?"
539
533
  - **options:** "Run gap closure" / "Continue without fixing" / "Stop autonomous mode"
540
534
 
541
- On **"Run gap closure"**: Execute gap closure cycle (limit: 1 attempt):
535
+ On **"Run gap closure"**: one gap-closure attempt:
542
536
 
543
537
  ```
544
538
  Skill(skill="gsd-plan-phase", args="${PHASE_NUM} --gaps")
545
539
  ```
546
540
 
547
- Verify gap plans were created — re-run `init phase-op ${PHASE_NUM}` and check `has_plans`. If no new gap plans → go to handle_blocker: "Gap closure planning for phase ${PHASE_NUM} did not produce plans."
541
+ Re-run `init phase-op ${PHASE_NUM}`; if `has_plans` is false, handle_blocker: "Gap closure planning for phase ${PHASE_NUM} did not produce plans."
548
542
 
549
543
  Re-execute:
550
544
  ```
@@ -553,27 +547,39 @@ Skill(skill="gsd-execute-phase", args="${PHASE_NUM} --no-transition")
553
547
 
554
548
  Re-read verification status:
555
549
  ```bash
556
- VERIFY_STATUS=$(grep "^status:" "${PHASE_DIR}"/*-VERIFICATION.md 2>/dev/null | head -1 | cut -d: -f2 | tr -d ' ')
550
+ VERIFY_STATUS=$(gsd_run query verification.status "${PHASE_DIR}" 2>/dev/null | jq -r '.status//empty')
557
551
  ```
558
552
 
559
- If `passed` or `human_needed`: Route normally (continue or ask user as above).
553
+ If `passed` or `human_needed`: route normally.
554
+
555
+ If `stale`: handle_blocker: "Stale verification for phase ${PHASE_NUM}."
560
556
 
561
557
  If still `gaps_found` after this retry: Display "Gaps persist after closure attempt." and ask via AskUserQuestion:
562
558
  - **question:** "Gap closure did not fully resolve issues. How to proceed?"
563
559
  - **options:** "Continue anyway" / "Stop autonomous mode"
564
560
 
565
- On "Continue anyway": Proceed to iterate step.
561
+ On "Continue anyway": record `verification_deferred_gaps` using the table below, display `Phase ${PHASE_NUM} ⏭ verification_deferred_gaps — resume with /gsd:plan-phase ${PHASE_NUM} --gaps`, then handle_blocker: "Verification gaps deferred for phase ${PHASE_NUM}."
566
562
  On "Stop autonomous mode": Go to handle_blocker.
567
563
 
568
- This limits gap closure to 1 automatic retry to prevent infinite loops.
564
+ This limits gap closure to 1 retry.
565
+
566
+ On **"Continue without fixing"**: record an explicit deferred state and stop autonomous mode:
567
+
568
+ ```markdown
569
+ ## Deferred Verification
570
+
571
+ | Phase | State | Resume |
572
+ |-------|-------|--------|
573
+ | ${PHASE_NUM} | verification_deferred_gaps | /gsd:plan-phase ${PHASE_NUM} --gaps |
574
+ ```
569
575
 
570
- On **"Continue without fixing"**: Display `Phase ${PHASE_NUM} ⏭ Gaps deferred` and proceed to iterate step.
576
+ Append/update this STATE.md section, display `Phase ${PHASE_NUM} ⏭ verification_deferred_gaps — resume with /gsd:plan-phase ${PHASE_NUM} --gaps`, then handle_blocker: "Verification gaps deferred for phase ${PHASE_NUM}."
571
577
 
572
578
  On **"Stop autonomous mode"**: Go to handle_blocker with "User stopped — gaps remain in phase ${PHASE_NUM}".
573
579
 
574
580
  **3d.5. UI Review (Frontend Phases)**
575
581
 
576
- > Run after any successful execution routing (passed, human_needed accepted, or gaps deferred/accepted) — before proceeding to the iterate step.
582
+ > Run only after `passed` or human verification was updated to `passed`.
577
583
 
578
584
  Resolve the active post-verification hooks and the UI-SPEC gate:
579
585
 
@@ -632,16 +638,17 @@ Read and execute: `$HOME/.claude/gsd-core/references/autonomous-smart-discuss.md
632
638
  Resume with: /gsd:autonomous --from ${next_incomplete_phase}
633
639
  ```
634
640
 
635
- Proceed directly to lifecycle step (which handles partial completion — skips audit/complete/cleanup since not all phases are done). Exit cleanly.
641
+ Proceed to lifecycle step (partial completion skips audit/complete/cleanup). Exit cleanly.
636
642
 
637
- **Otherwise:** After each phase completes, re-read ROADMAP.md to catch phases inserted mid-execution (decimal phases like 5.1):
643
+ **Otherwise:** After each phase, re-read manager projection:
638
644
 
639
645
  ```bash
640
- ROADMAP=$(gsd_run query roadmap.analyze)
646
+ INIT_MANAGER=$(gsd_run query init.manager)
647
+ if [[ "$INIT_MANAGER" == @file:* ]]; then INIT_MANAGER=$(cat "${INIT_MANAGER#@file:}"); fi
641
648
  ```
642
649
 
643
650
  Re-filter incomplete phases using the same logic as discover_phases:
644
- - Keep phases where `disk_status !== "complete"` OR `roadmap_complete === false`
651
+ - Keep phases where `phase_complete !== true` or `verification_status !== "passed"`
645
652
  - Apply `--from N` filter if originally provided
646
653
  - Apply `--to N` filter if originally provided
647
654
  - Sort by number ascending
@@ -72,27 +72,44 @@ If user chooses [A] (Acknowledge):
72
72
  ...
73
73
  ```
74
74
  Sanitize all slug and status values via `sanitizeForDisplay()` before writing. Never inject raw file content into STATE.md.
75
- 3. Record in MILESTONES.md entry: `Known deferred items at close: {count} (see STATE.md Deferred Items)`
75
+ 3. Set `closeout_type=override_closeout` and record `Known verification overrides: {count} (see STATE.md Deferred Items)` in the MILESTONES.md entry.
76
76
  4. Proceed with milestone close.
77
77
 
78
- If output shows all clear (no open items): print `All artifact types clear.` and proceed.
78
+ If output shows all clear (no open items): set `closeout_type=verified_closeout`, print `All artifact types clear.`, and proceed.
79
79
 
80
80
  SECURITY: Audit JSON output is structured data from the `audit-open` query handler (same JSON contract as legacy `gsd-tools.cjs audit-open`) — validated and sanitized at source. When writing to STATE.md, item slugs and descriptions are sanitized via `sanitizeForDisplay()` before inclusion. Never inject raw user-supplied content into STATE.md without sanitization.
81
81
  </step>
82
82
 
83
83
  <step name="verify_readiness">
84
84
 
85
- **Use `roadmap analyze` for comprehensive readiness check:**
85
+ **Use `init.manager` for canonical readiness check:**
86
86
 
87
87
  ```bash
88
- ROADMAP=$(gsd_run query roadmap.analyze)
88
+ INIT_MANAGER=$(gsd_run query init.manager)
89
+ if [[ "$INIT_MANAGER" == @file:* ]]; then INIT_MANAGER=$(cat "${INIT_MANAGER#@file:}"); fi
89
90
  ```
90
91
 
91
- This returns all phases with plan/summary counts and disk status. Use this to verify:
92
+ This returns all phases with implementation and verification projection. Use this to verify:
92
93
  - Which phases belong to this milestone?
93
- - All phases complete (all plans have summaries)? Check `disk_status === 'complete'` for each.
94
+ - `all_phases_verified`: all milestone phases have `phase_complete === true` and `verification_status === 'passed'`.
94
95
  - `progress_percent` should be 100%.
95
96
 
97
+ Compute readiness from `INIT_MANAGER`, not from roadmap counts:
98
+
99
+ ```bash
100
+ ALL_PHASES_VERIFIED=$(printf '%s' "$INIT_MANAGER" | jq -r '[
101
+ .phases[] | select((.number | tostring | test("^999(\\.|$)") | not))
102
+ | (.phase_complete == true and .verification_status == "passed")
103
+ ] | all')
104
+ ```
105
+
106
+ If not all_phases_verified, verified_closeout must not proceed. Set `closeout_type=override_closeout`, show each phase whose `phase_complete !== true` or `verification_status !== 'passed'`, and require an explicit user choice:
107
+ 1. **Proceed anyway** — record verification overrides in MILESTONES.md/STATE.md
108
+ 2. **Run verification first** — `/gsd:verify-work {phase}` or `/gsd:execute-phase {phase}`
109
+ 3. **Abort** — return to development
110
+
111
+ Only set `closeout_type=verified_closeout` when `ALL_PHASES_VERIFIED` is `true`.
112
+
96
113
  **Requirements completion check (REQUIRED before presenting):**
97
114
 
98
115
  Parse REQUIREMENTS.md traceability table:
@@ -110,7 +127,9 @@ Includes:
110
127
  - Phase 3: Core Features (3/3 plans complete)
111
128
  - Phase 4: Polish (1/1 plan complete)
112
129
 
113
- Total: {phase_count} phases, {total_plans} plans, all complete
130
+ Total: {phase_count} phases, {total_plans} plans
131
+ Verification: {all_phases_verified ? "all phases verified" : "override needed"}
132
+ Closeout type: {closeout_type}
114
133
  Requirements: {N}/{M} v1 requirements checked off
115
134
  ```
116
135
 
@@ -128,7 +147,7 @@ MUST present 3 options:
128
147
  2. **Run audit first** — `/gsd:audit-milestone` to assess gap severity
129
148
  3. **Abort** — return to development
130
149
 
131
- If user selects "Proceed anyway": note incomplete requirements in MILESTONES.md under `### Known Gaps` with REQ-IDs and descriptions.
150
+ If user selects "Proceed anyway": set `closeout_type=override_closeout`; note incomplete requirements in MILESTONES.md under `### Known Gaps` with REQ-IDs and descriptions.
132
151
 
133
152
  <config-check>
134
153
 
@@ -580,7 +580,7 @@ increases monotonically across waves. `{status}` is `complete` (success),
580
580
  DISPATCH_TS=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
581
581
  EXPECTED_BRANCH=$(git rev-parse --abbrev-ref HEAD)
582
582
  if [ "${USE_WORKTREES_FOR_PLAN:-true}" != "false" ] && [ -z "${WAVE_WORKTREE_MANIFEST:-}" ]; then
583
- WAVE_WORKTREE_MANIFEST=$(mktemp "${TMPDIR:-/tmp}/gsd-worktree-wave-XXXXXX.json")
583
+ M=$(mktemp "${TMPDIR:-/tmp}/gsd-worktree-wave-XXXXXX") && mv "$M" "$M.json" && WAVE_WORKTREE_MANIFEST="$M.json" || exit 1 # XXXXXX must be path-final on BSD/macOS (#1520)
584
584
  # Persist the dispatch-time orchestrator worktree root so wave-cleanup can pin back to the
585
585
  # orchestrator's OWN worktree — NOT `git worktree list`'s first entry (always the main
586
586
  # checkout), which pins a non-primary (per-phase lane) orchestrator off its branch (#630).
@@ -377,6 +377,11 @@ Create `{phase}-{plan}-SUMMARY.md` at `.planning/phases/XX-name/`. Use `~/.claud
377
377
 
378
378
  **Frontmatter:** phase, plan, subsystem, tags | requires/provides/affects | tech-stack.added/patterns | key-files.created/modified | key-decisions | requirements-completed (**MUST** copy `requirements` array from PLAN.md frontmatter verbatim) | duration ($DURATION), completed ($PLAN_END_TIME date).
379
379
 
380
+ **Coverage block (#1602):** Populate the `coverage:` frontmatter block — one entry per shipped deliverable (the structured form of each `## Accomplishments` bullet). For each deliverable, aggregate the task-level `<verify>` results and tests:
381
+ - A task whose `<verify>` command passed or whose matching test passed → a `verification` entry with `kind` + `ref` (`tests/path#name`, Playwright screenshot ref, or command) + `status: pass`, and `human_judgment: false`.
382
+ - A judgment-dependent deliverable (UX adequacy, external/multi-session behavior, anything no test asserts) → `human_judgment: true` with a `rationale`.
383
+ - **Every deliverable MUST be classified.** If you cannot determine coverage, default to `human_judgment: true` with `rationale: "Coverage not determined at authoring time — verifier must classify"`. Never set `human_judgment: false` without a non-empty all-`pass` `verification` — `verify-work` auto-passes (skips the human) ONLY on that proof, so an unproven `false` still routes to the human but loses the audit trail. Omit the whole block only for a genuinely prose-only SUMMARY (verify-work then uses the legacy `## Accomplishments` path). The block is validated downstream by `gsd-tools uat classify-coverage`.
384
+
380
385
  Title: `# Phase [X] Plan [Y]: [Name] Summary`
381
386
 
382
387
  One-liner SUBSTANTIVE: "JWT auth with refresh rotation using jose library" not "Authentication implemented"
@@ -72,6 +72,7 @@ Build dashboard from JSON. Symbols: `✓` done, `◆` active, `○` pending, `·
72
72
  **Status mapping** (disk_status → D P E Status):
73
73
 
74
74
  - `complete` → `✓ ✓ ✓` `✓ Complete`
75
+ - `executed` → `✓ ✓ ◆` `◆ Verification required`
75
76
  - `partial` → `✓ ✓ ◆` `◆ Executing...`
76
77
  - `planned` → `✓ ✓ ○` `○ Ready to execute`
77
78
  - `discussed` → `✓ ○ ·` `○ Ready to plan`
@@ -135,7 +136,7 @@ If `all_complete` is true:
135
136
  ║ MILESTONE COMPLETE ║
136
137
  ╚══════════════════════════════════════════════════════════════╝
137
138
 
138
- All {phase_count} phases done. Ready for final steps:
139
+ All {phase_count} phases verified complete. Ready for final steps:
139
140
  → /gsd:verify-work — run acceptance testing
140
141
  → /gsd:complete-milestone — archive and wrap up
141
142
  ```
@@ -158,8 +159,9 @@ Handle responses:
158
159
  **Building options:**
159
160
 
160
161
  1. Collect all background actions (execute and plan recommendations) — there can be multiple of each.
161
- 2. Collect the inline action (discuss recommendation, if any — there will be at most one since discuss is sequential).
162
- 3. Build compound options:
162
+ 2. Collect verification actions (`verify`) for implementation-complete phases whose canonical verification has not passed.
163
+ 3. Collect the inline action (discuss recommendation, if any — there will be at most one since discuss is sequential).
164
+ 4. Build compound options:
163
165
 
164
166
  **If there are ANY recommended actions (background, inline, or both):**
165
167
  Create ONE primary "Continue" option that dispatches ALL of them together:
@@ -169,10 +171,11 @@ Handle responses:
169
171
  Continue:
170
172
  → Execute Phase 32 (background)
171
173
  → Plan Phase 34 (background)
174
+ → Verify Phase 33
172
175
  → Discuss Phase 35 (inline)
173
176
  ```
174
- - This dispatches all background agents first, then runs the inline discuss (if any).
175
- - If there is no inline discuss, the dashboard refreshes after spawning background agents.
177
+ - This dispatches all background agents first, runs verification actions inline, then runs the inline discuss (if any).
178
+ - If there is no inline discuss, the dashboard refreshes after spawning background agents and inline verification.
176
179
 
177
180
  **Important:** The Continue option must include EVERY action from `recommended_actions` — not just 2. If there are 3 actions, list 3. If there are 5, list 5.
178
181
 
@@ -221,8 +224,15 @@ Go to exit step.
221
224
 
222
225
  When the user selects a compound option, behavior depends on the runtime — the Plan Phase N / Execute Phase N handlers below resolve it via `gsd_run query config-get runtime`:
223
226
 
224
- - **On Codex:** **Spawn all background agents first** (plan/execute) — dispatch them in parallel using the Plan Phase N / Execute Phase N handlers below — then run the inline discuss; the background agents continue while you discuss.
225
- - **Otherwise (Claude Code or any other non-Codex runtime):** a backgrounded agent cannot reliably nest the pipeline's subagents, so run the chosen plan/execute step(s) **inline** via their handlers below (in order), then run the inline discuss. There is no overlap.
227
+ - **On Codex:** **Spawn all background agents first** (plan/execute) — dispatch them in parallel using the Plan Phase N / Execute Phase N handlers below — then run verification actions, then run the inline discuss; the background agents continue while you verify/discuss.
228
+ - **On Claude Code or any other non-Codex runtime:** run the chosen plan/execute step(s) **inline** via their handlers below (in order), then run verification actions, then run the inline discuss. There is no overlap.
229
+
230
+ Inline verification:
231
+
232
+ For each verification recommendation, dispatch by the recommended action's `command`:
233
+ - If `command` contains `execute-phase`, run `Skill(skill="gsd-execute-phase", args="{PHASE_NUM} {manager_flags.execute}")`.
234
+ - If `command` contains `verify-work`, run `Skill(skill="gsd-verify-work", args="{PHASE_NUM}")`.
235
+ - If `command` is missing or unrecognized, stop and show the recommendation row instead of guessing.
226
236
 
227
237
  Inline discuss:
228
238
 
@@ -109,9 +109,9 @@ elif [ -n "$OPENCODE_CONFIG_DIR" ] || [ -n "$OPENCODE_CONFIG" ]; then RUNTIME="o
109
109
  else RUNTIME="claude"; fi
110
110
  ```
111
111
 
112
- Set the instruction file variable:
112
+ Set the instruction file variable via the shared runtime-name policy adapter (`gsd-tools query project-instruction-file`, backed by `getProjectInstructionFile` in `runtime-name-policy.cjs` — the single source of truth shared with `profile-output.cjs`):
113
113
  ```bash
114
- if [ "$RUNTIME" = "codex" ]; then INSTRUCTION_FILE="AGENTS.md"; else INSTRUCTION_FILE=".claude/CLAUDE.md"; fi
114
+ INSTRUCTION_FILE=$(gsd_run query project-instruction-file --runtime "$RUNTIME")
115
115
  ```
116
116
 
117
117
  All subsequent references to the project instruction file use `$INSTRUCTION_FILE`.
@@ -230,19 +230,52 @@ AskUserQuestion([
230
230
  { label: "Yes (Recommended)", description: "Resolve symbol references against live source during plan review — catches hallucinated names before execution" },
231
231
  { label: "No", description: "Skip symbol grounding — plan review proceeds without source verification" }
232
232
  ]
233
- },
233
+ }
234
+ ])
235
+
236
+ // Model profile uses a two-question split because AskUserQuestion enforces a hard
237
+ // 4-option cap and there are 5 valid profiles (quality, balanced, budget, adaptive,
238
+ // inherit). Q1 routes between adaptive/standard-tier/inherit; Q2 (shown only when
239
+ // Q1 = "Standard tier…") picks among the three standard profiles. Mirrors the
240
+ // /gsd:settings split (#3784, #1516).
241
+ AskUserQuestion([
234
242
  {
235
243
  header: "AI Models",
236
244
  question: "Which AI models for planning agents?",
237
245
  multiSelect: false,
238
246
  options: [
239
- { label: "Balanced (Recommended)", description: "Sonnet for most agents — good quality/cost ratio" },
240
- { label: "Quality", description: "Opus for research/roadmap — higher cost, deeper analysis" },
241
- { label: "Budget", description: "Haiku where possible — fastest, lowest cost" },
242
- { label: "Inherit", description: "Use the current session model for all agents (OpenCode /model)" }
247
+ { label: "Adaptive (Recommended)", description: "Role-based cost optimization: heavy roles use the highest-tier model available on the active runtime, light roles use the cheapest. Best balance of quality and cost across all supported runtimes (Claude, Codex, Gemini, OpenRouter, local)." },
248
+ { label: "Standard tier…", description: "Choose Quality, Balanced, or Budget — flat tier applied to all agents" },
249
+ { label: "Inherit", description: "Use the current session model for all agents (required for non-Claude runtimes: Codex, Gemini CLI, OpenCode /model, OpenRouter, local models)" }
243
250
  ]
244
251
  }
245
252
  ])
253
+
254
+ **Conditional visibility — model_profile (Q2):**
255
+ Only ask this question when Q1's answer is "Standard tier…".
256
+ If Q1 = "Adaptive (Recommended)" → write model_profile=adaptive and SKIP Q2.
257
+ If Q1 = "Inherit" → write model_profile=inherit and SKIP Q2.
258
+ If user cancels Q2 after picking "Standard tier…" → leave existing model_profile value unchanged.
259
+
260
+ AskUserQuestion([
261
+ {
262
+ question: "Which standard profile? (Quality / Balanced / Budget)",
263
+ header: "Model Tier",
264
+ multiSelect: false,
265
+ options: [
266
+ { label: "Quality", description: "Opus everywhere except verification (highest cost) — Claude only" },
267
+ { label: "Balanced", description: "Opus for planning, Sonnet for research/execution/verification — Claude only" },
268
+ { label: "Budget", description: "Sonnet for writing, Haiku for research/verification (lowest cost) — Claude only" }
269
+ ]
270
+ }
271
+ ])
272
+
273
+ // Map UI choices → config values:
274
+ // Q1 "Adaptive (Recommended)" → model_profile = "adaptive"
275
+ // Q1 "Inherit" → model_profile = "inherit"
276
+ // Q1 "Standard tier…" + Q2 "Quality" → model_profile = "quality"
277
+ // Q1 "Standard tier…" + Q2 "Balanced" → model_profile = "balanced"
278
+ // Q1 "Standard tier…" + Q2 "Budget" → model_profile = "budget"
246
279
  ```
247
280
 
248
281
  **Round 3 — PR body onboarding:**
@@ -273,7 +306,7 @@ Create `.planning/config.json` with all settings (CLI fills in remaining default
273
306
 
274
307
  ```bash
275
308
  mkdir -p .planning
276
- gsd_run query config-new-project '{"mode":"yolo","granularity":"[selected]","parallelization":true|false,"commit_docs":true|false,"model_profile":"quality|balanced|budget|inherit","workflow":{"research":true|false,"plan_check":true|false,"verifier":true|false,"nyquist_validation":true|false,"auto_advance":true},"plan_review":{"source_grounding":true|false},"ship":{"pr_body_sections":[{"heading":"User Stories & Acceptance Criteria","enabled":true|false,"source":"REQUIREMENTS.md ## User Stories || REQUIREMENTS.md ## Acceptance Criteria","fallback":"- Acceptance criteria are covered by the linked requirements and verification evidence."},{"heading":"Risks & Dependencies","enabled":true|false,"source":"PLAN.md ## Risks || PLAN.md ## Dependencies","fallback":"- No known high-risk rollout dependencies."},{"heading":"Success Metrics & Release Criteria","enabled":true|false,"source":"REQUIREMENTS.md ## Definition of Done || VERIFICATION.md ## Release Criteria","fallback":"- Release when automated verification and required manual checks pass."},{"heading":"Stakeholder Review & Approval","enabled":true|false,"template":"- Product owner approval pending for {phase_name}."}]}}'
309
+ gsd_run query config-new-project '{"mode":"yolo","granularity":"[selected]","parallelization":true|false,"commit_docs":true|false,"model_profile":"quality|balanced|budget|adaptive|inherit","workflow":{"research":true|false,"plan_check":true|false,"verifier":true|false,"nyquist_validation":true|false,"auto_advance":true},"plan_review":{"source_grounding":true|false},"ship":{"pr_body_sections":[{"heading":"User Stories & Acceptance Criteria","enabled":true|false,"source":"REQUIREMENTS.md ## User Stories || REQUIREMENTS.md ## Acceptance Criteria","fallback":"- Acceptance criteria are covered by the linked requirements and verification evidence."},{"heading":"Risks & Dependencies","enabled":true|false,"source":"PLAN.md ## Risks || PLAN.md ## Dependencies","fallback":"- No known high-risk rollout dependencies."},{"heading":"Success Metrics & Release Criteria","enabled":true|false,"source":"REQUIREMENTS.md ## Definition of Done || VERIFICATION.md ## Release Criteria","fallback":"- Release when automated verification and required manual checks pass."},{"heading":"Stakeholder Review & Approval","enabled":true|false,"template":"- Product owner approval pending for {phase_name}."}]}}'
277
310
  ```
278
311
 
279
312
  **If commit_docs = No:** Add `.planning/` to `.gitignore`.
@@ -745,19 +778,52 @@ questions: [
745
778
  { label: "Yes (Recommended)", description: "Confirm deliverables match phase goals" },
746
779
  { label: "No", description: "Trust execution, skip verification" }
747
780
  ]
748
- },
781
+ }
782
+ ]
783
+
784
+ // Model profile uses a two-question split because AskUserQuestion enforces a hard
785
+ // 4-option cap and there are 5 valid profiles (quality, balanced, budget, adaptive,
786
+ // inherit). Q1 routes between adaptive/standard-tier/inherit; Q2 (shown only when
787
+ // Q1 = "Standard tier…") picks among the three standard profiles. Mirrors the
788
+ // /gsd:settings split (#3784, #1516).
789
+ questions: [
749
790
  {
750
791
  header: "AI Models",
751
792
  question: "Which AI models for planning agents?",
752
793
  multiSelect: false,
753
794
  options: [
754
- { label: "Balanced (Recommended)", description: "Sonnet for most agents — good quality/cost ratio" },
755
- { label: "Quality", description: "Opus for research/roadmap — higher cost, deeper analysis" },
756
- { label: "Budget", description: "Haiku where possible — fastest, lowest cost" },
757
- { label: "Inherit", description: "Use the current session model for all agents (OpenCode /model)" }
795
+ { label: "Adaptive (Recommended)", description: "Role-based cost optimization: heavy roles use the highest-tier model available on the active runtime, light roles use the cheapest. Best balance of quality and cost across all supported runtimes (Claude, Codex, Gemini, OpenRouter, local)." },
796
+ { label: "Standard tier…", description: "Choose Quality, Balanced, or Budget — flat tier applied to all agents" },
797
+ { label: "Inherit", description: "Use the current session model for all agents (required for non-Claude runtimes: Codex, Gemini CLI, OpenCode /model, OpenRouter, local models)" }
758
798
  ]
759
799
  }
760
800
  ]
801
+
802
+ **Conditional visibility — model_profile (Q2):**
803
+ Only ask this question when Q1's answer is "Standard tier…".
804
+ If Q1 = "Adaptive (Recommended)" → write model_profile=adaptive and SKIP Q2.
805
+ If Q1 = "Inherit" → write model_profile=inherit and SKIP Q2.
806
+ If user cancels Q2 after picking "Standard tier…" → leave existing model_profile value unchanged.
807
+
808
+ questions: [
809
+ {
810
+ question: "Which standard profile? (Quality / Balanced / Budget)",
811
+ header: "Model Tier",
812
+ multiSelect: false,
813
+ options: [
814
+ { label: "Quality", description: "Opus everywhere except verification (highest cost) — Claude only" },
815
+ { label: "Balanced", description: "Opus for planning, Sonnet for research/execution/verification — Claude only" },
816
+ { label: "Budget", description: "Sonnet for writing, Haiku for research/verification (lowest cost) — Claude only" }
817
+ ]
818
+ }
819
+ ]
820
+
821
+ // Map UI choices → config values:
822
+ // Q1 "Adaptive (Recommended)" → model_profile = "adaptive"
823
+ // Q1 "Inherit" → model_profile = "inherit"
824
+ // Q1 "Standard tier…" + Q2 "Quality" → model_profile = "quality"
825
+ // Q1 "Standard tier…" + Q2 "Balanced" → model_profile = "balanced"
826
+ // Q1 "Standard tier…" + Q2 "Budget" → model_profile = "budget"
761
827
  ```
762
828
 
763
829
  **PR body onboarding:** Ask which optional PRD-style sections `/gsd:ship` should append to generated PR bodies. Use the same `ship.pr_body_sections` mapping as Step 2a: selected sections get `enabled: true`, seeded-but-unselected sections get `enabled: false`, and selecting none writes an empty list. Prefer lean/agile PRD sections that make user value, acceptance criteria, Definition of Done, and stakeholder traceability explicit.
@@ -773,7 +839,7 @@ Create `.planning/config.json` with all settings (CLI fills in remaining default
773
839
 
774
840
  ```bash
775
841
  mkdir -p .planning
776
- gsd_run query config-new-project '{"mode":"[yolo|interactive]","granularity":"[selected]","parallelization":true|false,"commit_docs":true|false,"model_profile":"quality|balanced|budget|inherit","workflow":{"research":true|false,"plan_check":true|false,"verifier":true|false,"nyquist_validation":[false if granularity=coarse, true otherwise]},"plan_review":{"source_grounding":true|false},"ship":{"pr_body_sections":[{"heading":"User Stories & Acceptance Criteria","enabled":true|false,"source":"REQUIREMENTS.md ## User Stories || REQUIREMENTS.md ## Acceptance Criteria","fallback":"- Acceptance criteria are covered by the linked requirements and verification evidence."},{"heading":"Risks & Dependencies","enabled":true|false,"source":"PLAN.md ## Risks || PLAN.md ## Dependencies","fallback":"- No known high-risk rollout dependencies."},{"heading":"Success Metrics & Release Criteria","enabled":true|false,"source":"REQUIREMENTS.md ## Definition of Done || VERIFICATION.md ## Release Criteria","fallback":"- Release when automated verification and required manual checks pass."},{"heading":"Stakeholder Review & Approval","enabled":true|false,"template":"- Product owner approval pending for {phase_name}."}]}}'
842
+ gsd_run query config-new-project '{"mode":"[yolo|interactive]","granularity":"[selected]","parallelization":true|false,"commit_docs":true|false,"model_profile":"quality|balanced|budget|adaptive|inherit","workflow":{"research":true|false,"plan_check":true|false,"verifier":true|false,"nyquist_validation":[false if granularity=coarse, true otherwise]},"plan_review":{"source_grounding":true|false},"ship":{"pr_body_sections":[{"heading":"User Stories & Acceptance Criteria","enabled":true|false,"source":"REQUIREMENTS.md ## User Stories || REQUIREMENTS.md ## Acceptance Criteria","fallback":"- Acceptance criteria are covered by the linked requirements and verification evidence."},{"heading":"Risks & Dependencies","enabled":true|false,"source":"PLAN.md ## Risks || PLAN.md ## Dependencies","fallback":"- No known high-risk rollout dependencies."},{"heading":"Success Metrics & Release Criteria","enabled":true|false,"source":"REQUIREMENTS.md ## Definition of Done || VERIFICATION.md ## Release Criteria","fallback":"- Release when automated verification and required manual checks pass."},{"heading":"Stakeholder Review & Approval","enabled":true|false,"template":"- Product owner approval pending for {phase_name}."}]}}'
777
843
  ```
778
844
 
779
845
  **Note:** Run `/gsd:settings` anytime to update model profile, workflow agents, branching strategy, and other preferences.
@@ -1533,7 +1599,7 @@ PHASE1_HAS_UI=$(echo "$PHASE1_SECTION" | grep -qi "UI hint.*yes" && echo "true"
1533
1599
  - `.planning/REQUIREMENTS.md`
1534
1600
  - `.planning/ROADMAP.md`
1535
1601
  - `.planning/STATE.md`
1536
- - `$INSTRUCTION_FILE` (`AGENTS.md` for Codex, `.claude/CLAUDE.md` for all other runtimes)
1602
+ - `$INSTRUCTION_FILE` (runtime-derived via the shared `getProjectInstructionFile` policy: `AGENTS.md` for codex/opencode/kilo/kimi, `.github/copilot-instructions.md` for copilot, `GEMINI.md` for gemini/antigravity, `.claude/CLAUDE.md` for claude)
1537
1603
 
1538
1604
  </output>
1539
1605
 
@@ -1555,7 +1621,7 @@ PHASE1_HAS_UI=$(echo "$PHASE1_SECTION" | grep -qi "UI hint.*yes" && echo "true"
1555
1621
  - [ ] ROADMAP.md created with phases, requirement mappings, success criteria
1556
1622
  - [ ] STATE.md initialized
1557
1623
  - [ ] REQUIREMENTS.md traceability updated
1558
- - [ ] `$INSTRUCTION_FILE` generated with GSD workflow guidance (AGENTS.md for Codex, `.claude/CLAUDE.md` otherwise; an existing hand-crafted file without GSD markers is left untouched unless `--force`)
1624
+ - [ ] `$INSTRUCTION_FILE` generated with GSD workflow guidance (runtime-derived via the shared `getProjectInstructionFile` policy — `AGENTS.md` for codex/opencode/kilo/kimi, `.github/copilot-instructions.md` for copilot, `GEMINI.md` for gemini/antigravity, `.claude/CLAUDE.md` for claude; an existing hand-crafted file without GSD markers is left untouched unless `--force`)
1559
1625
  - [ ] User knows next step is `/gsd:discuss-phase 1`
1560
1626
 
1561
1627
  **Atomic commits:** Each phase commits its artifacts immediately. If context is lost, artifacts persist.
@@ -693,6 +693,21 @@ Also available:
693
693
 
694
694
  **Exit the plan-phase workflow. Do not continue.**
695
695
 
696
+ ## 5.65. Codebase Map Freshness Pre-Check (drift plan:pre gate)
697
+
698
+ If `activeHooks` (from `PLAN_PRE_HOOKS_JSON`, §5.6) has a `kind == "gate"`, `capId == "drift"`,
699
+ `check.query == "verify.codebase-drift"` entry (`workflow.plan_drift_precheck` on), run the same check the
700
+ execute gate uses; otherwise skip to step 6:
701
+
702
+ ```bash
703
+ DRIFT=$(gsd_run verify codebase-drift 2>/dev/null || echo '{"skipped":true}')
704
+ ```
705
+
706
+ This gate is **non-blocking** and **never blocks, never spawns** the mapper at plan time. If `skipped` or
707
+ `action_required` is false, continue silently to step 6. If `action_required` is true, print `message`
708
+ verbatim (it ends with a `/gsd:map-codebase` pointer) and continue — planning proceeds whether or not the
709
+ map is refreshed first. (`drift_action: auto-remap` stays at `execute:wave:post`.)
710
+
696
711
  ## 6. Check Existing Plans
697
712
 
698
713
  ```bash
@@ -218,7 +218,9 @@ Collect all answers into an answers JSON object mapping dimension keys to select
218
218
 
219
219
  **Save answers to temp file:**
220
220
  ```bash
221
- ANSWERS_PATH=$(mktemp /tmp/gsd-profile-answers-XXXXXX.json)
221
+ # BSD/macOS mktemp only randomizes XXXXXX when it is the final path component, so make a
222
+ # suffixless temp then append the extension — portable across BSD + GNU (#1520).
223
+ ANSWERS_PATH=$(mktemp "${TMPDIR:-/tmp}/gsd-profile-answers-XXXXXX") && mv "$ANSWERS_PATH" "${ANSWERS_PATH}.json" && ANSWERS_PATH="${ANSWERS_PATH}.json" || exit 1
222
224
  ```
223
225
 
224
226
  Write the answers JSON to `$ANSWERS_PATH`.
@@ -232,7 +234,9 @@ Parse the analysis JSON from the result.
232
234
 
233
235
  Save analysis JSON to a temp file:
234
236
  ```bash
235
- ANALYSIS_PATH=$(mktemp /tmp/gsd-profile-analysis-XXXXXX.json)
237
+ # BSD/macOS mktemp only randomizes XXXXXX when it is the final path component, so make a
238
+ # suffixless temp then append the extension — portable across BSD + GNU (#1520).
239
+ ANALYSIS_PATH=$(mktemp "${TMPDIR:-/tmp}/gsd-profile-analysis-XXXXXX") && mv "$ANALYSIS_PATH" "${ANALYSIS_PATH}.json" && ANALYSIS_PATH="${ANALYSIS_PATH}.json" || exit 1
236
240
  ```
237
241
 
238
242
  Write the analysis JSON to `$ANALYSIS_PATH`.