@opengsd/gsd-core 1.5.0-rc.2 → 1.5.0-rc.4

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 (131) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/agents/gsd-advisor-researcher.md +1 -1
  3. package/agents/gsd-assumptions-analyzer.md +1 -1
  4. package/agents/gsd-code-fixer.md +1 -1
  5. package/agents/gsd-code-reviewer.md +1 -1
  6. package/agents/gsd-codebase-mapper.md +1 -1
  7. package/agents/gsd-debugger.md +1 -1
  8. package/agents/gsd-doc-writer.md +1 -1
  9. package/agents/gsd-eval-auditor.md +1 -1
  10. package/agents/gsd-executor.md +1 -1
  11. package/agents/gsd-integration-checker.md +1 -1
  12. package/agents/gsd-mempalace-curator.md +47 -0
  13. package/agents/gsd-nyquist-auditor.md +1 -0
  14. package/agents/gsd-phase-researcher.md +1 -1
  15. package/agents/gsd-plan-checker.md +1 -1
  16. package/agents/gsd-planner.md +1 -1
  17. package/agents/gsd-project-researcher.md +1 -1
  18. package/agents/gsd-research-synthesizer.md +1 -1
  19. package/agents/gsd-roadmapper.md +55 -2
  20. package/agents/gsd-security-auditor.md +1 -0
  21. package/agents/gsd-ui-auditor.md +1 -1
  22. package/agents/gsd-ui-checker.md +1 -1
  23. package/agents/gsd-ui-researcher.md +1 -1
  24. package/agents/gsd-verifier.md +13 -2
  25. package/bin/install.js +61 -64
  26. package/commands/gsd/mempalace-capture.md +71 -0
  27. package/commands/gsd/mempalace-recall.md +102 -0
  28. package/commands/gsd/ns-context.md +4 -2
  29. package/commands/gsd/progress.md +2 -1
  30. package/gemini-extension.json +1 -1
  31. package/gsd-core/bin/gsd-tools.cjs +277 -95
  32. package/gsd-core/bin/lib/active-workstream-store.cjs +6 -0
  33. package/gsd-core/bin/lib/capability-activation.cjs +86 -0
  34. package/gsd-core/bin/lib/capability-registry.cjs +1468 -11
  35. package/gsd-core/bin/lib/capability-state.cjs +128 -21
  36. package/gsd-core/bin/lib/capability-writer.cjs +354 -0
  37. package/gsd-core/bin/lib/check-command-router.cjs +328 -1
  38. package/gsd-core/bin/lib/clusters.cjs +2 -0
  39. package/gsd-core/bin/lib/command-roster.cjs +19 -0
  40. package/gsd-core/bin/lib/commands.cjs +33 -10
  41. package/gsd-core/bin/lib/config-loader.cjs +7 -8
  42. package/gsd-core/bin/lib/config-schema.cjs +32 -3
  43. package/gsd-core/bin/lib/config.cjs +81 -26
  44. package/gsd-core/bin/lib/core.cjs +5 -2
  45. package/gsd-core/bin/lib/edge-probe.cjs +25 -2
  46. package/gsd-core/bin/lib/frontmatter.cjs +53 -1
  47. package/gsd-core/bin/lib/git-base-branch.cjs +194 -0
  48. package/gsd-core/bin/lib/init.cjs +36 -11
  49. package/gsd-core/bin/lib/install-profiles.cjs +57 -1
  50. package/gsd-core/bin/lib/installer-migration-report.cjs +1 -0
  51. package/gsd-core/bin/lib/loop-resolver.cjs +157 -16
  52. package/gsd-core/bin/lib/model-resolver.cjs +47 -5
  53. package/gsd-core/bin/lib/phase.cjs +99 -23
  54. package/gsd-core/bin/lib/plan-drift-guard.cjs +117 -0
  55. package/gsd-core/bin/lib/probe-core.cjs +117 -1
  56. package/gsd-core/bin/lib/profile-output.cjs +45 -4
  57. package/gsd-core/bin/lib/profile-pipeline-command-router.cjs +138 -0
  58. package/gsd-core/bin/lib/roadmap-parser.cjs +13 -3
  59. package/gsd-core/bin/lib/roadmap.cjs +97 -7
  60. package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +1946 -0
  61. package/gsd-core/bin/lib/runtime-artifact-layout.cjs +54 -30
  62. package/gsd-core/bin/lib/runtime-config-adapter-registry.cjs +27 -19
  63. package/gsd-core/bin/lib/runtime-homes.cjs +26 -20
  64. package/gsd-core/bin/lib/state-command-router.cjs +15 -3
  65. package/gsd-core/bin/lib/state-document.cjs +46 -1
  66. package/gsd-core/bin/lib/state.cjs +461 -94
  67. package/gsd-core/bin/lib/verify.cjs +92 -8
  68. package/gsd-core/bin/lib/worktree-safety.cjs +2 -1
  69. package/gsd-core/bin/shared/config-defaults.manifest.json +1 -2
  70. package/gsd-core/bin/shared/config-schema.manifest.json +0 -18
  71. package/gsd-core/bin/shared/model-catalog.json +1 -0
  72. package/gsd-core/references/edge-probe.md +11 -0
  73. package/gsd-core/references/loop-hook-dispatch.md +61 -0
  74. package/gsd-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json +14 -0
  75. package/gsd-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json +4 -0
  76. package/gsd-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json +32 -0
  77. package/gsd-core/references/prohibition-probe.md +248 -0
  78. package/gsd-core/templates/config.json +1 -1
  79. package/gsd-core/templates/spec.md +14 -0
  80. package/gsd-core/workflows/audit-milestone.md +5 -3
  81. package/gsd-core/workflows/autonomous.md +10 -5
  82. package/gsd-core/workflows/code-review-fix.md +9 -7
  83. package/gsd-core/workflows/code-review.md +8 -6
  84. package/gsd-core/workflows/complete-milestone.md +1 -5
  85. package/gsd-core/workflows/discuss-phase.md +14 -0
  86. package/gsd-core/workflows/execute-phase.md +86 -146
  87. package/gsd-core/workflows/execute-plan.md +21 -6
  88. package/gsd-core/workflows/help/modes/full.md +7 -1
  89. package/gsd-core/workflows/new-project.md +3 -3
  90. package/gsd-core/workflows/next.md +50 -2
  91. package/gsd-core/workflows/pause-work.md +7 -1
  92. package/gsd-core/workflows/plan-phase.md +91 -221
  93. package/gsd-core/workflows/plan-review-convergence.md +14 -4
  94. package/gsd-core/workflows/pr-branch.md +4 -2
  95. package/gsd-core/workflows/profile-user.md +3 -1
  96. package/gsd-core/workflows/progress.md +58 -1
  97. package/gsd-core/workflows/quick.md +12 -8
  98. package/gsd-core/workflows/resume-project.md +17 -1
  99. package/gsd-core/workflows/review.md +19 -2
  100. package/gsd-core/workflows/secure-phase.md +4 -2
  101. package/gsd-core/workflows/settings-advanced.md +2 -0
  102. package/gsd-core/workflows/settings.md +27 -1
  103. package/gsd-core/workflows/ship.md +58 -5
  104. package/gsd-core/workflows/spec-phase.md +75 -0
  105. package/gsd-core/workflows/validate-phase.md +4 -2
  106. package/gsd-core/workflows/verify-phase.md +14 -4
  107. package/gsd-core/workflows/verify-work.md +27 -11
  108. package/hooks/dist/gsd-ensure-canonical-path.js +305 -0
  109. package/hooks/dist/gsd-statusline.js +1 -1
  110. package/hooks/dist/managed-hooks-registry.cjs +1 -0
  111. package/hooks/gsd-ensure-canonical-path.js +305 -0
  112. package/hooks/gsd-statusline.js +1 -1
  113. package/hooks/hooks.json +1 -0
  114. package/hooks/managed-hooks-registry.cjs +1 -0
  115. package/package.json +5 -4
  116. package/scripts/affected-tests-lib.cjs +16 -4
  117. package/scripts/build-hooks.js +7 -0
  118. package/scripts/changeset/new.cjs +17 -3
  119. package/scripts/fix-slash-commands.cjs +15 -3
  120. package/scripts/gen-capability-registry.cjs +373 -49
  121. package/scripts/gen-inventory-manifest.cjs +1 -4
  122. package/scripts/gen-loop-host-contract.cjs +55 -0
  123. package/scripts/issue-version-gate.cjs +140 -0
  124. package/scripts/lint-allow-test-rule-refs.allowlist.json +327 -0
  125. package/scripts/lint-allow-test-rule-refs.cjs +162 -0
  126. package/scripts/lint-test-file-count.allowlist.json +14 -0
  127. package/scripts/mutation-matrix.cjs +108 -7
  128. package/scripts/pr-target-policy.cjs +63 -0
  129. package/scripts/release-tarball-smoke.cjs +7 -1
  130. package/scripts/research-profiles.cjs +5 -5
  131. package/scripts/run-tests.cjs +178 -17
@@ -74,11 +74,10 @@ AGENT_SKILLS_RESEARCHER=$(gsd_run query agent-skills gsd-phase-researcher)
74
74
  AGENT_SKILLS_PLANNER=$(gsd_run query agent-skills gsd-planner)
75
75
  AGENT_SKILLS_CHECKER=$(gsd_run query agent-skills gsd-plan-checker)
76
76
  CONTEXT_WINDOW=$(gsd_run query config-get context_window 2>/dev/null || echo "200000")
77
- TDD_MODE=$(gsd_run query config-get workflow.tdd_mode 2>/dev/null || echo "false")
78
77
  MVP_MODE_CFG=$(gsd_run query config-get workflow.mvp_mode 2>/dev/null || echo "false")
79
78
  ```
80
79
 
81
- When `TDD_MODE` is `true`, the planner agent is instructed to apply `type: tdd` to eligible tasks using heuristics from `references/tdd.md`. The planner's `<required_reading>` is extended to include `@~/.claude/gsd-core/references/tdd.md` so gate enforcement rules are available during planning.
80
+ When the tdd capability's `workflow.tdd_mode` is active (resolved via the plan:pre render-hooks), the planner agent is instructed to apply `type: tdd` to eligible tasks using heuristics from `references/tdd.md`. The TDD guidance is injected via the tdd capability's contribution hook at §5.6; no inline config-get is needed.
82
81
 
83
82
  When `CONTEXT_WINDOW >= 500000`, the planner prompt includes the 3 most recent prior phase CONTEXT.md and SUMMARY.md files PLUS any phases explicitly listed in the current phase's `Depends on:` field in ROADMAP.md. Explicit dependencies always load regardless of recency (e.g., Phase 7 declaring `Depends on: Phase 2` always sees Phase 2's context). Bounded recency keeps the planner's context budget focused on recent work.
84
83
 
@@ -165,7 +164,9 @@ Set `TEXT_MODE=true` if `--text` is present in $ARGUMENTS OR `text_mode` from in
165
164
  ```bash
166
165
  MVP_FLAG_ARG=""
167
166
  if [[ "$ARGUMENTS" =~ (^|[[:space:]])--mvp([[:space:]]|$) ]]; then MVP_FLAG_ARG="--cli-flag"; fi
168
- if [[ "$ARGUMENTS" =~ (^|[[:space:]])--tdd([[:space:]]|$) ]]; then TDD_MODE=true; fi
167
+ if [[ "$ARGUMENTS" =~ (^|[[:space:]])--tdd([[:space:]]|$) ]]; then
168
+ gsd_run query config-set workflow.tdd_mode true 2>/dev/null || true
169
+ fi
169
170
  ```
170
171
 
171
172
  Defer the `phase.mvp-mode` query until `PHASE` is finalized (after explicit argument parsing/fallback phase detection + validation). The verb returns `true|false`; full result also exposes `source` (`cli_flag` | `roadmap` | `config` | `none`) for diagnostics. Mode is **all-or-nothing per phase** (PRD decision Q1).
@@ -411,45 +412,20 @@ If "Run discuss-phase first":
411
412
  ```
412
413
  **Exit the plan-phase workflow. Do not continue.**
413
414
 
414
- ## 4.5. Check AI-SPEC
415
+ ## 4.5. Resolve AI-SPEC Artifact
415
416
 
416
- **Skip if:** `ai_integration_phase_enabled` from config is false, or `--skip-ai-spec` flag provided.
417
+ AI integration activation is owned by the `ai-integration` capability's `plan:pre` step hook. The plan-phase host only discovers existing artifacts here so the planner can consume them; it must not read the capability's config key directly.
417
418
 
418
419
  ```bash
419
420
  AI_SPEC_FILE=$(ls "${PHASE_DIR}"/*-AI-SPEC.md 2>/dev/null | head -1)
420
- AI_PHASE_CFG=$(gsd_run query config-get workflow.ai_integration_phase 2>/dev/null || echo "true")
421
- ```
422
-
423
- **Skip if `AI_PHASE_CFG` is `false`.**
424
-
425
- **If `AI_SPEC_FILE` is empty:** Check phase goal for AI keywords:
426
- ```bash
427
- echo "${phase_goal}" | grep -qi "agent\|llm\|rag\|chatbot\|embedding\|langchain\|llamaindex\|crewai\|langgraph\|openai\|anthropic\|vector\|eval\|ai system"
428
- ```
429
-
430
- **If AI keywords detected AND no AI-SPEC.md:**
431
- ```
432
- ◆ Note: This phase appears to involve AI system development.
433
- Consider running /gsd:ai-integration-phase {N} before planning to:
434
- - Select the right framework for your use case
435
- - Research its docs and best practices
436
- - Design an evaluation strategy
437
-
438
- Continue planning without AI-SPEC? (non-blocking — /gsd:ai-integration-phase can be run after)
421
+ AI_SPEC_PATH="${AI_SPEC_FILE}"
422
+ FRAMEWORK_LINE=""
423
+ if [ -n "$AI_SPEC_FILE" ]; then
424
+ FRAMEWORK_LINE=$(grep "Selected Framework:" "${AI_SPEC_FILE}" | head -1)
425
+ fi
439
426
  ```
440
427
 
441
- Use AskUserQuestion with options:
442
- - "Continue — plan without AI-SPEC"
443
- - "Stop — I'll run /gsd:ai-integration-phase {N} first"
444
-
445
- If "Stop": Exit with `/gsd:ai-integration-phase {N}` reminder.
446
- If "Continue": Proceed. (Non-blocking — planner will note AI-SPEC is absent.)
447
-
448
- **If `AI_SPEC_FILE` is non-empty:** Extract framework for planner context:
449
- ```bash
450
- FRAMEWORK_LINE=$(grep "Selected Framework:" "${AI_SPEC_FILE}" | head -1)
451
- ```
452
- Pass `ai_spec_path` and `framework_line` to planner in step 7 so it can reference the AI design contract.
428
+ If `AI_SPEC_FILE` is non-empty, pass `AI_SPEC_PATH` and `FRAMEWORK_LINE` to the planner in step 8 so it can reference the AI design contract. If it is empty, the active `ai-integration` capability hook in step 5.6 handles any AI-system nudge or `/gsd:ai-integration-phase` dispatch.
453
429
 
454
430
  ## 5. Handle Research
455
431
 
@@ -525,41 +501,21 @@ Display banner:
525
501
 
526
502
  ```bash
527
503
  PHASE_DESC=$(gsd_run query roadmap.get-phase "${PHASE}" --pick section)
504
+ if [ -z "${PLAN_PRE_HOOKS_JSON:-}" ]; then
505
+ PLAN_PRE_HOOKS_JSON=$(gsd_run loop render-hooks plan:pre --raw)
506
+ fi
528
507
  ```
529
508
 
530
- Research prompt:
509
+ Find the active `research` step hook in `PLAN_PRE_HOOKS_JSON`. Use the hook's `fragment.inline` as the prompt template and substitute the phase fields below before spawning its declared `ref.agent`.
531
510
 
532
511
  ```markdown
533
- <objective>
534
- Research how to implement Phase {phase_number}: {phase_name}
535
- Answer: "What do I need to know to PLAN this phase well?"
536
- </objective>
537
-
538
- <files_to_read>
539
- - {context_path} (USER DECISIONS from /gsd:discuss-phase)
540
- - {requirements_path} (Project requirements)
541
- - {state_path} (Project decisions and history)
542
- </files_to_read>
543
-
544
- ${AGENT_SKILLS_RESEARCHER}
545
-
546
- <additional_context>
547
- **Phase description:** {phase_description}
548
- **Phase requirement IDs (MUST address):** {phase_req_ids}
549
-
550
- **Project instructions:** Read ./CLAUDE.md if exists — follow project-specific guidelines
551
- **Project skills:** Check .claude/skills/ or .agents/skills/ directory (if either exists) — read SKILL.md files, research should account for project skill patterns
552
- </additional_context>
553
-
554
- <output>
555
- Write to: {phase_dir}/{phase_num}-RESEARCH.md
556
- </output>
512
+ {research_hook.fragment.inline}
557
513
  ```
558
514
 
559
515
  ```
560
516
  Agent(
561
- prompt=research_prompt,
562
- subagent_type="gsd-phase-researcher",
517
+ prompt=filled_research_hook_fragment,
518
+ subagent_type=research_hook.ref.agent,
563
519
  model="{researcher_model}",
564
520
  description="Research Phase {phase}"
565
521
  )
@@ -622,17 +578,19 @@ test -f "${PHASE_DIR}/${PADDED_PHASE}-VALIDATION.md" && echo "VALIDATION_CREATED
622
578
 
623
579
  ## 5.55. Security Threat Model Gate
624
580
 
625
- > Skip if `workflow.security_enforcement` is explicitly `false`. Absent = enabled.
581
+ > Capability-driven dispatch. Resolves active `plan:pre` hooks via the capability registry; the security hook's `when` condition is evaluated by the registry.
626
582
 
627
583
  ```bash
628
- SECURITY_CFG=$(gsd_run query config-get workflow.security_enforcement --raw 2>/dev/null || echo "true")
629
- SECURITY_ASVS=$(gsd_run query config-get workflow.security_asvs_level --raw 2>/dev/null || echo "1")
630
- SECURITY_BLOCK=$(gsd_run query config-get workflow.security_block_on --raw 2>/dev/null || echo "high")
584
+ PLAN_PRE_HOOKS_JSON=$(gsd_run loop render-hooks plan:pre --raw)
631
585
  ```
632
586
 
633
- **If `SECURITY_CFG` is `false`:** Skip to step 5.6.
587
+ Resolve active contribution hooks from `PLAN_PRE_HOOKS_JSON` where `kind == "contribution"` and `capId == "security"`.
634
588
 
635
- **If `SECURITY_CFG` is `true`:** Display banner:
589
+ **If no active security contribution hook exists:** Skip to step 5.6.
590
+
591
+ **If an active security contribution hook exists:** Read `SECURITY_ASVS` from the active hook's `configValues.security_asvs_level` (default: `1`) and `SECURITY_BLOCK` from `configValues.security_block_on` (default: `"high"`). These values are resolved by the capability registry from user config using the same four-level precedence as hook activation — no inline `config-get` is needed.
592
+
593
+ Display banner:
636
594
 
637
595
  ```
638
596
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
@@ -646,21 +604,31 @@ Opt out: set security_enforcement: false in .planning/config.json
646
604
 
647
605
  Continue to step 5.6. Security config is passed to the planner in step 8.
648
606
 
649
- ## 5.6. UI Design Contract Gate
607
+ ## 5.6. Plan:Pre Capability Dispatch and UI Design Contract Gate
650
608
 
651
- > Capability-driven dispatch. Resolves active `plan:pre` hooks via the capability registry; each hook's `when` condition (`workflow.ui_phase` for step hooks, `workflow.ui_safety_gate` for gate hooks) is evaluated by the registry — no inline config-get needed.
609
+ > Capability-driven dispatch. Resolves active `plan:pre` hooks via the capability registry; each hook's `when` condition is evaluated by the registry — no inline config-get needed. This section handles skill-based planning preflights such as `ai-integration`, agent-backed hooks through `ref.agent`, and the UI gate whose deterministic check comes from `check.query`.
652
610
  >
653
611
  > **Config semantics (cutover fix):** `workflow.ui_phase` gates UI-SPEC *generation* (step); `workflow.ui_safety_gate` gates the *planning block* (gate). Both-on = identical to OLD §5.6. Intended change: `{ui_phase:true, ui_safety_gate:false}` now auto-generates in pipelines but does NOT block manual planning (each key controls exactly what its description says).
654
612
 
655
613
  ```bash
656
- HOOKS_JSON=$(gsd_run loop render-hooks plan:pre --raw)
614
+ PLAN_PRE_HOOKS_JSON=${PLAN_PRE_HOOKS_JSON:-$(gsd_run loop render-hooks plan:pre --raw)}
615
+ HOOKS_JSON="$PLAN_PRE_HOOKS_JSON"
657
616
  ```
658
617
 
659
- Read the `activeHooks` array directly from `HOOKS_JSON` (in-context — do NOT invoke a shell pipeline).
618
+ Read the `activeHooks` array directly from `PLAN_PRE_HOOKS_JSON` / `HOOKS_JSON` (in-context — do NOT invoke a shell pipeline).
619
+
620
+ **Branch 1 — all plan:pre hooks inactive (`activeHooks` is empty or absent):** Skip to step 6.
660
621
 
661
- **Branch 1 — both toggles off (`activeHooks` is empty or absent):** Skip to step 6.
622
+ **Generic step hook dispatch contract:** For each active entry where `kind == "step"`:
623
+ - If `ref.skill` is set, dispatch with `Skill(skill="gsd-${ref.skill}", args="${PHASE} --auto ${GSD_WS}")` when pipeline mode allows auto-chaining. Prepend `gsd-` to `ref.skill` — `ui-phase` → `gsd-ui-phase`.
624
+ - If `ref.agent` is set, dispatch with `Agent(prompt=filled_hook_fragment, subagent_type=ref.agent, model="{researcher_model}")`. Use the hook's `fragment.inline` as the prompt body and fill phase fields before spawning.
625
+ - The `research` hook is handled by §5.1's research decision. The `pattern-mapper` hook is handled by §7.8 after `RESEARCH_PATH` is known. Future plan:pre agent hooks use the same `ref.agent` fragment contract.
662
626
 
663
- Run whenever **any** `plan:pre` UI hook is active — including the step-only case (`workflow.ui_safety_gate` off). (`check.query` = `"ui.plan-gate"`; router normalizes dots→hyphens.)
627
+ **AI integration capability:** If the active `ai-integration` step hook is present, `AI_SPEC_PATH` is empty, and the phase goal contains AI keywords (`agent`, `llm`, `rag`, `chatbot`, `embedding`, `langchain`, `llamaindex`, `crewai`, `langgraph`, `openai`, `anthropic`, `vector`, `eval`, `ai system`), then:
628
+ - In pipeline / `--auto` mode, invoke the hook's `ref.skill` via `Skill(skill="gsd-${ref.skill}", args="${PHASE} --auto ${GSD_WS}")`.
629
+ - In manual mode, display the existing non-blocking `/gsd:ai-integration-phase {N}` recommendation and let the user continue planning without AI-SPEC or stop to run the capability workflow first.
630
+
631
+ Run the UI deterministic gate whenever **any** `plan:pre` UI hook is active — including the step-only case (`workflow.ui_safety_gate` off). (`check.query` = `"ui.plan-gate"`; router normalizes dots→hyphens.)
664
632
 
665
633
  ```bash
666
634
  GATE=$(gsd_run check ui-plan-gate "${PHASE}" --raw)
@@ -668,7 +636,7 @@ GATE=$(gsd_run check ui-plan-gate "${PHASE}" --raw)
668
636
 
669
637
  Read `frontend`, `hasUiSpec`, and `block` from `GATE`.
670
638
 
671
- **Branch 2 — no frontend indicators (`frontend` is `false`):** Skip silently to step 5.7.
639
+ **Branch 2 — no frontend indicators (`frontend` is `false`):** Skip silently to step 6.
672
640
 
673
641
  **Branch 3 — UI-SPEC already exists (`hasUiSpec` is `true`):**
674
642
 
@@ -689,13 +657,13 @@ Read the ephemeral auto-chain flag:
689
657
  AUTO_CHAIN=$(gsd_run query check auto-mode --pick auto_chain_active 2>/dev/null || echo "false")
690
658
  ```
691
659
 
692
- **Branch 5 — `AUTO_CHAIN` is `true` (pipeline / `--auto`):** Fire each active **step** hook — runs independently of whether a gate is active (covers `{ui_phase:true, ui_safety_gate:false}`). For each entry in `activeHooks` (in array order) where `kind == "step"` and `ref.skill` is set:
660
+ **Branch 5 — `AUTO_CHAIN` is `true` (pipeline / `--auto`):** Fire each active UI **step** hook — runs independently of whether a gate is active (covers `{ui_phase:true,ui_safety_gate:false}`). For each entry in `activeHooks` (in array order) where `kind == "step"` and `ref.skill` is set:
693
661
 
694
662
  ```
695
663
  Skill(skill="gsd-${ref.skill}", args="${PHASE} --auto ${GSD_WS}")
696
664
  ```
697
665
 
698
- (prepend `gsd-` to `ref.skill` — `ui-phase` → `gsd-ui-phase`.) After all step hooks return, re-read:
666
+ After all UI step hooks return, re-read:
699
667
 
700
668
  ```bash
701
669
  UI_SPEC_FILE=$(ls "${PHASE_DIR}"/*-UI-SPEC.md 2>/dev/null | head -1)
@@ -719,68 +687,6 @@ Also available:
719
687
 
720
688
  **Exit the plan-phase workflow. Do not continue.**
721
689
 
722
- ## 5.7. Schema Push Detection Gate
723
-
724
- > Detects schema-relevant files in the phase scope and injects a mandatory `[BLOCKING]` schema push task into the plan. Prevents false-positive verification where build/types pass because TypeScript types come from config, not the live database.
725
-
726
- Check if any files in the phase scope match schema patterns:
727
-
728
- ```bash
729
- PHASE_SECTION=$(gsd_run query roadmap.get-phase "${PHASE}" --pick section 2>/dev/null)
730
- ```
731
-
732
- Scan `PHASE_SECTION`, `CONTEXT.md` (if loaded), and `RESEARCH.md` (if exists) for file paths matching these ORM patterns:
733
-
734
- | ORM | File Patterns |
735
- |-----|--------------|
736
- | Payload CMS | `src/collections/**/*.ts`, `src/globals/**/*.ts` |
737
- | Prisma | `prisma/schema.prisma`, `prisma/schema/*.prisma` |
738
- | Drizzle | `drizzle/schema.ts`, `src/db/schema.ts`, `drizzle/*.ts` |
739
- | Supabase | `supabase/migrations/*.sql` |
740
- | TypeORM | `src/entities/**/*.ts`, `src/migrations/**/*.ts` |
741
-
742
- Also check if any existing PLAN.md files for this phase already reference these file patterns in `files_modified`.
743
-
744
- **If schema-relevant files detected:**
745
-
746
- Set `SCHEMA_PUSH_REQUIRED=true` and `SCHEMA_ORM={detected_orm}`.
747
-
748
- Determine the push command for the detected ORM:
749
-
750
- | ORM | Push Command | Non-TTY Workaround |
751
- |-----|-------------|-------------------|
752
- | Payload CMS | `npx payload migrate` | `CI=true PAYLOAD_MIGRATING=true npx payload migrate` |
753
- | Prisma | `npx prisma db push` | `npx prisma db push --accept-data-loss` (if destructive) |
754
- | Drizzle | `npx drizzle-kit push` | `npx drizzle-kit push` |
755
- | Supabase | `supabase db push` | Set `SUPABASE_ACCESS_TOKEN` env var |
756
- | TypeORM | `npx typeorm migration:run` | `npx typeorm migration:run -d src/data-source.ts` |
757
-
758
- Inject the following into the planner prompt (step 8) as an additional constraint:
759
-
760
- ```markdown
761
- <schema_push_requirement>
762
- **[BLOCKING] Schema Push Required**
763
-
764
- This phase modifies schema-relevant files ({detected_files}). The planner MUST include
765
- a `[BLOCKING]` task that runs the database schema push command AFTER all schema file
766
- modifications are complete but BEFORE verification.
767
-
768
- - ORM detected: {SCHEMA_ORM}
769
- - Push command: {push_command}
770
- - Non-TTY workaround: {env_hint}
771
- - If push requires interactive prompts that cannot be suppressed, flag the task for
772
- manual intervention with `autonomous: false`
773
-
774
- This task is mandatory — the phase CANNOT pass verification without it. Build and
775
- type checks will pass without the push (types come from config, not the live database),
776
- creating a false-positive verification state.
777
- </schema_push_requirement>
778
- ```
779
-
780
- Display: `Schema files detected ({SCHEMA_ORM}) — [BLOCKING] push task will be injected into plans`
781
-
782
- **If no schema-relevant files detected:** Skip silently to step 6.
783
-
784
690
  ## 6. Check Existing Plans
785
691
 
786
692
  ```bash
@@ -845,14 +751,7 @@ Proceed to Step 7.8 (or Step 8 if pattern mapper is disabled) only if user selec
845
751
 
846
752
  ## 7.8. Spawn gsd-pattern-mapper Agent (Optional)
847
753
 
848
- **Skip if** `workflow.pattern_mapper` is explicitly set to `false` in config.json (absent key = enabled). Also skip if no CONTEXT.md and no RESEARCH.md exist for this phase (nothing to extract file lists from).
849
-
850
- Check config:
851
- ```bash
852
- PATTERN_MAPPER_CFG=$(gsd_run query config-get workflow.pattern_mapper 2>/dev/null || echo "true")
853
- ```
854
-
855
- **If `PATTERN_MAPPER_CFG` is `false`:** Skip to step 8.
754
+ Pattern mapper activation is owned by the `pattern-mapper` capability's `plan:pre` step hook. Read `PLAN_PRE_HOOKS_JSON` and skip if no active step hook has `capId == "pattern-mapper"` and `ref.agent == "gsd-pattern-mapper"`. Also skip if no CONTEXT.md and no RESEARCH.md exist for this phase (nothing to extract file lists from).
856
755
 
857
756
  **If PATTERNS.md already exists** (`PATTERNS_PATH` is non-empty from step 7): Skip to step 8 (use existing).
858
757
 
@@ -865,30 +764,17 @@ Display banner:
865
764
  ◆ Spawning pattern mapper... (runs in a subagent — no output until it returns, ~1–5 min; expected, not a freeze)
866
765
  ```
867
766
 
868
- Pattern mapper prompt:
767
+ Use the active `pattern-mapper` hook's `fragment.inline` as the prompt template and substitute the phase fields below before spawning its declared `ref.agent`.
869
768
 
870
769
  ```markdown
871
- <pattern_mapping_context>
872
- **Phase:** {phase_number} - {phase_name}
873
- **Phase directory:** {phase_dir}
874
- **Padded phase:** {padded_phase}
875
-
876
- <files_to_read>
877
- - {context_path} (USER DECISIONS from /gsd:discuss-phase)
878
- - {research_path} (Technical Research)
879
- </files_to_read>
880
-
881
- **Output file:** {phase_dir}/{padded_phase}-PATTERNS.md
882
-
883
- Extract the list of files to be created/modified from CONTEXT.md and RESEARCH.md. For each file, classify by role and data flow, find the closest existing analog in the codebase, extract concrete code excerpts, and produce PATTERNS.md.
884
- </pattern_mapping_context>
770
+ {pattern_mapper_hook.fragment.inline}
885
771
  ```
886
772
 
887
773
  Spawn with:
888
774
  ```
889
775
  Agent(
890
- prompt="{above}",
891
- subagent_type="gsd-pattern-mapper",
776
+ prompt=filled_pattern_mapper_hook_fragment,
777
+ subagent_type=pattern_mapper_hook.ref.agent,
892
778
  model="{researcher_model}",
893
779
  )
894
780
  ```
@@ -906,16 +792,21 @@ PATTERNS_PATH="${PHASE_DIR}/${PADDED_PHASE}-PATTERNS.md"
906
792
 
907
793
  ## 7.9. Regenerate API-SURFACE.md (intel gate)
908
794
 
795
+ > Capability-driven dispatch. Resolves active `plan:pre` step hooks via the capability registry; the intel hook's `when: intel.enabled` condition is evaluated by the registry — no inline config-get needed.
796
+
797
+ Read the active intel step hook from `PLAN_PRE_HOOKS_JSON` where `kind == "step"` and `capId == "intel"`.
798
+
799
+ **If no active intel step hook exists:** `API_SURFACE_PATH` stays empty; skip to step 8. The step-8 planner entry for API Surface is omitted when `API_SURFACE_PATH` is empty.
800
+
801
+ **If an active intel step hook exists:**
909
802
  ```bash
910
- INTEL_CFG=$(gsd_run query config-get intel.enabled 2>/dev/null || echo "false")
911
- # false (absent = false) → API_SURFACE_PATH stays empty; step-8 planner entry omitted
912
- if [ "$INTEL_CFG" = "true" ]; then
913
- gsd_run intel api-surface
914
- API_SURFACE_PATH=".planning/intel/API-SURFACE.md"
915
- echo "✓ API surface regenerated: ${API_SURFACE_PATH}" # injected into step 8 as HINT
916
- fi
803
+ gsd_run intel api-surface
804
+ API_SURFACE_PATH=".planning/intel/API-SURFACE.md"
805
+ echo "✓ API surface regenerated: ${API_SURFACE_PATH}" # injected into step 8 as HINT
917
806
  ```
918
807
 
808
+ Continue to step 8.
809
+
919
810
  ## 8. Spawn gsd-planner Agent
920
811
 
921
812
  Display banner:
@@ -944,11 +835,12 @@ Planner prompt:
944
835
  - {verification_path} (Verification Gaps - if --gaps)
945
836
  - {uat_path} (UAT Gaps - if --gaps)
946
837
  - {reviews_path} (Cross-AI Review Feedback - if --reviews; actionable findings must be incorporated or explicitly deferred/rejected in PLAN.md)
838
+ - {AI_SPEC_PATH} (AI Design Contract — framework and evaluation strategy, if exists)
947
839
  - {UI_SPEC_PATH} (UI Design Contract — visual/interaction specs, if exists)
948
840
  - {SPEC_PATH} (Phase SPEC — carries the ## Edge Coverage section to lift covered/backstop edges from, if exists)
949
841
  - {SPIKE_FINDINGS_PATH} (Spike Findings — validated patterns, constraints, landmines from experiments, if exists)
950
842
  - {SKETCH_FINDINGS_PATH} (Sketch Findings — validated design decisions, CSS patterns, visual direction, if exists)
951
- - {API_SURFACE_PATH} (API Surface — HINT ONLY, if intel.enabled; see <intel_surface_hint> below)
843
+ - {API_SURFACE_PATH} (API Surface — HINT ONLY, when intel capability is active; see <intel_surface_hint> below)
952
844
  ${CONTEXT_WINDOW >= 500000 ? `
953
845
  **Cross-phase context (1M model enrichment):**
954
846
  - CONTEXT.md files from the 3 most recent completed phases (locked decisions — maintain consistency)
@@ -977,19 +869,10 @@ Historical findings already incorporated, explicitly deferred/rejected in PLAN.m
977
869
 
978
870
  **Phase requirement IDs (every ID MUST appear in a plan's `requirements` field):** {phase_req_ids}
979
871
 
980
- **Project instructions:** Read ./CLAUDE.md if exists — follow project-specific guidelines
872
+ **Project instructions:** Read ./CLAUDE.md or ./.claude/CLAUDE.md if either exists — follow project-specific guidelines
981
873
  **Project skills:** Check .claude/skills/ or .agents/skills/ directory (if either exists) — read SKILL.md files, plans should account for project skill rules
982
874
 
983
- ${TDD_MODE === 'true' ? `
984
- <tdd_mode_active>
985
- **TDD Mode is ENABLED.** Apply TDD heuristics from @~/.claude/gsd-core/references/tdd.md to all eligible tasks:
986
- - Business logic with defined I/O → type: tdd
987
- - API endpoints with request/response contracts → type: tdd
988
- - Data transformations, validation, algorithms → type: tdd
989
- - UI, config, glue code, CRUD → standard plan (type: execute)
990
- Each TDD plan gets one feature with RED/GREEN/REFACTOR gate sequence.
991
- </tdd_mode_active>
992
- ` : ''}
875
+ {For each active entry in `PLAN_PRE_HOOKS_JSON` where `kind == "contribution"` and `into == "planner"` (in array order): inject the entry's `fragment.inline` verbatim here. This delivers all planner-targeted contributions — including tdd's `<tdd_mode_active>` block (type:tdd heuristics), schema-gate's schema-push detection guidance (if active at plan:pre), and security's threat-model guidance. For the security contribution, also surface the resolved `configValues`: `security_asvs_level` (ASVS enforcement level) and `security_block_on` (severity threshold) so the planner uses the configured values when generating `<threat_model>` blocks. If no active planner contributions exist, omit this block entirely.}
993
876
 
994
877
  **MVP_MODE:** ${MVP_MODE} (when true, follow vertical-slice rules from `~/.claude/gsd-core/references/planner-mvp-mode.md`; when false, ignore MVP guidance entirely.)
995
878
  **WALKING_SKELETON:** ${WALKING_SKELETON} (when true, the first deliverable must be a Walking Skeleton — Read the template at `~/.claude/gsd-core/references/skeleton-template.md` and produce SKELETON.md alongside PLAN.md.)
@@ -1009,6 +892,7 @@ Output consumed by /gsd:execute-phase. Plans need:
1009
892
  - Verification criteria
1010
893
  - must_haves for goal-backward verification
1011
894
  - If the SPEC has an `## Edge Coverage` section, lift every `covered` edge's acceptance criterion into `must_haves.truths`, and every `backstop` edge into `must_haves.truths` as a non-inferable check (note it needs a held-out/property-based test). `unresolved` edges are explicit assumptions — surface them in the plan, do not silently drop them.
895
+ - If the SPEC has a `## Prohibitions` section, lift every resolved prohibition into the `must_haves.prohibitions:` sibling block (NOT `truths` — ADR-550 D3) carrying `statement` + `status` + `verification`; unresolved prohibitions are explicit assumptions — surface them in the plan, do not silently drop them. A prohibition is a must-NOT (negative) check that belongs in its own `must_haves.prohibitions` block. Never place a must-NOT under `must_haves.truths` — that block keeps positive-observable semantics only.
1012
896
  - **"Artifacts this phase produces" section (MANDATORY)** — list every symbol this phase creates: decorators, classes, functions, CLI flags, struct/dataclass fields, new file paths. The plan-review-convergence source-grounding pass reads this section to exclude newly-created symbols from drift verification; omitting it causes new symbols to be flagged for acknowledgement.
1013
897
  </downstream_consumer>
1014
898
 
@@ -1055,6 +939,7 @@ Every task MUST include these fields — they are NOT optional:
1055
939
  - [ ] must_haves derived from phase goal
1056
940
  - [ ] Every PLAN.md includes an "Artifacts this phase produces" section listing symbols created by this phase (decorators, classes, functions, CLI flags, struct/dataclass fields, new file paths)
1057
941
  - [ ] Every SPEC ## Edge Coverage covered/backstop edge is represented in a plan's must_haves (no silent drops)
942
+ - [ ] Every SPEC ## Prohibitions resolved item is represented in a plan's must_haves.prohibitions (no silent drops)
1058
943
  </quality_gate>
1059
944
  ```
1060
945
 
@@ -1316,7 +1201,7 @@ If an actionable finding remains only in REVIEWS.md and would be invisible to /g
1316
1201
 
1317
1202
  **Phase requirement IDs (MUST ALL be covered):** {phase_req_ids}
1318
1203
 
1319
- **Project instructions:** Read ./CLAUDE.md if exists — verify plans honor project guidelines
1204
+ **Project instructions:** Read ./CLAUDE.md or ./.claude/CLAUDE.md if either exists — verify plans honor project guidelines
1320
1205
  **Project skills:** Check .claude/skills/ or .agents/skills/ directory (if either exists) — verify plans account for project skill rules
1321
1206
  </verification_context>
1322
1207
 
@@ -1682,53 +1567,38 @@ gsd_run query commit "docs(${PADDED_PHASE}): create phase plan" --files "${PHASE
1682
1567
 
1683
1568
  This commits all PLAN.md files for the phase plus the updated STATE.md and ROADMAP.md to version-control the planning artifacts. Skip this step if `commit_docs` is false.
1684
1569
 
1685
- ## 13e. Post-Planning Gap Analysis
1686
-
1687
- After all plans are generated, committed, and the Requirements Coverage Gate (§13)
1688
- has run, emit a single unified gap report covering both REQUIREMENTS.md and the
1689
- CONTEXT.md `<decisions>` section. This is a **proactive, post-hoc report** — it
1690
- does not block phase advancement and does not re-plan. It exists so that any
1691
- requirement or decision that slipped through the per-plan checks is surfaced in
1692
- one place before execution begins.
1570
+ ## 13e. Post-Planning Gap Analysis (plan:post capability gate dispatch)
1693
1571
 
1694
- **Skip if:** `workflow.post_planning_gaps` is `false`. Default is `true`.
1572
+ Proactive, non-blocking coverage report gated on `workflow.post_planning_gaps`
1573
+ (default `true`). Dispatched via the `plan:post` capability gate owned by the
1574
+ `gap-analysis` capability (ADR-857 §53). Reads REQUIREMENTS.md and CONTEXT.md
1575
+ `<decisions>` and cross-references each REQ-ID / D-ID against `${PHASE_DIR}/*-PLAN.md`.
1695
1576
 
1696
1577
  ```bash
1697
- POST_PLANNING_GAPS=$(gsd_run query config-get workflow.post_planning_gaps --default true 2>/dev/null || echo true)
1698
- if [ "$POST_PLANNING_GAPS" = "true" ]; then
1699
- # Scope to this phase's mapped REQ-IDs (#447); null/TBD skips the requirements comparison (CONTEXT.md decisions still reported), mirroring §13.
1700
- gsd_run gap-analysis --phase-dir "${PHASE_DIR}" --phase-req-ids "$(gsd_run query init.plan-phase "$PHASE" --pick phase_req_ids 2>/dev/null || echo TBD)"
1701
- fi
1578
+ PLAN_POST_HOOKS_JSON=$(gsd_run loop render-hooks plan:post --raw)
1579
+ PHASE_REQ_IDS=$(gsd_run query init.plan-phase "$PHASE" --pick phase_req_ids 2>/dev/null || echo TBD)
1702
1580
  ```
1703
1581
 
1704
- (`gsd-tools.cjs gap-analysis` reads `.planning/REQUIREMENTS.md`, `${PHASE_DIR}/CONTEXT.md`,
1705
- and `${PHASE_DIR}/*-PLAN.md`, then prints a markdown table with one row per
1706
- REQ-ID and D-ID. Word-boundary matching prevents `REQ-1` from being mistaken for
1707
- `REQ-10`.)
1582
+ Read the `activeHooks` array from `PLAN_POST_HOOKS_JSON` in-context. If the
1583
+ `gap-analysis` gate hook is absent (capability inactive), skip this step.
1708
1584
 
1709
- **Output format (deterministic; sorted REQUIREMENTS.md → CONTEXT.md, then natural
1710
- sort within source):**
1585
+ **For each active entry where `kind == "gate"`** (process in array order):
1711
1586
 
1587
+ ```bash
1588
+ GATE_RESULT=$(gsd_run check ${hook.check.query} "${PHASE_DIR}" "${PHASE_REQ_IDS}" --raw)
1589
+ CHECK_EXIT=$?
1712
1590
  ```
1713
- ## Post-Planning Gap Analysis
1714
1591
 
1715
- | Source | Item | Status |
1716
- |--------|------|--------|
1717
- | REQUIREMENTS.md | REQ-01 | ✓ Covered |
1718
- | REQUIREMENTS.md | REQ-02 | ✗ Not covered |
1719
- | CONTEXT.md | D-01 | ✓ Covered |
1720
- | CONTEXT.md | D-02 | ✗ Not covered |
1721
-
1722
- ⚠ N items not covered by any plan
1723
- ```
1592
+ **Step 1 — did the CHECK COMMAND itself succeed?**
1593
+ If the check command failed (non-zero `CHECK_EXIT`, empty output, or unparseable JSON):
1594
+ - `onError == "halt"` → halt and surface command error.
1595
+ - `onError == "skip"` → log a warning and continue to the next hook.
1724
1596
 
1725
- **Skip-gracefully behavior:**
1726
- - REQUIREMENTS.md missing → CONTEXT-only report.
1727
- - CONTEXT.md missing → REQUIREMENTS-only report.
1728
- - Both missing or `<decisions>` block missing → "No requirements or decisions to check" line, no error.
1597
+ **Step 2 — read `GATE_RESULT.block` (boolean).** Only reached when command succeeded.
1729
1598
 
1730
- This step is non-blocking. If items are reported as not covered, the user may
1731
- re-run `/gsd:plan-phase --gaps` to add plans, or proceed to execute-phase as-is.
1599
+ - If `hook.blocking == true` and `GATE_RESULT.block == true`: halt. (gap-analysis is always `blocking: false` so this branch is informational only.)
1600
+ - If `hook.blocking == false` (advisory): if `GATE_RESULT.block == true` or non-empty `table`/`summary`, output the gap table and continue. Advisory gates never block phase completion.
1601
+ - If `hook.blocking == true` and `GATE_RESULT.block == false`: continue silently.
1732
1602
 
1733
1603
  ## 14. Present Final Status
1734
1604
 
@@ -185,13 +185,23 @@ Run this pass unless `plan_review.source_grounding` is `false`. It verifies ever
185
185
 
186
186
  1. **Enumerate cited symbols.** List every referenced symbol by kind, quoting the plan line for each (coverage must be auditable): decorators (`@name`), classes/methods (`Class.method`), functions (`module.function`), CLI flags (`--name`), file paths, dataclass/struct fields.
187
187
  2. **Exclude new artifacts.** Do NOT verify symbols the plan declares under its "Artifacts this phase produces" section — those are created by this phase, not references to existing code.
188
- 3. **Resolve each remaining symbol** using the adapter named by `plan_review.source_grounding_authority` (default `grep`):
188
+ 3. **Resolve each remaining symbol** using the effective authority adapter (resolved deterministically — see step 4a):
189
189
  - `grep` — ripgrep / Read the source; confirm the name appears as a real declaration.
190
190
  - `intel` — consult `.planning/intel/API-SURFACE.md` / `api-map.json` (only when `intel.enabled`).
191
191
  Record one verdict per symbol: **VERIFIED** (quote `file:line`), **MISSING** (adapter can check this language/kind and the symbol is absent), **AMBIGUOUS** (multiple candidates), or **UNCHECKABLE** (adapter cannot analyze this language/kind — e.g. non-JS under `intel`, or any signature under `grep`). Never treat UNCHECKABLE as verified or missing.
192
- 4. **Severity & gating:**
193
- - **MISSING** at authority `grep`/`intel` → `needs-acknowledgement`: the plan proceeds only if the author confirms the symbol is genuinely new or dynamically resolved, and that acknowledgement is recorded. A hard block is reserved for higher-authority adapters (LSP/SCIP) that can prove absence.
194
- - **AMBIGUOUS** → MEDIUM. **UNCHECKABLE** → INFO.
192
+ 4a. **Resolve effective authority** (deterministic — replaces manual `intel.enabled` reasoning):
193
+ ```bash
194
+ EFFECTIVE_AUTHORITY=$(gsd_run drift-guard authority --raw)
195
+ ```
196
+ 4. **Severity & gating** — classify each symbol's verdict using the seam (do not apply the table manually):
197
+ ```bash
198
+ # For each symbol, e.g.:
199
+ RESULT=$(gsd_run drift-guard severity --status <verdict> --authority "$EFFECTIVE_AUTHORITY")
200
+ # $RESULT is JSON: {"severity":"…","hardBlock":true|false}
201
+ ```
202
+ - `hardBlock: true` (HIGH at authority `lsp`/`scip`) — stops the review cycle immediately; do not proceed until the plan author resolves the missing symbol.
203
+ - `hardBlock: false`, severity `needs-acknowledgement` — plan proceeds only if the author confirms the symbol is genuinely new or dynamically resolved, and that acknowledgement is recorded.
204
+ - `AMBIGUOUS` → MEDIUM. `UNCHECKABLE` → INFO.
195
205
  - Signature mismatches cannot be asserted under `grep`/`intel`; report the signature as UNCHECKABLE.
196
206
  5. **Coverage block.** Append a "Verification coverage" section to `REVIEWS.md` listing every UNCHECKABLE/skipped symbol and why — a clean review must never silently mean "nothing was checked."
197
207
 
@@ -10,11 +10,13 @@ Uses git cherry-pick with path filtering to rebuild a clean history.
10
10
  <process>
11
11
 
12
12
  <step name="detect_state">
13
- Parse `$ARGUMENTS` for target branch (default: `main`).
13
+ Parse `$ARGUMENTS` for target branch. If no argument is supplied, detect the
14
+ default branch via the single resolver (#1146).
14
15
 
15
16
  ```bash
17
+ _GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; if [ -f "$GSD_TOOLS" ]; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif command -v gsd-tools >/dev/null 2>&1; then GSD_TOOLS="$(command -v gsd-tools)"; gsd_run() { "$GSD_TOOLS" "$@"; }; elif [ -f "$HOME/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="$HOME/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd-tools is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${GSD_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${GSD_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
16
18
  CURRENT_BRANCH=$(git branch --show-current)
17
- TARGET=${1:-main}
19
+ TARGET=${1:-$(gsd_run query git.base-branch)}
18
20
  ```
19
21
 
20
22
  Check preconditions:
@@ -414,10 +414,12 @@ Then list paths for each generated artifact:
414
414
  ```
415
415
  Artifacts:
416
416
  ✓ /gsd-dev-preferences $HOME/.claude/skills/gsd-dev-preferences/SKILL.md
417
- ✓ CLAUDE.md section ./CLAUDE.md
417
+ ✓ CLAUDE.md section <resolved claude_md_path, default ./.claude/CLAUDE.md>
418
418
  ✓ Global CLAUDE.md $HOME/.claude/CLAUDE.md
419
419
  ```
420
420
 
421
+ (Show the `claude_md_path` actually returned by the command — it defaults to `./.claude/CLAUDE.md` but may be overridden by config or `--output`.)
422
+
421
423
  (Only show artifacts that were actually generated.)
422
424
 
423
425
  **Clean up temp files:**