@opengsd/gsd-core 1.7.0 → 1.9.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.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.opencode/plugins/gsd-core.js +45 -1
- package/README.md +2 -0
- package/agents/gsd-code-fixer.md +1 -1
- package/agents/gsd-codebase-mapper.md +1 -1
- package/agents/gsd-debug-session-manager.md +78 -4
- package/agents/gsd-debugger.md +87 -29
- package/agents/gsd-executor.md +49 -9
- package/agents/gsd-intel-updater.md +3 -3
- package/agents/gsd-phase-researcher.md +4 -2
- package/agents/gsd-plan-checker.md +20 -0
- package/agents/gsd-planner.md +44 -59
- package/agents/gsd-project-researcher.md +2 -2
- package/agents/gsd-ui-auditor.md +0 -40
- package/agents/gsd-verifier.md +2 -2
- package/bin/install.js +1338 -135
- package/commands/gsd/ai-integration-phase.md +1 -1
- package/commands/gsd/mempalace-capture.md +9 -5
- package/commands/gsd/new-milestone.md +1 -1
- package/commands/gsd/plan-phase.md +5 -3
- package/commands/gsd/plan-review-convergence.md +7 -2
- package/gsd-core/bin/gsd-tools.cjs +2690 -2472
- package/gsd-core/bin/lib/adapter-imperative.cjs +8 -1
- package/gsd-core/bin/lib/agent-command-router.cjs +20 -5
- package/gsd-core/bin/lib/api-coverage.cjs +360 -53
- package/gsd-core/bin/lib/audit.cjs +8 -8
- package/gsd-core/bin/lib/broken-windows.cjs +716 -0
- package/gsd-core/bin/lib/capability-command-router.cjs +733 -0
- package/gsd-core/bin/lib/capability-consent.cjs +40 -1
- package/gsd-core/bin/lib/capability-lifecycle.cjs +58 -0
- package/gsd-core/bin/lib/capability-loader.cjs +23 -1
- package/gsd-core/bin/lib/capability-registry.cjs +1450 -160
- package/gsd-core/bin/lib/capability-trust.cjs +468 -33
- package/gsd-core/bin/lib/capability-validator.cjs +882 -6
- package/gsd-core/bin/lib/capability-writer.cjs +6 -1
- package/gsd-core/bin/lib/check-command-router.cjs +140 -27
- package/gsd-core/bin/lib/cjs-command-router-adapter.cjs +15 -0
- package/gsd-core/bin/lib/claude-orchestration-command-router.cjs +209 -31
- package/gsd-core/bin/lib/claude-orchestration.cjs +203 -25
- package/gsd-core/bin/lib/command-aliases.cjs +14 -0
- package/gsd-core/bin/lib/commands.cjs +326 -21
- package/gsd-core/bin/lib/config-loader.cjs +214 -30
- package/gsd-core/bin/lib/config.cjs +158 -22
- package/gsd-core/bin/lib/core-utils.cjs +6 -1
- package/gsd-core/bin/lib/decisions.cjs +32 -8
- package/gsd-core/bin/lib/docs.cjs +6 -0
- package/gsd-core/bin/lib/estimate-cli.cjs +336 -0
- package/gsd-core/bin/lib/external-descriptor-trust.cjs +14 -2
- package/gsd-core/bin/lib/frontmatter.cjs +125 -15
- package/gsd-core/bin/lib/gap-checker.cjs +17 -2
- package/gsd-core/bin/lib/host-integration.cjs +215 -8
- package/gsd-core/bin/lib/init.cjs +155 -66
- package/gsd-core/bin/lib/install-engine.cjs +299 -23
- package/gsd-core/bin/lib/install-profiles.cjs +239 -1
- package/gsd-core/bin/lib/installer-migrations/005-opencode-baseline-commands-dir.cjs +146 -0
- package/gsd-core/bin/lib/installer-migrations/006-pi-extension-cjs-to-js.cjs +91 -0
- package/gsd-core/bin/lib/installer-migrations.cjs +44 -5
- package/gsd-core/bin/lib/markdown-sectionizer.cjs +107 -0
- package/gsd-core/bin/lib/milestone.cjs +248 -14
- package/gsd-core/bin/lib/model-catalog.cjs +69 -4
- package/gsd-core/bin/lib/model-resolver.cjs +189 -7
- package/gsd-core/bin/lib/observability/logger.cjs +7 -2
- package/gsd-core/bin/lib/onboard-projection.cjs +11 -8
- package/gsd-core/bin/lib/phase-command-router.cjs +10 -1
- package/gsd-core/bin/lib/phase-estimation.cjs +398 -0
- package/gsd-core/bin/lib/phase-id.cjs +304 -9
- package/gsd-core/bin/lib/phase.cjs +258 -17
- package/gsd-core/bin/lib/plan-drift-guard.cjs +1 -1
- package/gsd-core/bin/lib/plan-scan.cjs +70 -2
- package/gsd-core/bin/lib/planning-workspace.cjs +9 -2
- package/gsd-core/bin/lib/profile-output.cjs +34 -8
- package/gsd-core/bin/lib/review-lane-descriptor.cjs +927 -0
- package/gsd-core/bin/lib/review-lane-invocation.cjs +348 -0
- package/gsd-core/bin/lib/review-lane-runner.cjs +594 -0
- package/gsd-core/bin/lib/review-reviewer-selection.cjs +114 -32
- package/gsd-core/bin/lib/roadmap-parser.cjs +61 -10
- package/gsd-core/bin/lib/roadmap.cjs +23 -7
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +38 -5
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +23 -9
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +156 -0
- package/gsd-core/bin/lib/runtime-name-policy.cjs +15 -2
- package/gsd-core/bin/lib/smart-entry.cjs +70 -5
- package/gsd-core/bin/lib/state-document.cjs +171 -24
- package/gsd-core/bin/lib/state-transition.cjs +50 -11
- package/gsd-core/bin/lib/state.cjs +206 -32
- package/gsd-core/bin/lib/surface.cjs +51 -9
- package/gsd-core/bin/lib/uat-predicate.cjs +6 -4
- package/gsd-core/bin/lib/uat.cjs +428 -11
- package/gsd-core/bin/lib/ui-consideration-probe.cjs +2 -2
- package/gsd-core/bin/lib/unusable-input.cjs +216 -0
- package/gsd-core/bin/lib/validate.cjs +44 -8
- package/gsd-core/bin/lib/verification.cjs +163 -31
- package/gsd-core/bin/lib/verify.cjs +348 -42
- package/gsd-core/bin/lib/worktree-safety.cjs +360 -15
- package/gsd-core/bin/shared/config-defaults.manifest.json +1 -0
- package/gsd-core/bin/shared/config-schema.manifest.json +4 -15
- package/gsd-core/bin/shared/model-catalog.json +5 -0
- package/gsd-core/bin/shared/runtime-aliases.manifest.json +5 -0
- package/gsd-core/references/api-coverage.md +37 -7
- package/gsd-core/references/checkpoints.md +1 -1
- package/gsd-core/references/common-bug-patterns.md +13 -0
- package/gsd-core/references/context-budget.md +40 -0
- package/gsd-core/references/debugger-bug-taxonomy.md +111 -0
- package/gsd-core/references/debugger-fix-acceptance.md +157 -0
- package/gsd-core/references/debugger-philosophy.md +1 -0
- package/gsd-core/references/debugger-prevention.md +98 -0
- package/gsd-core/references/debugger-rca-branching.md +98 -0
- package/gsd-core/references/debugger-repro-hardening.md +130 -0
- package/gsd-core/references/debugger-sbfl.md +110 -0
- package/gsd-core/references/debugger-semantic-recall.md +81 -0
- package/gsd-core/references/execute-phase-quota-recovery.md +55 -0
- package/gsd-core/references/execute-phase-requirement-revert.md +8 -0
- package/gsd-core/references/execute-phase-response-language.md +7 -0
- package/gsd-core/references/gate-prompts.md +6 -3
- package/gsd-core/references/model-profile-resolution.md +64 -13
- package/gsd-core/references/offer-next.md +88 -0
- package/gsd-core/references/planner-antipatterns.md +6 -0
- package/gsd-core/references/planner-mvp-mode.md +12 -13
- package/gsd-core/references/planner-preconditions.md +156 -0
- package/gsd-core/references/planner-reversibility.md +132 -0
- package/gsd-core/references/planning-config.md +2 -1
- package/gsd-core/references/reviewer-instances.md +28 -19
- package/gsd-core/references/runtime-aware-dispatch.md +42 -0
- package/gsd-core/references/skeleton-template.md +1 -1
- package/gsd-core/references/thinking-models-planning.md +3 -1
- package/gsd-core/references/ui-consideration-probe.md +2 -2
- package/gsd-core/references/worktree-branch-check.md +4 -4
- package/gsd-core/templates/DEBUG.md +5 -3
- package/gsd-core/templates/summary-minimal.md +4 -0
- package/gsd-core/templates/summary-standard.md +4 -0
- package/gsd-core/templates/summary.md +7 -0
- package/gsd-core/workflows/add-phase.md +2 -0
- package/gsd-core/workflows/add-tests.md +3 -1
- package/gsd-core/workflows/add-todo.md +32 -1
- package/gsd-core/workflows/ai-integration-phase.md +8 -6
- package/gsd-core/workflows/audit-fix.md +6 -2
- package/gsd-core/workflows/audit-milestone.md +8 -0
- package/gsd-core/workflows/autonomous.md +19 -15
- package/gsd-core/workflows/check-todos.md +5 -3
- package/gsd-core/workflows/cleanup.md +7 -1
- package/gsd-core/workflows/code-review-fix.md +14 -6
- package/gsd-core/workflows/code-review.md +93 -24
- package/gsd-core/workflows/complete-milestone.md +3 -0
- package/gsd-core/workflows/debug.md +35 -7
- package/gsd-core/workflows/diagnose-issues.md +5 -1
- package/gsd-core/workflows/discovery-phase.md +7 -0
- package/gsd-core/workflows/discuss-phase/modes/advisor.md +2 -4
- package/gsd-core/workflows/discuss-phase/modes/auto.md +0 -6
- package/gsd-core/workflows/discuss-phase/templates/context.md +16 -2
- package/gsd-core/workflows/discuss-phase-assumptions.md +18 -9
- package/gsd-core/workflows/discuss-phase.md +2 -2
- package/gsd-core/workflows/do.md +7 -1
- package/gsd-core/workflows/docs-update.md +9 -0
- package/gsd-core/workflows/eval-review.md +4 -1
- package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +4 -0
- package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +160 -0
- package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +4 -4
- package/gsd-core/workflows/execute-phase/steps/regression-gate.md +2 -2
- package/gsd-core/workflows/execute-phase.md +110 -149
- package/gsd-core/workflows/execute-plan.md +20 -8
- package/gsd-core/workflows/explore.md +4 -0
- package/gsd-core/workflows/extract-learnings.md +21 -0
- package/gsd-core/workflows/graduation.md +3 -0
- package/gsd-core/workflows/health.md +7 -1
- package/gsd-core/workflows/help/modes/full.md +9 -5
- package/gsd-core/workflows/import.md +11 -2
- package/gsd-core/workflows/inbox.md +7 -0
- package/gsd-core/workflows/ingest-docs.md +19 -10
- package/gsd-core/workflows/manager.md +3 -1
- package/gsd-core/workflows/map-codebase.md +17 -10
- package/gsd-core/workflows/mvp-phase.md +3 -0
- package/gsd-core/workflows/new-milestone.md +79 -23
- package/gsd-core/workflows/new-project.md +28 -19
- package/gsd-core/workflows/new-workspace.md +3 -1
- package/gsd-core/workflows/next.md +5 -2
- package/gsd-core/workflows/onboard.md +3 -0
- package/gsd-core/workflows/plan-phase.md +56 -51
- package/gsd-core/workflows/plan-review-convergence.md +61 -12
- package/gsd-core/workflows/plant-seed.md +3 -0
- package/gsd-core/workflows/profile-user.md +7 -1
- package/gsd-core/workflows/progress.md +31 -3
- package/gsd-core/workflows/quick.md +33 -10
- package/gsd-core/workflows/remove-workspace.md +3 -0
- package/gsd-core/workflows/review.md +172 -585
- package/gsd-core/workflows/scan.md +10 -2
- package/gsd-core/workflows/secure-phase.md +13 -2
- package/gsd-core/workflows/settings-integrations.md +3 -0
- package/gsd-core/workflows/settings.md +3 -0
- package/gsd-core/workflows/ship.md +88 -11
- package/gsd-core/workflows/sketch.md +3 -0
- package/gsd-core/workflows/smart-entry.md +4 -1
- package/gsd-core/workflows/spike.md +7 -1
- package/gsd-core/workflows/ui-phase.md +11 -2
- package/gsd-core/workflows/ui-review.md +11 -1
- package/gsd-core/workflows/undo.md +7 -0
- package/gsd-core/workflows/update.md +106 -5
- package/gsd-core/workflows/validate-phase.md +13 -2
- package/gsd-core/workflows/verify-phase.md +2 -2
- package/gsd-core/workflows/verify-work.md +15 -4
- package/hooks/dist/gsd-context-monitor.js +27 -9
- package/hooks/dist/gsd-cursor-session-start.js +6 -2
- package/hooks/dist/gsd-cursor-stop.js +6 -2
- package/hooks/dist/gsd-cursor-subagent-start.js +6 -2
- package/hooks/dist/gsd-graphify-update.sh +9 -0
- package/hooks/dist/gsd-phase-boundary.sh +14 -2
- package/hooks/dist/gsd-prompt-guard.js +101 -2
- package/hooks/dist/gsd-read-guard.js +100 -2
- package/hooks/dist/gsd-read-injection-scanner.js +109 -2
- package/hooks/dist/gsd-statusline.js +97 -9
- package/hooks/dist/gsd-workflow-guard.js +110 -6
- package/hooks/dist/gsd-worktree-path-guard.js +132 -8
- package/hooks/dist/lib/cursor-workspace.js +74 -0
- package/hooks/gsd-context-monitor.js +27 -9
- package/hooks/gsd-cursor-session-start.js +6 -2
- package/hooks/gsd-cursor-stop.js +6 -2
- package/hooks/gsd-cursor-subagent-start.js +6 -2
- package/hooks/gsd-graphify-update.sh +9 -0
- package/hooks/gsd-phase-boundary.sh +14 -2
- package/hooks/gsd-prompt-guard.js +101 -2
- package/hooks/gsd-read-guard.js +100 -2
- package/hooks/gsd-read-injection-scanner.js +109 -2
- package/hooks/gsd-statusline.js +97 -9
- package/hooks/gsd-workflow-guard.js +110 -6
- package/hooks/gsd-worktree-path-guard.js +132 -8
- package/hooks/lib/cursor-workspace.js +74 -0
- package/package.json +10 -8
- package/pi/gsd.cjs +34 -3
- package/scripts/changeset/lint.cjs +1 -0
- package/scripts/changeset/parse.cjs +26 -0
- package/scripts/check-coverage-gate.cjs +51 -0
- package/scripts/check-glossary-refs.cjs +244 -0
- package/scripts/ci-rebase-check.cjs +48 -4
- package/scripts/ci-test-scope.cjs +67 -17
- package/scripts/gen-adr-index.cjs +528 -0
- package/scripts/gen-capability-matrix.cjs +26 -2
- package/scripts/gen-capability-registry.cjs +132 -34
- package/scripts/gen-emitted-baseline.cjs +145 -0
- package/scripts/gen-test-timings.cjs +201 -0
- package/scripts/lint-compiled-artifact-sync.cjs +146 -0
- package/scripts/lint-emitted-drift-ack.cjs +149 -0
- package/scripts/lint-fix-has-regression-test.cjs +131 -0
- package/scripts/lint-portable-timeout.cjs +140 -0
- package/scripts/lint-resolution-provenance.cjs +9 -0
- package/scripts/lint-test-file-count.allowlist.json +1 -0
- package/scripts/mutation-matrix.cjs +4 -0
- package/scripts/prompt-injection-scan.sh +6 -0
- package/scripts/registry-schema.cjs +57 -8
- package/scripts/release-notes/conventional-title.cjs +19 -1
- package/scripts/release-notes/format-github-release-notes.cjs +7 -3
- package/scripts/release-tarball-smoke.cjs +18 -11
- package/scripts/run-tests.cjs +420 -58
- package/scripts/workflow-size.cjs +16 -8
- package/skills/gsd-ai-integration-phase/SKILL.md +1 -1
- package/skills/gsd-mempalace-capture/SKILL.md +9 -5
- package/skills/gsd-new-milestone/SKILL.md +1 -1
- package/skills/gsd-plan-phase/SKILL.md +5 -3
- package/skills/gsd-plan-review-convergence/SKILL.md +7 -2
- package/vscode/package.json +1 -1
- package/scripts/gen-golden-install-parity-zcode.cjs +0 -77
- package/scripts/update-size-baseline.cjs +0 -68
|
@@ -13,6 +13,10 @@ Execute all plans in a phase using wave-based parallel execution. Orchestrator s
|
|
|
13
13
|
Orchestrator coordinates, not executes. Each subagent loads the full execute-plan context. Orchestrator: discover plans → analyze deps → group waves → spawn agents → handle checkpoints → collect results.
|
|
14
14
|
</core_principle>
|
|
15
15
|
|
|
16
|
+
<!-- #2508 runtime-aware-dispatch -->
|
|
17
|
+
|
|
18
|
+
> **Runtime-aware dispatch (#2508 Phase 4).** GSD workflows dispatch specialized subagents by role. Before dispatching on a built-in-only runtime (kimi-code — three built-ins only), resolve the role to a built-in via `gsd_run query resolve-dispatch-type --requested <role> --raw`. On named-dispatch runtimes (Claude/OpenCode/…) the role is returned unchanged; on kimi-code it maps to `coder`/`explore`/`plan` by role-suffix. The persona rides `${AGENT_SKILLS_<ROLE>}` (Phase 3) regardless. See @gsd-core/references/runtime-aware-dispatch.md.
|
|
19
|
+
|
|
16
20
|
<runtime_compatibility>
|
|
17
21
|
**Subagent spawning is runtime-specific:**
|
|
18
22
|
- **Claude Code:** Uses `Agent(subagent_type="gsd-executor", ...)` — blocks until complete, returns result
|
|
@@ -82,11 +86,11 @@ if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
|
82
86
|
AGENT_SKILLS=$(gsd_run query agent-skills gsd-executor)
|
|
83
87
|
```
|
|
84
88
|
|
|
85
|
-
Parse JSON for: `executor_model`, `verifier_model`, `commit_docs`, `parallelization`, `branching_strategy`, `branch_name`, `phase_found`, `phase_dir`, `phase_number`, `phase_name`, `phase_slug`, `plans`, `incomplete_plans`, `plan_count`, `incomplete_count`, `state_exists`, `roadmap_exists`, `phase_req_ids`, `response_language`.
|
|
89
|
+
Parse JSON for: `executor_model`, `verifier_model`, `commit_docs`, `parallelization`, `branching_strategy`, `branch_name`, `phase_found`, `phase_dir`, `phase_number`, `phase_name`, `phase_slug`, `plans`, `incomplete_plans`, `plan_count`, `incomplete_count`, `state_exists`, `roadmap_exists`, `phase_req_ids`, `response_language`, `requirements_path`.
|
|
86
90
|
|
|
87
91
|
**Model resolution:** If `executor_model` is `"inherit"`, omit the `model=` parameter from all `Agent()` calls — do NOT pass `model="inherit"` to Agent. Omitting the `model=` parameter causes Claude Code to inherit the current orchestrator model automatically. Only set `model=` when `executor_model` is an explicit model name (e.g., `"claude-sonnet-5"`, `"claude-opus-4-8"`).
|
|
88
92
|
|
|
89
|
-
|
|
93
|
+
@~/.claude/gsd-core/references/execute-phase-response-language.md
|
|
90
94
|
|
|
91
95
|
Read runtime/worktree config and fail closed before any executor dispatch:
|
|
92
96
|
|
|
@@ -96,26 +100,16 @@ USE_WORKTREES=$(gsd_run query config-get workflow.use_worktrees --raw 2>/dev/nul
|
|
|
96
100
|
EXECUTOR_STALL_INTERVAL_MINUTES=$(gsd_run query config-get executor.stall_detect_interval_minutes 2>/dev/null || echo "5")
|
|
97
101
|
EXECUTOR_STALL_THRESHOLD_MINUTES=$(gsd_run query config-get executor.stall_threshold_minutes 2>/dev/null || echo "10")
|
|
98
102
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
#
|
|
104
|
-
[ "$USE_WORKTREES" != "false" ] && gsd_run query worktree.reap-orphans 2>/dev/null || true
|
|
105
|
-
# Auto-degrade to sequential if HEAD has diverged from the worktree fork base (#683).
|
|
106
|
-
# Only applies to Claude Code (isolation="worktree" is Claude-Code-specific).
|
|
107
|
-
if [ "$RUNTIME" = "claude" ] && [ "$USE_WORKTREES" != "false" ]; then
|
|
108
|
-
_SHOULD_DEGRADE=$(gsd_run query worktree.base-check --pick shouldDegrade 2>/dev/null || true)
|
|
109
|
-
if [ "$_SHOULD_DEGRADE" = "true" ]; then
|
|
110
|
-
_DEGRADE_MSG=$(gsd_run query worktree.base-check --pick message 2>/dev/null || true)
|
|
111
|
-
[ -n "$_DEGRADE_MSG" ] && printf '%s\n' "$_DEGRADE_MSG" >&2
|
|
112
|
-
USE_WORKTREES=false
|
|
113
|
-
fi
|
|
114
|
-
fi
|
|
103
|
+
# Resolve ISOLATION + apply its guards: read and execute the "Resolve ISOLATION"
|
|
104
|
+
# section of execute-phase/steps/executor-isolation-dispatch.md. It sets
|
|
105
|
+
# ISOLATION (harness-worktree|orchestrator-worktree|none), forces none when
|
|
106
|
+
# USE_WORKTREES=false, fails closed when a host has no primitive, sweeps orphans,
|
|
107
|
+
# and applies the #683 fork-base auto-degrade.
|
|
115
108
|
```
|
|
116
|
-
`isolation="worktree"` is a Claude-Code-specific agent primitive; no other runtime can honor it (Codex maps subagents to `spawn_agent`, others prohibit or omit worktree binding). Failing closed prevents main-checkout edits while the workflow believes agents are isolated.
|
|
117
109
|
|
|
118
|
-
|
|
110
|
+
`ISOLATION` — not `RUNTIME` — is the ONLY fan-out branch point; **never add a `RUNTIME = "codex"` test here.** Per-host dispatch detail lives in `execute-phase/steps/executor-isolation-dispatch.md` (read from step 3).
|
|
111
|
+
|
|
112
|
+
If the project uses git submodules, worktree isolation is unsafe **only when a plan touches a submodule path** — the executor commit protocol cannot correctly handle submodule commits inside isolated worktrees. Compute submodule paths once and intersect them per-plan with the plan's declared `files_modified` frontmatter.
|
|
119
113
|
|
|
120
114
|
```bash
|
|
121
115
|
# Parse submodule paths from .gitmodules once (empty if no .gitmodules).
|
|
@@ -127,11 +121,11 @@ else
|
|
|
127
121
|
fi
|
|
128
122
|
```
|
|
129
123
|
|
|
130
|
-
`SUBMODULE_PATHS` is exported to the `execute_waves` step, where the per-plan decision
|
|
124
|
+
`SUBMODULE_PATHS` is exported to the `execute_waves` step, where the per-plan decision happens (see "Per-plan worktree decision" sub-step inside `execute_waves`). The decision is per-plan because different plans in the same wave can touch different files — only plans whose paths intersect a submodule must drop worktree isolation; plans nowhere near a submodule keep parallel isolation.
|
|
131
125
|
|
|
132
|
-
When `USE_WORKTREES`
|
|
126
|
+
When `USE_WORKTREES` is `false`, `ISOLATION` is forced to `none`: executors run sequentially on the main working tree. The per-plan decision below has no effect when worktrees are project-disabled.
|
|
133
127
|
|
|
134
|
-
`USE_WORKTREES`
|
|
128
|
+
`USE_WORKTREES` and `ISOLATION` are also reset for the run when `worktree base-check` detects the orchestrator HEAD has diverged from the worktree fork base (#683 — e.g. an unmerged milestone branch). This runs for **any** isolated run, not only Claude: fork-base divergence is a property of the repository, so it degrades a GSD-created worktree exactly as a harness-created one. The auto-degrade prints a one-line warning to stderr and falls through to the sequential path so executors do not hit the exit-42 worktree-branch-check halt. To restore parallel worktree execution, set `worktree.baseRef:"head"` in `.claude/settings.local.json` (or run `gsd_run worktree set-baseref`) — this makes the fork base track the live HEAD instead of a fixed remote ref. The `worktree-branch-check` exit-42 guard inside each executor remains in place as a backstop.
|
|
135
129
|
|
|
136
130
|
Read context window size for adaptive prompt enrichment:
|
|
137
131
|
|
|
@@ -277,12 +271,6 @@ checkpoints between tasks. The user can review, modify, or redirect work at any
|
|
|
277
271
|
|
|
278
272
|
3. After all plans: proceed to verification (same as normal mode).
|
|
279
273
|
|
|
280
|
-
**Benefits of interactive mode:**
|
|
281
|
-
- No subagent overhead — dramatically lower token usage
|
|
282
|
-
- User catches mistakes early — saves costly verification cycles
|
|
283
|
-
- Maintains GSD's planning/tracking structure
|
|
284
|
-
- Best for: small phases, bug fixes, verification gaps, learning GSD
|
|
285
|
-
|
|
286
274
|
**Skip to handle_branching step** (interactive plans execute inline after grouping).
|
|
287
275
|
</step>
|
|
288
276
|
|
|
@@ -313,10 +301,8 @@ else
|
|
|
313
301
|
else
|
|
314
302
|
git switch --quiet "$DEFAULT_BRANCH" 2>/dev/null && git merge --ff-only --quiet "origin/$DEFAULT_BRANCH" 2>/dev/null || true
|
|
315
303
|
fi
|
|
316
|
-
# Pinned base
|
|
317
|
-
|
|
318
|
-
# explicit base argument here is the single source of correctness for #2916.
|
|
319
|
-
git checkout -b "$BRANCH_NAME" "origin/$DEFAULT_BRANCH" \
|
|
304
|
+
# Pinned base (#2916); --no-track (#2498) so default autoSetupMerge doesn't wire upstream to origin/$DEFAULT_BRANCH.
|
|
305
|
+
git checkout -b "$BRANCH_NAME" "origin/$DEFAULT_BRANCH" --no-track \
|
|
320
306
|
|| { echo "ERROR: Could not create '$BRANCH_NAME' from origin/$DEFAULT_BRANCH (#2916)." >&2; exit 1; }
|
|
321
307
|
fi
|
|
322
308
|
```
|
|
@@ -409,7 +395,7 @@ CROSS_AI_TIMEOUT=$(gsd_run query config-get workflow.cross_ai_timeout 2>/dev/nul
|
|
|
409
395
|
3. **Run the external command** from the project root, writing the prompt to stdin.
|
|
410
396
|
Never shell-interpolate the prompt — always pipe via stdin to prevent injection:
|
|
411
397
|
```bash
|
|
412
|
-
echo "$TASK_PROMPT" | timeout "${CROSS_AI_TIMEOUT}
|
|
398
|
+
echo "$TASK_PROMPT" | gsd_run run-with-timeout "${CROSS_AI_TIMEOUT}" -- ${CROSS_AI_CMD} > "$CANDIDATE_SUMMARY" 2>"$ERROR_LOG"
|
|
413
399
|
EXIT_CODE=$?
|
|
414
400
|
```
|
|
415
401
|
|
|
@@ -447,18 +433,63 @@ cwd inside an agent worktree (or a subdirectory of one). Every subsequent
|
|
|
447
433
|
orchestrator-side git call would then target the wrong tree — this is how a wrong-base
|
|
448
434
|
merge nearly shipped ~1000 files. Resolve the *worktree root* (so a subdirectory cwd
|
|
449
435
|
cannot skew the check) and refuse if it is an agent worktree. The discriminator is the
|
|
450
|
-
per-agent branch namespace `worktree-agent-*`, NOT the `.claude/worktrees/` path: the
|
|
436
|
+
per-agent branch namespace `agent-*` / `worktree-agent-*`, NOT the `.claude/worktrees/` path: the
|
|
451
437
|
orchestrator may itself be legitimately invoked from a feature worktree under
|
|
452
438
|
`.claude/worktrees/`, so a path-substring refusal would break legitimate runs. Do NOT
|
|
453
439
|
pin to `git worktree list`'s first entry — that is the main worktree, the wrong target
|
|
454
440
|
when the orchestrator legitimately runs from a feature worktree.
|
|
455
441
|
|
|
456
442
|
```bash
|
|
443
|
+
# gsd:guard=orchestrator-cwd-drift
|
|
457
444
|
ORCHESTRATOR_WT=$(git rev-parse --show-toplevel 2>/dev/null) || {
|
|
458
445
|
echo "FATAL: execute_waves entry is not inside a git worktree (#48)." >&2; exit 1; }
|
|
459
446
|
ORCH_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
|
|
460
|
-
if printf '%s' "$ORCH_BRANCH" | grep -Eq '^worktree-agent-'; then
|
|
447
|
+
if printf '%s' "$ORCH_BRANCH" | grep -Eq '^(worktree-)?agent-'; then
|
|
461
448
|
echo "FATAL: orchestrator cwd is inside an agent worktree (branch '$ORCH_BRANCH', root '$ORCHESTRATOR_WT') — refusing to execute waves (#48). A prior isolation=\"worktree\" dispatch drifted the cwd; re-run from the orchestrator's own worktree." >&2
|
|
449
|
+
# #1856 handoff: the refusal above is correct, but on its own it is a dead end —
|
|
450
|
+
# this worktree may hold committed fixes AND uncommitted work, and "re-run from
|
|
451
|
+
# the orchestrator's worktree" silently means abandoning them. Report exactly
|
|
452
|
+
# what is stranded and how to integrate it. Every command here is DIAGNOSTIC:
|
|
453
|
+
# each is `|| true`-guarded so a failure degrades to the plain refusal above
|
|
454
|
+
# rather than crashing before the message prints.
|
|
455
|
+
_WT_BASE=""
|
|
456
|
+
for _ref in "$(git rev-parse --abbrev-ref --symbolic-full-name '@{u}' 2>/dev/null || true)" \
|
|
457
|
+
origin/next origin/main next main; do
|
|
458
|
+
[ -n "$_ref" ] || continue
|
|
459
|
+
if git rev-parse --verify --quiet "$_ref" >/dev/null 2>&1; then _WT_BASE="$_ref"; break; fi
|
|
460
|
+
done
|
|
461
|
+
_WT_AHEAD=""
|
|
462
|
+
[ -n "$_WT_BASE" ] && _WT_AHEAD=$(git rev-list --count "$_WT_BASE..HEAD" 2>/dev/null || true)
|
|
463
|
+
# Count BEFORE truncating, so a long list reports its true size rather than
|
|
464
|
+
# under-reporting what is stranded — which is the whole point of this report.
|
|
465
|
+
_WT_DIRTY_ALL=$(git status --porcelain 2>/dev/null || true)
|
|
466
|
+
_WT_DIRTY_N=0
|
|
467
|
+
[ -n "$_WT_DIRTY_ALL" ] && _WT_DIRTY_N=$(printf '%s\n' "$_WT_DIRTY_ALL" | wc -l | tr -d ' ')
|
|
468
|
+
_WT_HAS_COMMITS=0
|
|
469
|
+
[ -n "$_WT_AHEAD" ] && [ "$_WT_AHEAD" -gt 0 ] 2>/dev/null && _WT_HAS_COMMITS=1
|
|
470
|
+
|
|
471
|
+
echo "" >&2
|
|
472
|
+
echo "── Handoff: what is in this worktree (#1856) ──" >&2
|
|
473
|
+
if [ "$_WT_HAS_COMMITS" -eq 1 ]; then
|
|
474
|
+
echo " $_WT_AHEAD commit(s) on '$ORCH_BRANCH' not on '$_WT_BASE':" >&2
|
|
475
|
+
git log --oneline --no-decorate "$_WT_BASE..HEAD" 2>/dev/null | head -20 | sed 's/^/ /' >&2 || true
|
|
476
|
+
[ "$_WT_AHEAD" -gt 20 ] 2>/dev/null && echo " … and $((_WT_AHEAD - 20)) more" >&2
|
|
477
|
+
echo " These live ONLY on this branch. Switching away without integrating loses them." >&2
|
|
478
|
+
fi
|
|
479
|
+
if [ -n "$_WT_DIRTY_ALL" ]; then
|
|
480
|
+
echo " $_WT_DIRTY_N uncommitted change(s) still in this worktree:" >&2
|
|
481
|
+
printf '%s\n' "$_WT_DIRTY_ALL" | head -20 | sed 's/^/ /' >&2
|
|
482
|
+
[ "$_WT_DIRTY_N" -gt 20 ] 2>/dev/null && echo " … and $((_WT_DIRTY_N - 20)) more" >&2
|
|
483
|
+
fi
|
|
484
|
+
if [ "$_WT_HAS_COMMITS" -eq 1 ] || [ -n "$_WT_DIRTY_ALL" ]; then
|
|
485
|
+
echo "" >&2
|
|
486
|
+
echo " To integrate before continuing:" >&2
|
|
487
|
+
[ -n "$_WT_DIRTY_ALL" ] && echo " 1. git add -A && git commit -m 'wip: recover worktree state' # from THIS worktree" >&2
|
|
488
|
+
echo " 2. cd <orchestrator worktree> # a checkout whose branch is NOT agent-*/worktree-agent-*" >&2
|
|
489
|
+
echo " 3. git merge --no-ff $ORCH_BRANCH # or: git cherry-pick <sha>... for selected commits" >&2
|
|
490
|
+
echo " 4. re-run the phase from there" >&2
|
|
491
|
+
echo " Verify with: git log --oneline ${_WT_BASE:-HEAD}..$ORCH_BRANCH" >&2
|
|
492
|
+
fi
|
|
462
493
|
exit 1
|
|
463
494
|
fi
|
|
464
495
|
# Pin to the worktree root; each later orchestrator-side block re-pins the same way
|
|
@@ -553,13 +584,21 @@ increases monotonically across waves. `{status}` is `complete` (success),
|
|
|
553
584
|
```
|
|
554
585
|
|
|
555
586
|
- Bad: "Executing terrain generation plan"
|
|
556
|
-
- Good: "Procedural terrain generator using Perlin noise — creates height maps
|
|
587
|
+
- Good: "Procedural terrain generator using Perlin noise — creates height maps and biome zones. Required before vehicle physics."
|
|
557
588
|
|
|
558
589
|
2.5. **Per-plan worktree decision (run for each plan in this wave BEFORE its dispatch):**
|
|
559
590
|
|
|
560
591
|
Read and execute `gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md` for each plan. It extracts `PLAN_FILES` from the plan's JSON, intersects against `SUBMODULE_PATHS` (with normalization, bidirectional matching, and glob-prefix handling), and sets `USE_WORKTREES_FOR_PLAN` to `false` when the plan touches a submodule path. Append `plan_id` to a `WAVE_WORKTREE_PLANS` accumulator when `USE_WORKTREES_FOR_PLAN != false`.
|
|
561
592
|
|
|
562
|
-
The dispatch branches in step 3
|
|
593
|
+
The dispatch branches in step 3 gate on both `USE_WORKTREES` and `USE_WORKTREES_FOR_PLAN` (#2474).
|
|
594
|
+
|
|
595
|
+
2.75. **Execute:wave:pre capability dispatch:**
|
|
596
|
+
|
|
597
|
+
```bash
|
|
598
|
+
WAVE_PRE_HOOKS_JSON=$(gsd_run loop render-hooks execute:wave:pre --raw)
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
If a contribution's `activeHooks` entry provides an alternate wave dispatch, follow it instead of step 3's inline loop; otherwise proceed to step 3.
|
|
563
602
|
|
|
564
603
|
3. **Spawn executor agents:**
|
|
565
604
|
|
|
@@ -572,14 +611,14 @@ increases monotonically across waves. `{status}` is `complete` (success),
|
|
|
572
611
|
For 200k models, this keeps orchestrator context lean (~10-15%).
|
|
573
612
|
For 1M+ models (Opus 4.6, Sonnet 4.6), richer context can be passed directly.
|
|
574
613
|
|
|
575
|
-
**Worktree mode** (`USE_WORKTREES_FOR_PLAN`
|
|
614
|
+
**Worktree mode** (`USE_WORKTREES` and `USE_WORKTREES_FOR_PLAN` not `false`):
|
|
576
615
|
|
|
577
616
|
Before spawning, capture the current HEAD:
|
|
578
617
|
```bash
|
|
579
618
|
EXPECTED_BASE=$(git rev-parse HEAD)
|
|
580
619
|
DISPATCH_TS=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
581
620
|
EXPECTED_BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
|
582
|
-
|
|
621
|
+
if [ "${USE_WORKTREES:-true}" != "false" ] && [ "${USE_WORKTREES_FOR_PLAN:-true}" != "false" ] && [ -z "${WAVE_WORKTREE_MANIFEST:-}" ]; then
|
|
583
622
|
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
623
|
# Persist the dispatch-time orchestrator worktree root so wave-cleanup can pin back to the
|
|
585
624
|
# orchestrator's OWN worktree — NOT `git worktree list`'s first entry (always the main
|
|
@@ -591,6 +630,8 @@ increases monotonically across waves. `{status}` is `complete` (success),
|
|
|
591
630
|
fi
|
|
592
631
|
```
|
|
593
632
|
|
|
633
|
+
**Isolation model.** The block below is the **`harness-worktree`** path. For `orchestrator-worktree` use the dispatch below it; for `none` use sequential mode. Both are detailed in `execute-phase/steps/executor-isolation-dispatch.md`.
|
|
634
|
+
|
|
594
635
|
**Sequential dispatch for parallel execution (waves with 2+ agents):**
|
|
595
636
|
Dispatch each `Agent()` call **one at a time with `run_in_background: true`**. Do NOT
|
|
596
637
|
send all Agent calls in a single message: simultaneous `git worktree add` calls race
|
|
@@ -609,7 +650,10 @@ increases monotonically across waves. `{status}` is `complete` (success),
|
|
|
609
650
|
# When executor_model is "inherit", omit this parameter entirely so
|
|
610
651
|
# Claude Code inherits the orchestrator model automatically.
|
|
611
652
|
model="{executor_model}", # omit this line when executor_model == "inherit"
|
|
612
|
-
isolation
|
|
653
|
+
# The host's OWN declared isolation flag (`harnessFlag` from
|
|
654
|
+
# `dispatch-isolation --json`; see the isolation-dispatch fragment).
|
|
655
|
+
# Emit the declared token — do NOT hardcode a runtime's flag.
|
|
656
|
+
{harnessFlag},
|
|
613
657
|
prompt="
|
|
614
658
|
<objective>
|
|
615
659
|
Execute plan {plan_number} of phase {phase_number}-{phase_name}.
|
|
@@ -693,6 +737,8 @@ increases monotonically across waves. `{status}` is `complete` (success),
|
|
|
693
737
|
|
|
694
738
|
> **ORCHESTRATOR RULE — CODEX RUNTIME**: After calling Agent() above to spawn executor agent(s), stop working on this task immediately. Do not read more files, edit code, or run tests related to this task while the subagent is active. Wait for the subagent to return its result. This prevents duplicate work, conflicting edits, and wasted context. Only resume when the subagent result is available.
|
|
695
739
|
|
|
740
|
+
**Orchestrator-managed worktree dispatch** (`ISOLATION=orchestrator-worktree`): read and execute `execute-phase/steps/executor-isolation-dispatch.md`. GSD creates each worktree (`worktree create`) and spawns the executor into it; the orchestrator performs every git operation. Merge-back and cleanup are the existing manifest-scoped gauntlet, unchanged.
|
|
741
|
+
|
|
696
742
|
**Sequential mode** (`USE_WORKTREES_FOR_PLAN` is `false` — either project-level `USE_WORKTREES=false`, or per-plan submodule intersection forced it false in step 2.5):
|
|
697
743
|
|
|
698
744
|
Omit `isolation="worktree"` from the Agent call. Replace the `<parallel_execution>` block with:
|
|
@@ -974,7 +1020,7 @@ increases monotonically across waves. `{status}` is `complete` (success),
|
|
|
974
1020
|
Note: If `WAVE_FAILURE_COUNT > 1`, strongly recommend "Fix now" — compounding
|
|
975
1021
|
failures across multiple waves become exponentially harder to diagnose.
|
|
976
1022
|
|
|
977
|
-
If "Fix now": diagnose failures (
|
|
1023
|
+
If "Fix now": diagnose failures (import conflicts, missing types,
|
|
978
1024
|
or changed function signatures from parallel plans modifying the same module).
|
|
979
1025
|
Fix, commit as `fix: resolve post-merge conflicts from wave {N}`, re-run tests.
|
|
980
1026
|
|
|
@@ -992,8 +1038,6 @@ increases monotonically across waves. `{status}` is `complete` (success),
|
|
|
992
1038
|
[checkpoint] phase {PHASE_NUMBER} wave {N}/{M} complete, {P}/{Q} plans done ({wave_success}/{wave_plan_count} ok)
|
|
993
1039
|
```
|
|
994
1040
|
|
|
995
|
-
|
|
996
|
-
|
|
997
1041
|
For each SUMMARY.md:
|
|
998
1042
|
- Verify first 2 files from `key-files.created` exist on disk
|
|
999
1043
|
- Check `git log --oneline --all --grep="{phase}-{plan}"` returns ≥1 commit
|
|
@@ -1024,24 +1068,14 @@ increases monotonically across waves. `{status}` is `complete` (success),
|
|
|
1024
1068
|
if [ -n "$RETRY_AFTER" ]; then RETRY_HINT=" Provider hinted retry-after: ${RETRY_AFTER}s"; else RETRY_HINT=""; fi
|
|
1025
1069
|
```
|
|
1026
1070
|
One classifier branch handles sentinels across Claude/Copilot/Codex/Gemini. Reference: `docs/research/provider-rate-limit-signals.md`.
|
|
1027
|
-
**Step 7.1 — `class == "quota-exceeded"`:**
|
|
1028
|
-
Do not offer "retry now". Run step-5 spot-check first; if SUMMARY.md is missing but commits exist, route to safe-resume (`state.verify-against-disk`) instead of immediate redispatch.
|
|
1029
|
-
```text
|
|
1030
|
-
⚠ Plan {plan_id} terminated by provider quota / rate limit
|
|
1031
|
-
Runtime sentinel: {SENTINEL}
|
|
1032
|
-
{RETRY_HINT}
|
|
1033
|
-
Partial commits on worktree branch: {N}
|
|
1034
|
-
SUMMARY.md present: {yes|no}
|
|
1035
|
-
1. Wait for quota reset, then resume (recommended)
|
|
1036
|
-
2. Switch to a different runtime / model and resume
|
|
1037
|
-
3. Abort phase and report partial state
|
|
1038
|
-
```
|
|
1039
|
-
Re-run `/gsd:execute-phase` after quota reset for Option 1.
|
|
1071
|
+
**Step 7.1 — `class == "quota-exceeded"`:** follow the quota-recovery fragment below.
|
|
1040
1072
|
**Step 7.2 — `class == "classify-handoff-bug"`:**
|
|
1041
1073
|
If error contains `classifyHandoffIfNeeded is not defined`, treat as Claude runtime bug. Run the same step-5 spot-checks; PASS => treat as success, FAIL => fall through.
|
|
1042
1074
|
**Step 7.3 — `class == "unknown-failure"`:**
|
|
1043
1075
|
Report failed plan and ask Continue/Stop; continuing may cascade into dependent plan failures.
|
|
1044
1076
|
|
|
1077
|
+
@~/.claude/gsd-core/references/execute-phase-quota-recovery.md
|
|
1078
|
+
|
|
1045
1079
|
@~/.claude/gsd-core/references/execute-phase-between-wave-reset.md
|
|
1046
1080
|
|
|
1047
1081
|
8. **Execute checkpoint plans between waves** — see `<checkpoint_handling>`.
|
|
@@ -1342,7 +1376,7 @@ Create VERIFICATION.md.
|
|
|
1342
1376
|
Read these files before verification:
|
|
1343
1377
|
- {phase_dir}/*-PLAN.md (All plans — understand intent, check must_haves)
|
|
1344
1378
|
- {phase_dir}/*-SUMMARY.md (All summaries — cross-reference claimed vs actual)
|
|
1345
|
-
-
|
|
1379
|
+
- {requirements_path} (Requirement traceability)
|
|
1346
1380
|
${CONTEXT_WINDOW >= 500000 ? `- {phase_dir}/*-CONTEXT.md (User decisions — verify they were honored)
|
|
1347
1381
|
- {phase_dir}/*-RESEARCH.md (Known pitfalls — check for traps)
|
|
1348
1382
|
- Prior VERIFICATION.md files from earlier phases (regression check)
|
|
@@ -1415,7 +1449,7 @@ Commit the file:
|
|
|
1415
1449
|
gsd_run query commit "test({phase_num}): persist human verification items as UAT" --files "{phase_dir}/{phase_num}-UAT.md"
|
|
1416
1450
|
```
|
|
1417
1451
|
|
|
1418
|
-
**Step B: Present to user
|
|
1452
|
+
**Step B: Present to user**:
|
|
1419
1453
|
|
|
1420
1454
|
```
|
|
1421
1455
|
## ◷ Phase {X}: {Name} — Human Verification Needed
|
|
@@ -1437,9 +1471,10 @@ Verify-work will walk you through each item and mark the phase complete when all
|
|
|
1437
1471
|
|
|
1438
1472
|
**If user acknowledges without reporting issues (including "ok", "noted", "ack", "got it", "approved", "done", "yes", "pass", or similar):** Stop. The phase remains pending. No further orchestrator action — wait for the user to run `/gsd:verify-work`.
|
|
1439
1473
|
|
|
1440
|
-
**If user reports issues now
|
|
1474
|
+
**If user reports issues now:** Proceed to gap closure.
|
|
1441
1475
|
|
|
1442
1476
|
**If gaps_found:**
|
|
1477
|
+
@~/.claude/gsd-core/references/execute-phase-requirement-revert.md
|
|
1443
1478
|
```
|
|
1444
1479
|
## ⚠ Phase {X}: {Name} — Gaps Found
|
|
1445
1480
|
|
|
@@ -1480,7 +1515,7 @@ The CLI handles:
|
|
|
1480
1515
|
|
|
1481
1516
|
Extract from result: `next_phase`, `next_phase_name`, `is_last_phase`, `warnings`, `has_warnings`.
|
|
1482
1517
|
|
|
1483
|
-
**If has_warnings is true
|
|
1518
|
+
**If has_warnings is true**:
|
|
1484
1519
|
```
|
|
1485
1520
|
## Phase {X} marked complete with {N} warnings:
|
|
1486
1521
|
|
|
@@ -1520,7 +1555,7 @@ Copy failure must NOT block phase completion.
|
|
|
1520
1555
|
<step name="close_phase_todos">
|
|
1521
1556
|
**Auto-close pending todos tagged for this phase (#2433).**
|
|
1522
1557
|
|
|
1523
|
-
|
|
1558
|
+
After `update_roadmap`, moves todos whose `resolves_phase` matches to `completed/`.
|
|
1524
1559
|
|
|
1525
1560
|
```bash
|
|
1526
1561
|
PHASE_NUM="${PHASE_NUMBER}"
|
|
@@ -1528,25 +1563,32 @@ PENDING_DIR=".planning/todos/pending"
|
|
|
1528
1563
|
COMPLETED_DIR=".planning/todos/completed"
|
|
1529
1564
|
mkdir -p "$COMPLETED_DIR"
|
|
1530
1565
|
|
|
1566
|
+
# "05"=="5" (#2576).
|
|
1567
|
+
normalize_phase_num() {
|
|
1568
|
+
local p="${1//\"/}"; printf '%s' "$p" | sed 's/^0*\([0-9]\)/\1/'
|
|
1569
|
+
}
|
|
1570
|
+
PHASE_NUM_NORM=$(normalize_phase_num "$PHASE_NUM")
|
|
1571
|
+
|
|
1531
1572
|
CLOSED=()
|
|
1532
1573
|
for TODO_FILE in "$PENDING_DIR"/*.md; do
|
|
1533
1574
|
[ -f "$TODO_FILE" ] || continue
|
|
1534
|
-
#
|
|
1575
|
+
# resolves_phase from first frontmatter block
|
|
1535
1576
|
RP=$(awk '/^---/{c++;next} c==1 && /^resolves_phase:/{print $2;exit} c==2{exit}' "$TODO_FILE" 2>/dev/null || true)
|
|
1536
|
-
|
|
1577
|
+
RP_NORM=$(normalize_phase_num "$RP")
|
|
1578
|
+
if [ -n "$RP_NORM" ] && [ "$RP_NORM" = "$PHASE_NUM_NORM" ]; then
|
|
1537
1579
|
mv "$TODO_FILE" "$COMPLETED_DIR/"
|
|
1538
1580
|
CLOSED+=("$(basename "$TODO_FILE")")
|
|
1539
1581
|
fi
|
|
1540
1582
|
done
|
|
1541
1583
|
|
|
1542
1584
|
if [ ${#CLOSED[@]} -gt 0 ]; then
|
|
1543
|
-
gsd_run query commit "docs(phase-${PHASE_NUMBER}):
|
|
1585
|
+
gsd_run query commit "docs(phase-${PHASE_NUMBER}): close ${#CLOSED[@]} resolved todo(s)" --files .planning/todos/completed/ .planning/todos/pending/ .planning/STATE.md|| true
|
|
1544
1586
|
echo "◆ Closed ${#CLOSED[@]} todo(s) resolved by Phase ${PHASE_NUMBER}:"
|
|
1545
1587
|
for f in "${CLOSED[@]}"; do echo " ✓ $f"; done
|
|
1546
1588
|
fi
|
|
1547
1589
|
```
|
|
1548
1590
|
|
|
1549
|
-
**
|
|
1591
|
+
**No matches:** skip silently (always additive, non-blocking).
|
|
1550
1592
|
</step>
|
|
1551
1593
|
|
|
1552
1594
|
<step name="update_project_md">
|
|
@@ -1572,88 +1614,7 @@ gsd_run query commit "docs(phase-{X}): evolve PROJECT.md after phase completion"
|
|
|
1572
1614
|
</step>
|
|
1573
1615
|
|
|
1574
1616
|
<step name="offer_next">
|
|
1575
|
-
|
|
1576
|
-
**Exception:** If `gaps_found`, the `verify_phase_goal` step already presents the gap-closure path (`/gsd:plan-phase {X} --gaps`). No additional routing needed — skip auto-advance.
|
|
1577
|
-
|
|
1578
|
-
**No-transition check (spawned by auto-advance chain):**
|
|
1579
|
-
|
|
1580
|
-
Parse `--no-transition` flag from $ARGUMENTS.
|
|
1581
|
-
|
|
1582
|
-
**If `--no-transition` flag present:**
|
|
1583
|
-
|
|
1584
|
-
Execute-phase was spawned by plan-phase's auto-advance. Do NOT run transition.md.
|
|
1585
|
-
After verification passes and roadmap is updated, return completion status to parent:
|
|
1586
|
-
|
|
1587
|
-
```
|
|
1588
|
-
## PHASE COMPLETE
|
|
1589
|
-
|
|
1590
|
-
Phase: ${PHASE_NUMBER} - ${PHASE_NAME}
|
|
1591
|
-
Plans: ${completed_count}/${total_count}
|
|
1592
|
-
Verification: {Passed | Gaps Found}
|
|
1593
|
-
|
|
1594
|
-
[Include aggregate_results output]
|
|
1595
|
-
```
|
|
1596
|
-
|
|
1597
|
-
STOP. Do not proceed to auto-advance or transition.
|
|
1598
|
-
|
|
1599
|
-
**If `--no-transition` flag is NOT present:**
|
|
1600
|
-
|
|
1601
|
-
**Auto-advance detection:**
|
|
1602
|
-
|
|
1603
|
-
1. Parse `--auto` flag from $ARGUMENTS
|
|
1604
|
-
2. Read consolidated auto-mode (`active` = chain flag OR user preference; chain flag already synced in init step):
|
|
1605
|
-
```bash
|
|
1606
|
-
AUTO_MODE=$(gsd_run query check auto-mode --pick active 2>/dev/null || echo "false")
|
|
1607
|
-
```
|
|
1608
|
-
|
|
1609
|
-
**If `--auto` flag present OR `AUTO_MODE` is true (AND verification passed with no gaps):**
|
|
1610
|
-
|
|
1611
|
-
```
|
|
1612
|
-
╔══════════════════════════════════════════╗
|
|
1613
|
-
║ AUTO-ADVANCING → TRANSITION ║
|
|
1614
|
-
║ Phase {X} verified, continuing chain ║
|
|
1615
|
-
╚══════════════════════════════════════════╝
|
|
1616
|
-
```
|
|
1617
|
-
|
|
1618
|
-
Execute the transition workflow inline (do NOT use Agent — orchestrator context is ~10-15%, transition needs phase completion data already in context):
|
|
1619
|
-
|
|
1620
|
-
Read and follow `~/.claude/gsd-core/workflows/transition.md`, passing through the `--auto` flag so it propagates to the next phase invocation.
|
|
1621
|
-
|
|
1622
|
-
**If neither `--auto` nor `AUTO_MODE` is true:**
|
|
1623
|
-
|
|
1624
|
-
**STOP. Do not auto-advance. Do not execute transition. Do not plan next phase. Present options to the user and wait.**
|
|
1625
|
-
|
|
1626
|
-
**IMPORTANT: There is NO `/gsd-transition` command. Never suggest it. The transition workflow is internal only.**
|
|
1627
|
-
|
|
1628
|
-
Check whether CONTEXT.md already exists for the next phase:
|
|
1629
|
-
|
|
1630
|
-
```bash
|
|
1631
|
-
ls .planning/phases/*{next}*/{next}-CONTEXT.md 2>/dev/null || echo "no-context"
|
|
1632
|
-
```
|
|
1633
|
-
|
|
1634
|
-
If CONTEXT.md does **not** exist for the next phase, present:
|
|
1635
|
-
|
|
1636
|
-
```
|
|
1637
|
-
## ✓ Phase {X}: {Name} Complete
|
|
1638
|
-
|
|
1639
|
-
/gsd:progress ${GSD_WS} — see updated roadmap
|
|
1640
|
-
/gsd:discuss-phase {next} ${GSD_WS} — start here: discuss next phase before planning ← recommended
|
|
1641
|
-
/gsd:plan-phase {next} ${GSD_WS} — plan next phase (skip discuss)
|
|
1642
|
-
/gsd:execute-phase {next} ${GSD_WS} — execute next phase (skip discuss and plan)
|
|
1643
|
-
```
|
|
1644
|
-
|
|
1645
|
-
If CONTEXT.md **exists** for the next phase, present:
|
|
1646
|
-
|
|
1647
|
-
```
|
|
1648
|
-
## ✓ Phase {X}: {Name} Complete
|
|
1649
|
-
|
|
1650
|
-
/gsd:progress ${GSD_WS} — see updated roadmap
|
|
1651
|
-
/gsd:plan-phase {next} ${GSD_WS} — start here: plan next phase (CONTEXT.md already present) ← recommended
|
|
1652
|
-
/gsd:discuss-phase {next} ${GSD_WS} — re-discuss next phase
|
|
1653
|
-
/gsd:execute-phase {next} ${GSD_WS} — execute next phase (skip planning)
|
|
1654
|
-
```
|
|
1655
|
-
|
|
1656
|
-
Only suggest the commands listed above. Do not invent or hallucinate command names.
|
|
1617
|
+
@~/.claude/gsd-core/references/offer-next.md
|
|
1657
1618
|
</step>
|
|
1658
1619
|
|
|
1659
1620
|
</process>
|
|
@@ -1663,7 +1624,7 @@ Orchestrator: ~10-15% context for 200k windows, can use more for 1M+ windows.
|
|
|
1663
1624
|
Subagents: fresh context each (200k-1M depending on model). No polling (Agent blocks). No context bleed.
|
|
1664
1625
|
|
|
1665
1626
|
For 1M+ context models, consider:
|
|
1666
|
-
- Passing richer context (code snippets, dependency outputs) directly to executors instead of
|
|
1627
|
+
- Passing richer context (code snippets, dependency outputs) directly to executors instead of file paths
|
|
1667
1628
|
- Running small phases (≤3 plans, no dependencies) inline without subagent spawning overhead
|
|
1668
1629
|
- Relaxing /clear recommendations — context rot onset is much further out with 5x window
|
|
1669
1630
|
</context_efficiency>
|
|
@@ -48,7 +48,9 @@ INIT=$(gsd_run query init.execute-phase "${PHASE}")
|
|
|
48
48
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
-
Extract from init JSON: `executor_model`, `commit_docs`, `sub_repos`, `phase_dir`, `phase_number`, `plans`, `summaries`, `incomplete_plans`, `state_path`, `config_path`.
|
|
51
|
+
Extract from init JSON: `executor_model`, `commit_docs`, `sub_repos`, `phase_dir`, `phase_number`, `plans`, `summaries`, `incomplete_plans`, `state_path`, `config_path`, `response_language`.
|
|
52
|
+
|
|
53
|
+
**If `response_language` is set:** All user-facing questions, prompts, and explanations in this workflow MUST be presented in `{response_language}`. Technical terms, code, file paths, and subagent prompts stay in English — only user-facing output is translated.
|
|
52
54
|
|
|
53
55
|
If `.planning/` missing: error.
|
|
54
56
|
</step>
|
|
@@ -107,7 +109,11 @@ Otherwise: Apply checkpoint-based routing below.
|
|
|
107
109
|
| Verify-only | B (segmented) | Segments between checkpoints. After none/human-verify → SUBAGENT. After decision/human-action → MAIN |
|
|
108
110
|
| Decision | C (main) | Execute entirely in main context |
|
|
109
111
|
|
|
110
|
-
|
|
112
|
+
<!-- #2508 runtime-aware-dispatch -->
|
|
113
|
+
|
|
114
|
+
> **Runtime-aware dispatch (#2508 Phase 4).** GSD workflows dispatch specialized subagents by role. Before dispatching on a built-in-only runtime (kimi-code — three built-ins only), resolve the role to a built-in via `gsd_run query resolve-dispatch-type --requested <role> --raw`. On named-dispatch runtimes (Claude/OpenCode/…) the role is returned unchanged; on kimi-code it maps to `coder`/`explore`/`plan` by role-suffix. The persona rides `${AGENT_SKILLS_<ROLE>}` (Phase 3) regardless. See @gsd-core/references/runtime-aware-dispatch.md.
|
|
115
|
+
|
|
116
|
+
**Pattern A:** init_agent_tracking → capture `EXPECTED_BASE=$(git rev-parse HEAD)` → print `Spawning executor agent (runs in a subagent — no output until it returns, ~1–5 min; expected, not a freeze)` → spawn Agent(subagent_type="gsd-executor", model=executor_model) with prompt: execute plan at [path], autonomous, all tasks + SUMMARY + commit, follow deviation/auth rules, report: plan name, tasks, SUMMARY path, commit hash → track agent_id → wait → update tracking → report. **Include `isolation="worktree"` only if `workflow.use_worktrees` is not `false`** (read via `config-get workflow.use_worktrees`). **When using `isolation="worktree"`, embed the `<worktree_branch_check>` block from `gsd-core/references/worktree-branch-check.md` into the prompt, substituting `{EXPECTED_BASE}` with the captured base SHA.** That guard is **verify-only and fail-closed** (#48): it asserts a per-agent `agent-*` / `worktree-agent-*` branch and the exact base, forbids `git update-ref` self-recovery (#2924), and on any mismatch prints `FATAL:` and `exit 42` so the orchestrator can recover — the sub-agent never rewrites a worktree it did not create. This supersedes the former self-recovery (#2015), whose destructive base rewrite could fail silently under a deny rule; the base-drift it addressed affects all platforms, and base correction is now the orchestrator's responsibility.
|
|
111
117
|
|
|
112
118
|
**Pattern B:** Execute segment-by-segment. Autonomous segments: spawn subagent for assigned tasks only (no SUMMARY/commit). Checkpoints: main context. After all segments: aggregate, create SUMMARY, commit. See segment_execution.
|
|
113
119
|
|
|
@@ -157,9 +163,6 @@ Pattern B only (verify-only checkpoints). Skip for A/C.
|
|
|
157
163
|
|
|
158
164
|
**Known Claude Code bug (classifyHandoffIfNeeded):** If any segment agent reports "failed" with `classifyHandoffIfNeeded is not defined`, this is a Claude Code runtime bug — not a real failure. Run spot-checks; if they pass, treat as successful.
|
|
159
165
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
166
|
</step>
|
|
164
167
|
|
|
165
168
|
<step name="load_prompt">
|
|
@@ -189,6 +192,7 @@ Deviations are normal — handle via rules below.
|
|
|
189
192
|
3. Per task:
|
|
190
193
|
- **MANDATORY read_first gate:** If the task has a `<read_first>` field, you MUST read every listed file BEFORE making any edits. This is not optional. Do not skip files because you "already know" what's in them — read them. The read_first files establish ground truth for the task.
|
|
191
194
|
- `type="auto"`: if `tdd="true"` → TDD execution. Implement with deviation rules + auth gates. Verify done criteria. Commit (see task_commit). Track hash for Summary.
|
|
195
|
+
- `type="tracer"`: execute like `type="auto"` (production-quality, real `<verify>`, commit), then run the tracer feedback gate BEFORE any expansion task — an early integration checkpoint. Auto mode active (`AUTO_CHAIN` or `AUTO_CFG`): re-run the tracer `<verify>`; on failure HALT and surface (deviation) — do NOT start expansion tasks. Interactive: STOP → return a `checkpoint:human-verify` for the tracer via checkpoint_protocol before expansion.
|
|
192
196
|
- `type="checkpoint:*"`: STOP → checkpoint_protocol → wait for user → continue only after confirmation.
|
|
193
197
|
- **HARD GATE — acceptance_criteria verification:** After completing each task, if it has `<acceptance_criteria>`, you MUST run a verification loop before proceeding:
|
|
194
198
|
1. For each criterion: execute the grep, file check, or CLI command that proves it passes
|
|
@@ -469,13 +473,21 @@ Counts PLAN vs SUMMARY files on disk. Updates progress table row with correct co
|
|
|
469
473
|
</step>
|
|
470
474
|
|
|
471
475
|
<step name="update_requirements">
|
|
472
|
-
Mark completed requirements from the PLAN.md frontmatter `requirements:` field
|
|
476
|
+
Mark completed requirements from the PLAN.md frontmatter `requirements:` field.
|
|
477
|
+
|
|
478
|
+
Extract requirement IDs from the plan's frontmatter (e.g., `requirements: [AUTH-01, AUTH-02]`) into `REQ_IDS`. If no requirements field, skip this step.
|
|
479
|
+
|
|
480
|
+
**Shared-ID gate (#2388):** a requirement ID declared by more than one plan in this phase must not read `Complete` until every plan declaring it has finished (produced a `*-SUMMARY.md`) — otherwise the first plan to finish flips it `Complete` while its sibling plans are still running, before phase verification ever gets a chance to catch a real gap. Compute the ready subset first, then mark only those:
|
|
473
481
|
|
|
474
482
|
```bash
|
|
475
|
-
gsd_run query requirements.
|
|
483
|
+
READY=$(gsd_run query requirements.ready-ids "${PLAN_PATH}" ${REQ_IDS} --raw)
|
|
484
|
+
READY_IDS=$(printf '%s' "$READY" | jq -r '.ready[]' 2>/dev/null | tr '\n' ' ')
|
|
485
|
+
if [ -n "$(printf '%s' "$READY_IDS" | tr -d '[:space:]')" ]; then
|
|
486
|
+
gsd_run query requirements.mark-complete ${READY_IDS}
|
|
487
|
+
fi
|
|
476
488
|
```
|
|
477
489
|
|
|
478
|
-
|
|
490
|
+
`requirements.ready-ids` is read-only: it scans sibling `*-PLAN.md` files in this plan's phase directory and blocks an ID only when a sibling ALSO declares it and that sibling has no `*-SUMMARY.md` yet. An ID no sibling declares is always ready (single-plan requirements mark immediately, no added latency). A blocked ID is re-evaluated the next time any plan in this phase finishes its own `update_requirements` step, and becomes ready once the LAST declaring plan's SUMMARY exists.
|
|
479
491
|
</step>
|
|
480
492
|
|
|
481
493
|
<step name="git_commit_metadata">
|
|
@@ -60,6 +60,10 @@ This would take ~30 seconds and might surface useful context.
|
|
|
60
60
|
|
|
61
61
|
If yes, spawn a research agent:
|
|
62
62
|
|
|
63
|
+
<!-- #2508 runtime-aware-dispatch -->
|
|
64
|
+
|
|
65
|
+
> **Runtime-aware dispatch (#2508 Phase 4).** GSD workflows dispatch specialized subagents by role. Before dispatching on a built-in-only runtime (kimi-code — three built-ins only), resolve the role to a built-in via `gsd_run query resolve-dispatch-type --requested <role> --raw`. On named-dispatch runtimes (Claude/OpenCode/…) the role is returned unchanged; on kimi-code it maps to `coder`/`explore`/`plan` by role-suffix. The persona rides `${AGENT_SKILLS_<ROLE>}` (Phase 3) regardless. See @gsd-core/references/runtime-aware-dispatch.md.
|
|
66
|
+
|
|
63
67
|
Print: `◆ Spawning explorer... (runs in a subagent — no output until it returns, ~1–5 min; expected, not a freeze)`
|
|
64
68
|
```
|
|
65
69
|
Agent(
|
|
@@ -186,6 +186,27 @@ The body follows this structure:
|
|
|
186
186
|
```
|
|
187
187
|
</step>
|
|
188
188
|
|
|
189
|
+
<step name="calibrate_estimates">
|
|
190
|
+
Rebuild the estimate-vs-actual calibration from every completed phase (#2632, ADR-2629).
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
gsd_run query estimate-calibrate
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
This pairs each phase's PLAN `estimate` with its SUMMARY `actuals`, writes
|
|
197
|
+
`.planning/estimation-calibration.json`, and reports the resulting correction factor.
|
|
198
|
+
The planner reads it on the next `/gsd:plan-phase`, so estimates improve for THIS project
|
|
199
|
+
over time.
|
|
200
|
+
|
|
201
|
+
Report the returned `factor`, `sample_count`, and `confidence` in the summary output.
|
|
202
|
+
`applied: false` means fewer than 3 phases carry both an estimate and actuals — that is
|
|
203
|
+
expected early and is not an error. The verb rebuilds from scratch each run, so it is safe
|
|
204
|
+
to re-run and never accumulates duplicates.
|
|
205
|
+
|
|
206
|
+
Phases missing either side are skipped rather than guessed: a fabricated sample would
|
|
207
|
+
steer every future estimate.
|
|
208
|
+
</step>
|
|
209
|
+
|
|
189
210
|
<step name="update_state">
|
|
190
211
|
Update STATE.md to reflect the learning extraction:
|
|
191
212
|
|
|
@@ -22,11 +22,14 @@ Read from project config (`config.json`):
|
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
24
|
_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 "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CLAUDE_CONFIG_DIR:-$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
|
|
25
|
+
RESPONSE_LANGUAGE=$(gsd_run query config-get response_language --default "" 2>/dev/null || echo "")
|
|
25
26
|
GRADUATION_ENABLED=$(gsd_run query config-get features.graduation 2>/dev/null || echo "true")
|
|
26
27
|
GRADUATION_WINDOW=$(gsd_run query config-get features.graduation_window 2>/dev/null || echo "5")
|
|
27
28
|
GRADUATION_THRESHOLD=$(gsd_run query config-get features.graduation_threshold 2>/dev/null || echo "3")
|
|
28
29
|
```
|
|
29
30
|
|
|
31
|
+
**If `response_language` is set:** All user-facing questions, prompts, and explanations in this workflow MUST be presented in `{response_language}`. Technical terms, code, file paths, and subagent prompts stay in English — only user-facing output is translated.
|
|
32
|
+
|
|
30
33
|
**Skip silently (print nothing) if:**
|
|
31
34
|
- `features.graduation` is `false`
|
|
32
35
|
- Fewer than `graduation_threshold` completed prior phases exist (not enough data)
|