* feat: make model profiles runtime-aware for Codex/non-Claude runtimes (closes#2517)
Adds an optional top-level `runtime` config key plus a
`model_profile_overrides[runtime][tier]` map. When `runtime` is set,
profile tiers (opus/sonnet/haiku) resolve to runtime-native model IDs
(and reasoning_effort where supported) instead of bare Claude aliases.
Codex defaults from the spec:
opus -> gpt-5.4 reasoning_effort: xhigh
sonnet -> gpt-5.3-codex reasoning_effort: medium
haiku -> gpt-5.4-mini reasoning_effort: medium
Claude defaults mirror MODEL_ALIAS_MAP. Unknown runtimes fall back to
the Claude-alias safe default rather than emit IDs the runtime cannot
accept. reasoning_effort is only emitted into Codex install paths;
never returned from resolveModelInternal and never written to Claude
agent frontmatter.
Backwards compatible: any user without `runtime` set sees identical
behavior — the new branch is gated on `config.runtime != null`.
Precedence (highest to lowest):
1. per-agent model_overrides
2. runtime-aware tier resolution (when `runtime` is set)
3. resolve_model_ids: "omit"
4. Claude-native default
5. inherit (literal passthrough)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(#2517): address adversarial review of #2609 (findings 1-16)
Addresses all 16 findings from the adversarial review of PR #2609.
Each finding is enumerated below with its resolution.
CRITICAL
- F1: readGsdRuntimeProfileResolver(targetDir) now probes per-project
.planning/config.json AND ~/.gsd/defaults.json with per-project winning,
so the PR's headline claim ("set runtime in project config and Codex
TOML emit picks it up") actually holds end-to-end.
- F2: resolveTierEntry field-merges user overrides with built-in defaults.
The CONFIGURATION.md string-shorthand example
`{ codex: { opus: "gpt-5-pro" } }`
now keeps reasoning_effort from the built-in entry. Partial-object
overrides like `{ opus: { reasoning_effort: 'low' } }` keep the
built-in model. Both paths regression-tested.
MAJOR
- F3: resolveReasoningEffortInternal gates strictly on the
RUNTIMES_WITH_REASONING_EFFORT allowlist regardless of override
presence. Override + unknown-runtime no longer leaks reasoning_effort.
- F4: runtime:"claude" is now a no-op for resolution (it is the implicit
default). It no longer hijacks resolve_model_ids:"omit". Existing
tests for `runtime:"claude"` returning Claude IDs were rewritten to
reflect the no-op semantics; new test asserts the omit case returns "".
- F5: _readGsdConfigFile in install.js writes a stderr warning on JSON
parse failure instead of silently returning null. Read failure and
parse failure are warned separately. Library require is hoisted to top
of install.js so it is not co-mingled with config-read failure modes.
- F6: install.js requires for core.cjs / model-profiles.cjs are hoisted
to the top of the file with __dirname-based absolute paths so global
npm install works regardless of cwd. Test asserts both lib paths exist
relative to install.js __dirname.
- F7: docs/CONFIGURATION.md `runtime` row no longer lists `opencode` as
a valid runtime — install-path emission for non-Codex runtimes is
explicitly out of scope per #2517 / #2612, and the doc now points at
#2612 for the follow-on work. resolveModelInternal still accepts any
runtime string (back-compat) and falls back safely for unknown values.
- F8: Tests now isolate HOME (and GSD_HOME) to a per-test tmpdir so the
developer's real ~/.gsd/defaults.json cannot bleed into assertions.
Same pattern CodeRabbit caught on PRs #2603 / #2604.
- F9: `runtime` and `model_profile_overrides` documented as flat-only
in core.cjs comments — not routed through `get()` because they are
top-level keys per docs/CONFIGURATION.md and introducing nested
resolution for two new keys was not worth the edge-case surface.
- F10/F13: loadConfig now invokes _warnUnknownProfileOverrides on the
raw parsed config so direct .planning/config.json edits surface
unknown runtime values (e.g. typo `runtime: "codx"`) and unknown
tier values (e.g. `model_profile_overrides.codex.banana`) at read
time. Warnings only — preserves back-compat for runtimes added
later. Per-process warning cache prevents log spam across repeated
loadConfig calls.
MINOR / NIT
- F11: Removed dead `tier || 'sonnet'` defensive shortcut. The local
is now `const alias = tier;` with a comment explaining why `tier`
is guaranteed truthy at that point (every MODEL_PROFILES entry
defines `balanced`, the fallback profile).
- F12: Extracted resolveTierEntry() in core.cjs as the single source
of truth for runtime-aware tier resolution. core.cjs and bin/install.js
both consume it — no duplicated lookup logic between the two files.
- F14: Added regression tests for findings #1, #2, #3, #4, #6, #10, #13
in tests/issue-2517-runtime-aware-profiles.test.cjs. Each must-fix
path has a corresponding test that fails against the pre-fix code
and passes against the post-fix code.
- F15: docs/CONFIGURATION.md `model_profile` row cross-references
#1713 / #1806 next to the `adaptive` enum value.
- F16: RUNTIME_PROFILE_MAP remains in core.cjs as the single source of
truth; install.js imports it through the exported resolveTierEntry
helper rather than carrying its own copy. Doc files (CONFIGURATION.md,
USER-GUIDE.md, settings.md) intentionally still embed the IDs as text
— code comment in core.cjs flags that those doc files must be updated
whenever the constant changes.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(workflows): extract discuss-phase modes/templates/advisor for progressive disclosure (closes#2551)
Splits 1,347-line workflows/discuss-phase.md into a 495-line dispatcher plus
per-mode files in workflows/discuss-phase/modes/ and templates in
workflows/discuss-phase/templates/. Mirrors the progressive-disclosure
pattern that #2361 enforced for agents.
- Per-mode files: power, all, auto, chain, text, batch, analyze, default, advisor
- Templates lazy-loaded at the step that produces the artifact (CONTEXT.md
template at write_context, DISCUSSION-LOG.md template at git_commit,
checkpoint.json schema when checkpointing)
- Advisor mode gated behind `[ -f $HOME/.claude/get-shit-done/USER-PROFILE.md ]`
— inverse of #2174's --advisor flag (don't pay the cost when unused)
- scout_codebase phase-type→map selection table extracted to
references/scout-codebase.md
- New tests/workflow-size-budget.test.cjs enforces tiered budgets across
all workflows/*.md (XL=1700 / LARGE=1500 / DEFAULT=1000) plus the
explicit <500 ceiling for discuss-phase.md per #2551
- Existing tests updated to read from the new file locations after the
split (functional equivalence preserved — content moved, not removed)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(#2607): align modes/auto.md check_existing with parent (Update it, not Skip)
CodeRabbit flagged drift between the parent step (which auto-selects "Update
it") and modes/auto.md (which documented "Skip"). The pre-refactor file had
both — line 182 said "Skip" in the overview, line 250 said "Update it" in the
actual step. The step is authoritative. Fix the new mode file to match.
Refs: PR #2607 review comment 3127783430
* test(#2607): harden discuss-phase regression tests after #2551 split
CodeRabbit identified four test smells where the split weakened coverage:
- workflow-size-budget: assertion was unreachable (entered if-block on match,
then asserted occurrences === 0 — always failed). Now unconditional.
- bug-2549-2550-2552: bounded-read assertion checked concatenated source, so
src.includes('3') was satisfied by unrelated content in scout-codebase.md
(e.g., "3-5 most relevant files"). Now reads parent only with a stricter
regex. Also asserts SCOUT_REF exists.
- chain-flag-plan-phase: filter(existsSync) silently skipped a missing
modes/chain.md. Now fails loudly via explicit asserts.
- discuss-checkpoint: same silent-filter pattern across three sources. Now
asserts each required path before reading.
Refs: PR #2607 review comments 3127783457, 3127783452, plus nitpicks for
chain-flag-plan-phase.test.cjs:21-24 and discuss-checkpoint.test.cjs:22-27
* docs(#2607): fix INVENTORY count, context.md placeholders, scout grep portability
- INVENTORY.md: subdirectory note said "50 top-level references" but the
section header now says 51. Updated to 51.
- templates/context.md: footer hardcoded XX-name instead of declared
placeholders [X]/[Name], which would leak sample text into generated
CONTEXT.md files. Now uses the declared placeholders.
- references/scout-codebase.md: no-maps fallback used grep -rl with
"\\|" alternation (GNU grep only — silent on BSD/macOS grep). Switched
to grep -rlE with extended regex for portability.
Refs: PR #2607 review comments 3127783404, 3127783448, plus nitpick for
scout-codebase.md:32-40
* docs(#2607): label fenced examples + clarify overlay/advisor precedence
- analyze.md / text.md / default.md: add language tags (markdown/text) to
fenced example blocks to silence markdownlint MD040 warnings flagged by
CodeRabbit (one fence in analyze.md, two in text.md, five in default.md).
- discuss-phase.md: document overlay stacking rules in discuss_areas — fixed
outer→inner order --analyze → --batch → --text, with a pointer to each
overlay file for mode-specific precedence.
- advisor.md: add tie-breaker rules for NON_TECHNICAL_OWNER signals — explicit
technical_background overrides inferred signals; otherwise OR-aggregate;
contradictory explanation_depth values resolve by most-recent-wins.
Refs: PR #2607 review comments 3127783415, 3127783437, plus nitpicks for
default.md:24, discuss-phase.md:345-365, and advisor.md:51-56
* fix(#2607): extract codebase_drift_gate body to keep execute-phase under XL budget
PR #2605 added 80 lines to execute-phase.md (1622 -> 1702), pushing it over
the XL_BUDGET=1700 line cap enforced by tests/workflow-size-budget.test.cjs
(introduced by this PR). Per the test's own remediation hint and #2551's
progressive-disclosure pattern, extract the codebase_drift_gate step body to
get-shit-done/workflows/execute-phase/steps/codebase-drift-gate.md and leave
a brief pointer in the workflow. execute-phase.md is now 1633 lines.
Budget is NOT relaxed; the offending workflow is tightened.
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(#2529): /gsd-settings-integrations — third-party integrations command
Adds /gsd-settings-integrations for configuring API keys, code-review CLI
routing, and agent-skill injection. Distinct from /gsd-settings (workflow
toggles) because these are connectivity, not pipeline shape.
Three sections:
- Search Integrations: brave_search / firecrawl / exa_search API keys,
plus search_gitignored toggle.
- Code Review CLI Routing: review.models.{claude,codex,gemini,opencode}
shell-command strings.
- Agent Skills Injection: agent_skills.<agent-type> free-text input,
validated against [a-zA-Z0-9_-]+.
Security:
- New secrets.cjs module with ****<last-4> masking convention.
- cmdConfigSet now masks value/previousValue in CLI output for secret keys.
- Plaintext is written only to .planning/config.json; never echoed to
stdout/stderr, never written to audit/log files by this flow.
- Slug validators reject path separators, whitespace, shell metacharacters.
Tests (tests/settings-integrations.test.cjs — 25 cases):
- Artifact presence / frontmatter.
- Field round-trips via gsd-tools config-set for all four search keys,
review.models.<cli>, agent_skills.<agent-type>.
- Config-merge safety: unrelated keys preserved across writes.
- Masking: config-set output never contains plaintext sentinel.
- Logging containment: plaintext secret sentinel appears only in
config.json under .planning/, nowhere else on disk.
- Negative: path-traversal, shell-metachar, and empty-slug rejected.
- /gsd:settings workflow mentions /gsd:settings-integrations.
Docs:
- docs/COMMANDS.md: new command entry with security note.
- docs/CONFIGURATION.md: integration settings section (keys, routing,
skills injection) with masking documentation.
- docs/CLI-TOOLS.md: reviewer CLI routing and secret-handling sections.
- docs/INVENTORY.md + INVENTORY-MANIFEST.json regenerated.
Closes#2529
* fix(#2529): mask secrets in config-get; address CodeRabbit review
cmdConfigGet was emitting plaintext for brave_search/firecrawl/exa_search.
Apply the same isSecretKey/maskSecret treatment used by config-set so the
CLI surface never echoes raw API keys; plaintext still lives only in
config.json on disk.
Also addresses CodeRabbit review items in the same PR area:
- #3127146188: config-get plaintext leak (root fix above)
- #3127146211: rename test sentinels to concat-built markers so secret
scanners stop flagging the test file. Behavior preserved.
- #3127146207: add explicit 'text' language to fenced code blocks (MD040).
- nitpick: unify masked-value wording in read_current legend
('****<last-4>' instead of '**** already set').
- nitpick: extend round-trip test to cover search_gitignored toggle.
New regression test 'config-get masks secrets and never echoes plaintext'
verifies the fix for all three secret keys.
* docs(#2529): bump INVENTORY counts post-rebase (commands 84→85, workflows 82→83)
* fix(test): bump CLI Modules count 27→28 after rebase onto main (CI #24811455435)
PR #2604 was rebased onto main before #2605 (drift.cjs) merged. The
pull_request CI runs against the merge ref (refs/pull/2604/merge),
which now contains 28 .cjs files in get-shit-done/bin/lib/, but
docs/INVENTORY.md headline still said "(27 shipped)".
inventory-counts.test.cjs failed with:
AssertionError: docs/INVENTORY.md "CLI Modules (27 shipped)" disagrees
with get-shit-done/bin/lib/ file count (28)
Rebased branch onto current origin/main (picks up drift.cjs row, which
was already added by #2605) and bumped the headline to 28.
Full suite: 5200/5200 pass.
* feat: auto-remap codebase after significant phase execution (#2003)
Adds a post-phase structural drift detector that compares the committed tree
against `.planning/codebase/STRUCTURE.md` and either warns or auto-remaps
the affected subtrees when drift exceeds a configurable threshold.
## Summary
- New `bin/lib/drift.cjs` — pure detector covering four drift categories:
new directories outside mapped paths, new barrel exports at
`(packages|apps)/*/src/index.*`, new migration files, and new route
modules. Prioritizes the most-specific category per file.
- New `verify codebase-drift` CLI subcommand + SDK handler, registered as
`gsd-sdk query verify.codebase-drift`.
- New `codebase_drift_gate` step in `execute-phase` between
`schema_drift_gate` and `verify_phase_goal`. Non-blocking by contract —
any error logs and the phase continues.
- Two new config keys: `workflow.drift_threshold` (int, default 3) and
`workflow.drift_action` (`warn` | `auto-remap`, default `warn`), with
enum/integer validation in `config-set`.
- `gsd-codebase-mapper` learns an optional `--paths <p1,p2,...>` scope hint
for incremental remapping; agent/workflow docs updated.
- `last_mapped_commit` lives in YAML frontmatter on each
`.planning/codebase/*.md` file; `readMappedCommit`/`writeMappedCommit`
round-trip helpers ship in `drift.cjs`.
## Tests
- 55 new tests in `tests/drift-detection.test.cjs` covering:
classification, threshold gating at 2/3/4 elements, warn vs. auto-remap
routing, affected-path scoping, `--paths` sanitization (traversal,
absolute, shell metacharacter rejection), frontmatter round-trip,
defensive paths (missing STRUCTURE.md, malformed input, non-git repos),
CLI JSON output, and documentation parity.
- Full suite: 5044 pass / 0 fail.
## Documentation
- `docs/CONFIGURATION.md` — rows for both new keys.
- `docs/ARCHITECTURE.md` — section on the post-execute drift gate.
- `docs/AGENTS.md` — `--paths` flag on `gsd-codebase-mapper`.
- `docs/USER-GUIDE.md` — user-facing behavior note + toggle commands.
- `docs/FEATURES.md` — new 27a section with REQ-DRIFT-01..06.
- `docs/INVENTORY.md` + `docs/INVENTORY-MANIFEST.json` — drift.cjs listed.
- `get-shit-done/workflows/execute-phase.md` — `codebase_drift_gate` step.
- `get-shit-done/workflows/map-codebase.md` — `parse_paths_flag` step.
- `agents/gsd-codebase-mapper.md` — `--paths` directive under parse_focus.
## Design decisions
- **Frontmatter over sidecar JSON** for `last_mapped_commit`: keeps the
baseline attached to the file, survives git moves, survives per-doc
regeneration, no extra file lifecycle.
- **Substring match against STRUCTURE.md** for `isPathMapped`: the map is
free-form markdown, not a structured manifest; any mention of a path
prefix counts as "mapped territory". Cheap, no parser, zero false
negatives on reasonable maps.
- **Category priority migration > route > barrel > new_dir** so a file
matching multiple rules counts exactly once at the most specific level.
- **Empty-tree SHA fallback** (`4b825dc6…`) when `last_mapped_commit` is
absent — semantically correct (no baseline means everything is drift)
and deterministic across repos.
- **Four layers of non-blocking** — detector try/catch, CLI try/catch, SDK
handler try/catch, and workflow `|| echo` shell fallback. Any single
layer failing still returns a valid skipped result.
- **SDK handler delegates to `gsd-tools.cjs`** rather than re-porting the
detector to TypeScript, keeping drift logic in one canonical place.
Closes#2003
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs(mapper): tag --paths fenced block as text (CodeRabbit MD040)
Comment 3127255172.
* docs(config): use /gsd- dash command syntax in drift_action row (CodeRabbit)
Comment 3127255180. Matches the convention used by every other command
reference in docs/CONFIGURATION.md.
* fix(execute-phase): initialize AGENT_SKILLS_MAPPER + tag fenced blocks
Two CodeRabbit findings on the auto-remap branch of the drift gate:
- 3127255186 (must-fix): the mapper Task prompt referenced
${AGENT_SKILLS_MAPPER} but only AGENT_SKILLS (for gsd-executor) is
loaded at init_context (line 72). Without this fix the literal
placeholder string would leak into the spawned mapper's prompt.
Add an explicit gsd-sdk query agent-skills gsd-codebase-mapper step
right before the Task spawn.
- 3127255183: tag the warn-message and Task() fenced code blocks as
text to satisfy markdownlint MD040.
* docs(map-codebase): wire PATH_SCOPE_HINT through every mapper prompt
CodeRabbit (review id 4158286952, comment 3127255190) flagged that the
parse_paths_flag step defined incremental-remap semantics but did not
inject a normalized variable into the spawn_agents and sequential_mapping
mapper prompts, so incremental remap could silently regress to a
whole-repo scan.
- Define SCOPED_PATHS / PATH_SCOPE_HINT in parse_paths_flag.
- Inject ${PATH_SCOPE_HINT} into all four spawn_agents Task prompts.
- Document the same scope contract for sequential_mapping mode.
* fix(drift): writeMappedCommit tolerates missing target file
CodeRabbit (review id 4158286952, drift.cjs:349-355 nitpick) noted that
readMappedCommit returns null on ENOENT but writeMappedCommit threw — an
asymmetry that breaks first-time stamping of a freshly produced doc that
the caller has not yet written.
- Catch ENOENT on the read; treat absent file as empty content.
- Add a regression test that calls writeMappedCommit on a non-existent
path and asserts the file is created with correct frontmatter.
Test was authored to fail before the fix (ENOENT) and passes after.
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat: /gsd-settings-advanced — power-user config tuning command (closes#2528)
Adds a second-tier interactive configuration command covering the power-user
knobs that don't belong in the common-case /gsd-settings prompt. Six sectioned
AskUserQuestion batches cover planning, execution, discussion, cross-AI, git,
and runtime settings (19 config keys total). Current values are pre-selected;
numeric fields reject non-numeric input; writes route through
gsd-sdk query config-set so unrelated keys are preserved.
- commands/gsd/settings-advanced.md — command entry
- get-shit-done/workflows/settings-advanced.md — six-section workflow
- get-shit-done/workflows/settings.md — advertise advanced command
- get-shit-done/bin/lib/config-schema.cjs — add context_window to VALID_CONFIG_KEYS
- docs/COMMANDS.md, docs/CONFIGURATION.md, docs/INVENTORY.md — docs + inventory
- tests/gsd-settings-advanced.test.cjs — 81 tests (files, frontmatter,
field coverage, pre-selection, merge-preserves-siblings, VALID_CONFIG_KEYS
membership, confirmation table, /gsd-settings cross-link, negative scenarios)
All 5073 tests pass; coverage 88.66% (>= 70% threshold).
* docs(settings-advanced): clarify per-field numeric bounds and label fenced blocks
Addresses CodeRabbit review on PR #2603:
- Numeric-input rule now states min is field-specific: plan_bounce_passes
and max_discuss_passes require >= 1; other numeric fields accept >= 0.
Resolves the inconsistency between the global rule and the field-level
prompts (CodeRabbit comment 3127136557).
- Adds 'text' fence language to seven previously unlabeled code blocks in
the workflow (six AskUserQuestion sections plus the confirmation banner)
to satisfy markdownlint MD040 (CodeRabbit comment 3127136561).
* test(settings-advanced): tighten section assertion, fix misleading test name, add executable numeric-input coverage
Addresses CodeRabbit review on PR #2603:
- Required section list now asserts the full 'Runtime / Output' heading
rather than the looser 'Runtime' substring (comment 3127136564).
- Renames the subagent_timeout coercion test to match the actual key
under test (was titled 'context_window' but exercised
workflow.subagent_timeout — comment 3127136573).
- Adds two executable behavioral tests at the config-set boundary
(comment 3127136579):
* Non-numeric input on a numeric key currently lands as a string —
locks in that the workflow's AskUserQuestion re-prompt loop is the
layer responsible for type rejection. If a future change adds CLI-side
numeric validation, the assertion flips and the test surfaces it.
* Numeric string on workflow.max_discuss_passes is coerced to Number —
locks in the parser invariant for a second numeric key.
* feat(#2527): add settings layers to /gsd:settings (Group A toggles)
Expand /gsd:settings from 14 to 22 settings, grouped into six visual
sections: Planning, Execution, Docs & Output, Features, Model & Pipeline,
Misc. Adds 8 new toggles:
workflow.pattern_mapper, workflow.tdd_mode, workflow.code_review,
workflow.code_review_depth (conditional on code_review=on),
workflow.ui_review, commit_docs, intel.enabled, graphify.enabled
All 8 keys already existed in VALID_CONFIG_KEYS and docs/CONFIGURATION.md;
this wires them into the interactive flow, update_config write step,
~/.gsd/defaults.json persistence, and confirmation table.
Closes#2527
* test(#2527): tighten leaf-collision and rename mismatched negative test
Addresses CodeRabbit findings on PR #2602:
- comment 3127100796: leaf-only matching collapsed `intel.enabled` and
`graphify.enabled` to a single `enabled` token, so one occurrence
could satisfy both assertions. Replace with hasPathLike(), which
requires each dotted segment to appear in order within a bounded
window. Applied to both update_config and save_as_defaults blocks.
- comment 3127100798: the negative-test description claimed to verify
invalid `code_review_depth` value rejection but actually exercised an
unknown key path. Split into two suites with accurate names: one
asserts settings.md constrains the depth options, the other asserts
config-set rejects an unknown key path.
* docs(#2527): clarify resolved config path for /gsd-settings
Addresses CodeRabbit comment 3127100790 on PR #2602: the original line
implied a single `.planning/config.json` target, but settings updates
route to `.planning/workstreams/<active>/config.json` when a workstream
is active. Document both resolved paths so the merge target is
unambiguous.
Adds a `statusline.show_last_command` config toggle (default: false) that
appends ` │ last: /<cmd>` to the statusline, showing the most recently
invoked slash command in the current session.
The suffix is derived by tailing the active Claude Code transcript
(provided as transcript_path in the hook input) and extracting the last
<command-name> tag. Reads only the final 256 KiB to stay cheap per render.
Graceful degradation: missing transcript, no recorded command, unreadable
config, or parse errors all silently omit the suffix without breaking the
statusline.
Closes#2538
* fix(#2530-2535): correct VALID_CONFIG_KEYS set — remove internal state key, add missing public keys, add migration hints
- Remove workflow._auto_chain_active from VALID_CONFIG_KEYS (internal runtime state, not user-settable) (#2530)
- Add hooks.workflow_guard to VALID_CONFIG_KEYS (read by gsd-workflow-guard.js hook, already documented) (#2531)
- Add workflow.ui_review to VALID_CONFIG_KEYS (read in autonomous.md via config-get) (#2532)
- Add workflow.max_discuss_passes to VALID_CONFIG_KEYS (read in discuss-phase.md via config-get) (#2533)
- Add CONFIG_KEY_SUGGESTIONS entries for sub_repos → planning.sub_repos and plan_checker → workflow.plan_check (#2535)
- Document workflow.ui_review and workflow.max_discuss_passes in docs/CONFIGURATION.md
- Clear INTERNAL_KEYS exemption in parity test (workflow._auto_chain_active removed from schema entirely)
- Add regression test file tests/bug-2530-valid-config-keys.test.cjs covering all 6 bugs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: align SDK VALID_CONFIG_KEYS with CJS — remove internal key, add missing public keys
- Remove workflow._auto_chain_active from SDK (internal runtime state, not user-settable)
- Add workflow.ui_review, workflow.max_discuss_passes, hooks.workflow_guard to SDK
- Add ui_review and max_discuss_passes to Full Schema example in CONFIGURATION.md
Resolves CodeRabbit review on #2561.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(plan-phase): chunked mode + filesystem fallback for Windows stdio hang (#2310)
Addresses the 2026-04-16 Windows incident where gsd-planner wrote all 5
PLAN.md files to disk but Task() never returned, hanging the orchestrator
for 30+ minutes. Two mitigations:
1. Filesystem fallback (steps 9a, 11a): when Task() returns with an
empty/truncated response but PLAN.md files exist on disk, surface a
recoverable prompt (Accept plans / Retry planner / Stop) instead of
silently failing. Directly addresses the post-restart recovery path.
2. Chunked mode (--chunked flag / workflow.plan_chunked config): splits the
single long-lived planner Task into a short outline Task (~2 min) followed
by N short per-plan Tasks (~3-5 min each). Each plan is committed
individually for crash resilience. A hang loses one plan, not all of them.
Resume detection skips plans already on disk on re-run.
RCA confirmed: task state mtime 14:29 vs PLAN.md writes 14:32-14:52 =
subagent completed normally, IPC return was dropped by Windows stdio deadlock.
Neither mitigation fixes the root cause (requires upstream Task() timeout
support); both bound damage and enable recovery.
New reference file planner-chunked.md keeps OUTLINE COMPLETE / PLAN COMPLETE
return formats out of gsd-planner.md (which sits at 46K near its size limit).
Closes#2310
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(plan-phase): address CodeRabbit review comments on #2499
- docs/CONFIGURATION.md: add workflow.plan_chunked to full JSON schema example
- plan-phase.md step 8.5.1: validate PLAN-OUTLINE.md with grep for OUTLINE
COMPLETE marker before reusing (not just file existence)
- plan-phase.md step 8.5.2: validate per-plan PLAN.md has YAML frontmatter
(head -1 grep for ---) before skipping in resume path
- plan-phase.md: add language tags (text/javascript/bash) to bare fenced
code blocks in steps 8.5, 9a, 11a (markdownlint MD040)
- Rejected: commit_docs gate on per-plan commits (gsd-sdk query commit
already respects commit_docs internally — comment was a false positive)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(plan-phase): route Accept-plans through step 9 PLANNING COMPLETE handling
Honors --skip-verify / plan_checker_enabled=false in 9a fallback path.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(install): remove bare ~/.claude reference in update.md (closes#2470)
The installer's copyWithPathReplacement() replaces ~/\.claude\/ (with
trailing slash) but not ~/\.claude (bare, no trailing slash). A comment
on line 398 of update.md used the bare form, which scanForLeakedPaths()
correctly flagged for every non-Claude runtime install.
Replaced the example in the comment with a non-Claude runtime path so
the file passes the scanner for all runtimes.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(test): align regex with installer's word-boundary semantics (CodeRabbit #2482)
Replace negative lookahead (?!\/) with \b word boundary to match the
installer's scanForLeakedPaths() pattern. The lookahead would incorrectly
flag ~/.claude_suffix whereas \b correctly excludes it.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(test): revert \b regex — (?!\/) was intentionally scoped to bare refs
The installer's scanForLeakedPaths uses \b but the test is specifically
checking for bare ~/.claude without trailing slash that the replacer misses.
~/.claude/ (with slash) at line 359 of update.md is expected and handled.
\b would flag it as a false positive.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(inventory): update workflow count to 81 (graduation.md added in #2490)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(assembly): add link mode for CLAUDE.md @-reference sections (#2415)
Adds `claude_md_assembly.mode: "link"` config option that writes
`@.planning/<source>` instead of inlining content between GSD markers,
reducing typical CLAUDE.md size by ~65%. Per-block overrides available
via `claude_md_assembly.blocks.<section>`. Falls back to embed for
sections without a real source file (workflow, fallbacks).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(test): add positive assertion for embedded workflow content (CodeRabbit #2484)
The negative assertion only confirmed @GSD defaults wasn't written.
Add assert.ok(content.includes('GSD Workflow Enforcement')) to verify
the workflow section is actually embedded inline when link mode falls back.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(tests): update 5 source-text tests to read config-schema.cjs
VALID_CONFIG_KEYS moved from config.cjs to config-schema.cjs in the
drift-prevention companion PR. Tests that read config.cjs source text
and checked for key literal includes() now point to the correct file.
Closes#2480
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(cli): add /gsd-sync-skills for cross-runtime managed skill sync (#2380)
Adds /gsd-sync-skills command so multi-runtime users can keep gsd-* skill
directories aligned across runtime roots after updating one runtime with gsd-update.
Changes:
- bin/install.js: add --skills-root <runtime> flag that prints the skills root
path for any supported runtime, reusing the existing getGlobalDir() table.
Banner is suppressed when --skills-root is used (machine-readable output).
- commands/gsd/sync-skills.md: slash command definition
- get-shit-done/workflows/sync-skills.md: full workflow spec covering argument
parsing, path resolution via --skills-root, diff computation (CREATE/UPDATE/
REMOVE/SKIP), dry-run report (default), apply execution, idempotency guarantee,
and safety rules (only gsd-* touched, dry-run performs no writes).
Safety rules: only gsd-* directories are ever created/updated/removed; non-GSD
skills in destination roots are never touched; --dry-run is the default.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(tests): update 5 source-text tests to read config-schema.cjs
VALID_CONFIG_KEYS moved from config.cjs to config-schema.cjs in the
drift-prevention companion PR. Tests that read config.cjs source text
and checked for key literal includes() now point to the correct file.
Closes#2480
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(workflows): close LEARNINGS.md consumption-and-graduation loop (#2430)
Part A — Consumption: extend plan-phase.md cross-phase context load to include
LEARNINGS.md files from the 3 most recent prior phases (same recency gate as
CONTEXT.md + SUMMARY.md: CONTEXT_WINDOW >= 500000 only). Also loads LEARNINGS.md
from any phases in the Depends-on chain. Silent skip if absent; 15% context
budget cap with oldest-first truncation; [from Phase N LEARNINGS] attribution.
Part B — Graduation: add graduation_scan step to transition.md (after
evolve_project) that delegates to new graduation.md helper workflow. The helper
clusters recurring items across the last N phases (default window=5, threshold=3)
using Jaccard lexical similarity, surfaces HITL Promote/Defer/Dismiss prompts,
routes promotions to PROJECT.md or PATTERNS.md by category, annotates graduated
items with `graduated:` field, and persists dismissed/deferred clusters in
STATE.md graduation_backlog. Always non-blocking; silently no-ops on first phase
or when data is insufficient.
Also: adds optional `graduated:` annotation docs to extract_learnings.md schema.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(graduation): address CodeRabbit review findings on PR #2490
- graduation.md: unify insufficient-data guard to silent-skip (remove
contradictory [no-op] print path)
- graduation.md: add TEXT_MODE fallback for HITL cluster prompts
- graduation.md: add A (defer-all) to accepted actions [P/D/X/A]
- graduation.md: tag untyped code fences with text language (MD040)
- transition.md: tag untyped graduation.md fence with text language
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(graduation): rephrase TEXT_MODE line to avoid prompt-injection scanner false positive
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds artifacts.cjs with canonical .planning/ root file names, W019 warning
in gsd-health that flags unrecognized .md files at the .planning/ root, and
templates/README.md as the authoritative artifact index for agents and humans.
Closes#2448
- quick.md Step 5.6: commit PLAN.md to base branch before worktree executor
spawn when USE_WORKTREES is active, preventing CC #36182 path-resolution
drift that caused silent writes to main repo instead of worktree
- reapply-patches.md Option A: replace first-add commit heuristic with
pristine_hashes SHA-256 matching from backup-meta.json so baseline detection
works correctly on multi-cycle repos; first-add fallback kept for older
installers without pristine_hashes
- CONFIGURATION.md: move security_enforcement/security_asvs_level/security_block_on
to workflow.* (matches templates/config.json and workflow readers); rename
context_profile → context (matches VALID_CONFIG_KEYS in config.cjs); add
planning.sub_repos to schema example
- universal-anti-patterns.md + context-budget.md: fix context_window_tokens →
context_window (the actual key name in config.cjs)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Option A — ghost-entry guard (INVENTORY ⊆ actual):
tests/inventory-source-parity.test.cjs parses every declared row in
INVENTORY.md and asserts the source file exists. Catches deletions and
renames that leave ghost entries behind.
Option B — auto-generated structural manifest:
scripts/gen-inventory-manifest.cjs walks all six family dirs and emits
docs/INVENTORY-MANIFEST.json. tests/inventory-manifest-sync.test.cjs
fails CI when a new surface ships without a manifest update, surfacing
exactly which entries are missing.
Option C — schema-driven config validation + docs parity:
get-shit-done/bin/lib/config-schema.cjs extracted from config.cjs as
the single source of truth for VALID_CONFIG_KEYS and dynamic patterns.
config.cjs now imports from it. tests/config-schema-docs-parity.test.cjs
asserts every exact-match key appears in docs/CONFIGURATION.md, surfacing
14 previously undocumented keys (planning.sub_repos, workflow.ai_integration_phase,
git.base_branch, learnings.max_inject, and 10 others) — all now documented
in their appropriate sections.
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* docs: finish trust-bug fixes in user guide and commands
Correct load-bearing defects in the v1.36.0 docs corpus so readers stop
acting on wrong defaults and stale exhaustiveness claims.
- README.md: drop "Complete feature"/"Every command"/"All 18 agents"
exhaustiveness claims; replace version-pinned "What's new in v1.32"
bullet with a CHANGELOG pointer.
- CONFIGURATION.md: fix `claude_md_path` default (null/none -> `./CLAUDE.md`)
in both Full Schema and core settings table; correct `workflow.tdd_mode`
provenance from "Added in v1.37" to "Added in v1.36".
- USER-GUIDE.md: fix `workflow.discuss_mode` default (`standard` ->
`discuss`) in the workflow-toggles table AND in the abbreviated Full
Schema JSON block above it; align the Options cell with the shipped
enum.
- COMMANDS.md: drop "Complete command syntax" subtitle overclaim to
match the README posture.
- AGENTS.md: weaken "All 21 specialized agents" header to reflect that
the `agents/` filesystem is authoritative (shipped roster is 31).
Part 1 of a stacked docs refresh series (PR 1/4).
* docs: refresh shipped surface coverage for v1.36
Close the v1.36.0 shipped-surface gaps in the docs corpus.
- COMMANDS.md: add /gsd-graphify section (build/query/status/diff) and
its config gate; expand /gsd-quick with --validate flag and list/
status/resume subcommands; expand /gsd-thread with list --open, list
--resolved, close <slug>, status <slug>.
- CLI-TOOLS.md: replace the hardcoded "15 domain modules" count with a
pointer to the Module Architecture table; add a graphify verb-family
section (build/query/status/diff/snapshot); add Graphify and Learnings
rows to the Module Architecture table.
- FEATURES.md: add TOC entries for #116 TDD Pipeline Mode and #117
Knowledge Graph Integration; add the #117 body with REQ-GRAPH-01..05.
- CONFIGURATION.md: move security_enforcement / security_asvs_level /
security_block_on from root into `workflow.*` in Full Schema to match
templates/config.json and the gsd-sdk runtime reads; update Security
Settings table to use the workflow.* prefix; add planning.sub_repos
to Full Schema and description table; add a Graphify Settings section
documenting graphify.enabled and graphify.build_timeout.
Note: VALID_CONFIG_KEYS in bin/lib/config.cjs does not yet include
workflow.security_* or planning.sub_repos, so config-set currently
rejects them. That is a pre-existing validator gap that this PR does
not attempt to fix; the docs now correctly describe where these keys
live per the shipped template and runtime reads.
Part 2 of a stacked docs refresh series (PR 2/5), based on PR 1.
* docs: make inventory authoritative and reconcile architecture
Upgrade docs/INVENTORY.md from "complete for agents, selective for others"
to authoritative across all six shipped-surface families, and reconcile
docs/ARCHITECTURE.md against the new inventory so the PR that introduces
INVENTORY does not also introduce an INVENTORY/ARCHITECTURE contradiction.
- docs/AGENTS.md: weaken "21 specialized agents" header to 21 primary +
10 advanced (31 shipped); add new "Advanced and Specialized Agents"
section with concise role cards for the 10 previously-omitted shipped
agents (pattern-mapper, debug-session-manager, code-reviewer,
code-fixer, ai-researcher, domain-researcher, eval-planner,
eval-auditor, framework-selector, intel-updater); footnote the Agent
Tool Permissions Summary as primary-agents-only so it no longer
misleads.
- docs/INVENTORY.md (rewritten to be authoritative):
* Full 31-agent roster with one-line role + spawner + primary-doc
status per agent (unchanged from prior partial work).
* Commands: full 75-row enumeration grouped by Core Workflow, Phase &
Milestone Management, Session & Navigation, Codebase Intelligence,
Review/Debug/Recovery, and Docs/Profile/Utilities — each row
carries a one-line role derived from the command's frontmatter and
a link to the source file.
* Workflows: full 72-row enumeration covering every
get-shit-done/workflows/*.md, with a one-line role per workflow and
a column naming the user-facing command (or internal orchestrator)
that invokes it.
* References: full 41-row enumeration grouped by Core, Workflow,
Thinking-Model clusters, and the Modular Planner decomposition,
matching the groupings docs/ARCHITECTURE.md already uses; notes
the few-shot-examples subdirectory separately.
* CLI Modules and Hooks: unchanged — already full rosters.
* Maintenance section rewritten to describe the drift-guard test
suite that will land in PR4 (inventory-counts, commands-doc-parity,
agents-doc-parity, cli-modules-doc-parity, hooks-doc-parity).
- docs/ARCHITECTURE.md reconciled against INVENTORY:
* References block: drop the stale "(35 total)" count; point at
INVENTORY.md#references-41-shipped for the authoritative count.
* CLI Tools block: drop the stale "19 domain modules" count; point
at INVENTORY.md#cli-modules-24-shipped for the authoritative roster.
* Agent Spawn Categories: relabel as "Primary Agent Spawn Categories"
and add a footer naming the 10 advanced agents and pointing at
INVENTORY.md#agents-31-shipped for the full 31-agent roster.
- docs/CONFIGURATION.md: preserve the six model-profile rows added in
the prior partial work, and tighten the fallback note so it names the
13 shipped agents without an explicit profile row, documents
model_overrides as the escape hatch, and points at INVENTORY.md for
the authoritative 31-agent roster.
Part 3 of a stacked docs refresh series (PR 3/4). Remaining consistency
work (USER-GUIDE config-section delete-and-link, FEATURES.md TOC
reorder, ARCHITECTURE.md Hook-table expansion + installation-layout
collapse, CLI-TOOLS.md module-row additions, workflow-discuss-mode
invocation normalization, and the five doc-parity tests) lands in PR4.
* test(docs): add consistency guards and remove duplicate refs
Consolidates USER-GUIDE.md's command/config duplicates into pointers to
COMMANDS.md and CONFIGURATION.md (kills a ghost `resolve_model_ids` key
and a stale `discuss_mode: standard` default); reorders FEATURES.md TOC
chronologically so v1.32 precedes v1.34/1.35/1.36; expands
ARCHITECTURE.md's Hook table to the 11 shipped hooks
(gsd-read-injection-scanner, gsd-check-update-worker) and collapses
the installation-layout hook enumeration to the *.js/*.sh pattern form;
adds audit/gsd2-import/intel rows and state signal-*, audit-open,
from-gsd2 verbs to CLI-TOOLS.md; normalizes workflow-discuss-mode.md
invocations to `node gsd-tools.cjs config-set`.
Adds five drift guards anchored on docs/INVENTORY.md as the
authoritative roster: inventory-counts (all six families),
commands/agents/cli-modules/hooks parity checks that every shipped
surface has a row somewhere.
* fix(convergence): thread --ws to review agent; add stall and max-cycles behavioral tests
- Thread GSD_WS through to review agent spawn in plan-review-convergence
workflow (step 5a) so --ws scoping is symmetric with planning step
- Add behavioral stall detection test: asserts workflow compares
HIGH_COUNT >= prev_high_count and emits a stall warning
- Add behavioral --max-cycles 1 test: asserts workflow reaches escalation
gate when cycle >= MAX_CYCLES with HIGH > 0 after a single cycle
- Include original PR files (commands, workflow, tests) as the branch
predated the PR commits
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(docs,config): PR #2390 review — security_* config keys and REQ-GRAPH-02 scope
Addresses trek-e's review items that don't require rebase:
- config.cjs: add workflow.security_enforcement, workflow.security_asvs_level,
workflow.security_block_on to VALID_CONFIG_KEYS so gsd-sdk config-set accepts
them (closed the gap where docs/CONFIGURATION.md listed keys the validator
rejected).
- core.cjs: add matching CONFIG_DEFAULTS entries (true / 1 / 'high') so the
canonical defaults table matches the documented values.
- config.cjs: wire the three keys into the new-project workflow defaults so
fresh configs inherit them.
- planning-config.md: document the three keys in the Workflow Fields table,
keeping the CONFIG_DEFAULTS ↔ doc parity test happy.
- config-field-docs.test.cjs: extend NAMESPACE_MAP so the flat keys in
CONFIG_DEFAULTS resolve to their workflow.* doc rows.
- FEATURES.md REQ-GRAPH-02: split the slash-command surface (build|query|
status|diff) from the CLI surface which additionally exposes `snapshot`
(invoked automatically at the tail of `graphify build`). The prior text
overstated the slash-command surface.
* docs(inventory): refresh rosters and counts for post-rebase drift
origin/main accumulated surfaces since this PR was authored:
- Agents: 31 → 33 (+ gsd-doc-classifier, gsd-doc-synthesizer)
- Commands: 76 → 82 (+ ingest-docs, ultraplan-phase, spike, spike-wrap-up,
sketch, sketch-wrap-up)
- Workflows: 73 → 79 (same 6 names)
- References: 41 → 49 (+ debugger-philosophy, doc-conflict-engine,
mandatory-initial-read, project-skills-discovery, sketch-interactivity,
sketch-theme-system, sketch-tooling, sketch-variant-patterns)
Adds rows in the existing sub-groupings, introduces a Sketch References
subsection, and bumps all four headline counts. Roles are pulled from
source frontmatter / purpose blocks for each file. All 5 parity tests
(inventory-counts, agents-doc-parity, commands-doc-parity,
cli-modules-doc-parity, hooks-doc-parity) pass against this state —
156 assertions, 0 failures.
Also updates the 'Coverage note' advanced-agent count 10 → 12 and the
few-shot-examples footnote "41 top-level references" → "49" to keep the
file internally consistent.
* docs(agents): add advanced stubs for gsd-doc-classifier and gsd-doc-synthesizer
Both agents ship on main (spawned by /gsd-ingest-docs) but had no
coverage in docs/AGENTS.md. Adds the "advanced stub" entries (Role,
property table, Key behaviors) following the template used by the other
10 advanced/specialized agents in the same section.
Also updates the Agent Tool Permissions Summary scope note from
"10 advanced/specialized agents" to 12 to reflect the two new stubs.
* docs(commands): add entries for ingest-docs, ultraplan-phase, plan-review-convergence
These three commands ship on main (plan-review-convergence via trek-e's
4b452d29 commit on this branch) but had no user-facing section in
docs/COMMANDS.md — they lived only in INVENTORY.md. The commands-doc-parity
test already passes via INVENTORY, but the user-facing doc was missing
canonical explanations, argument tables, and examples.
- /gsd-plan-review-convergence → Core Workflow (after /gsd-plan-phase)
- /gsd-ultraplan-phase → Core Workflow (after plan-review-convergence)
- /gsd-ingest-docs → Brownfield (after /gsd-import, since both consume
the references/doc-conflict-engine.md contract)
Content pulled from each command's frontmatter and workflow purpose block.
* test: remove redundant ARCHITECTURE.md count tests
tests/architecture-counts.test.cjs and tests/command-count-sync.test.cjs
were added when docs/ARCHITECTURE.md carried hardcoded counts for commands/
workflows/agents. With the PR #2390 cleanup, ARCHITECTURE.md no longer
owns those numbers — docs/INVENTORY.md does, enforced by
tests/inventory-counts.test.cjs (scans the same filesystem directories
with the same readdirSync filter).
Keeping these ARCHITECTURE-specific tests would re-introduce the hardcoded
counts they guard, defeating trek-e's review point. The single-source-of-
truth parity tests already catch the same drift scenarios.
Related: #2257 (the regression this replaced).
---------
Co-authored-by: Tom Boucher <trekkie@nomorestars.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* docs: clarify capture_thought is an optional convention (#1873)
Issue #1873 merged /gsd:extract-learnings with an optional
capture_thought hook, but the docs never explained what the tool is
or where it comes from — readers couldn't tell whether it was a
bundled GSD tool, a required dependency, or something they had to
install. This surfaced in a user question on that issue's thread.
Clarify in docs/FEATURES.md §112 and the workflow file that
capture_thought is a convention — any MCP server exposing a tool
with that name will be used; if none is present, LEARNINGS.md
remains the primary output and the step is a silent no-op.
No behavioral change. All 23 extract-learnings tests still pass.
* fix(security): add human to detection message; test [/INST] closing form neutralization
- Detection message now lists <human> alongside <system>/<assistant>/<user>
- Sanitizer regex extended to cover [/INST] closing form (was only [INST])
- Detection pattern extended to cover [/INST] closing form
- New sanitizeForPrompt test asserts [/INST] is neutralized
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(config): add workflow.security_* keys to VALID_CONFIG_KEYS
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* docs: add language tag to fenced code block in FEATURES.md
Fixes MD040 lint finding in PR #2379 — the capture_thought tool
signature example was missing a javascript language identifier.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Tom Boucher <trekkie@nomorestars.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Two new specialist agents for /gsd-ingest-docs (#2387):
- gsd-doc-classifier: reads one doc, writes JSON classification
({ADR|PRD|SPEC|DOC|UNKNOWN} + title + scope + cross-refs + locked).
Heuristic-first, LLM on ambiguous. Designed for parallel fan-out per doc.
- gsd-doc-synthesizer: consumes all classifications + sources, applies
precedence rules (ADR>SPEC>PRD>DOC, manifest-overridable), runs cycle
detection on cross-ref graph, enforces LOCKED-vs-LOCKED hard-blocks
in both modes, writes INGEST-CONFLICTS.md with three buckets
(auto-resolved, competing-variants, unresolved-blockers) and
per-type intel staging files for gsd-roadmapper.
Also updates docs/ARCHITECTURE.md total-agents count (31 → 33) and the
copilot-install expected agent list.
Refs #2387
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs: add design spec for /gsd-ultraplan-phase beta command
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: add /gsd-ultraplan-phase [BETA] command
Offloads GSD plan phase to Claude Code's ultraplan cloud infrastructure.
Plan drafts remotely while terminal stays free; browser UI for inline
comments and revisions; imports back via existing /gsd-import --from.
Intentionally isolated from /gsd-plan-phase so upstream ultraplan changes
cannot break the core planning pipeline.
Closes#2374
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: resolve 5 pre-existing test failures before PR
- ARCHITECTURE.md: update command count 75→80 and workflow count 72→77
(stale doc counts; also incremented by new ultraplan-phase files)
- sketch.md: add TEXT_MODE plain-text fallback for AskUserQuestion (#2012)
- read-guard.test.cjs: clear CLAUDECODE env var alongside CLAUDE_SESSION_ID
so positive-path hook tests pass when run inside a Claude Code session
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* docs: add BETA.md with /gsd-ultraplan-phase user documentation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: address CodeRabbit review — MD040 fence labels and sketch.md TEXT_MODE duplicate
- Add language identifiers to all unlabeled fenced blocks in
ultraplan-phase.md and design spec (resolves MD040)
- Remove duplicate TEXT_MODE explanation from sketch.md mood_intake step
(was identical to the banner step definition)
- Make AskUserQuestion conditional explicit in mood_intake prose
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(tests): clear CLAUDECODE env var in read-guard test runner
The hook skips its advisory on two env vars: CLAUDE_SESSION_ID and
CLAUDECODE. runHook() cleared CLAUDE_SESSION_ID but inherited CLAUDECODE
from process.env, so tests run inside a Claude Code session silently
no-oped and produced no stdout, causing JSON.parse to throw.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(ci): update ARCHITECTURE.md counts and add TEXT_MODE fallback to sketch workflow
Four new spike/sketch files were added in 1.37.0 but two housekeeping
items were missed: ARCHITECTURE.md component counts (75→79 commands,
72→76 workflows) and the required TEXT_MODE fallback in sketch.md for
non-Claude runtimes (#2012).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(ci): update directory-tree slash command count in ARCHITECTURE.md
Missed the second count in the directory tree (# 75 slash commands → 79).
The prose "Total commands" was updated but the tree annotation was not,
causing command-count-sync.test.cjs to fail.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* docs: update release notes and command reference for v1.37.0
Covers spike/sketch commands, agent size-budget enforcement, and shared
boilerplate extraction across README, COMMANDS, FEATURES, and USER-GUIDE.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(tests): clear CLAUDECODE env var in read-guard test runner
The hook skips its advisory on two env vars: CLAUDE_SESSION_ID and
CLAUDECODE. runHook() cleared CLAUDE_SESSION_ID but inherited CLAUDECODE
from process.env, so tests run inside a Claude Code session silently
no-oped and produced no stdout, causing JSON.parse to throw.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(ci): update ARCHITECTURE.md counts and add TEXT_MODE fallback to sketch workflow
Four new spike/sketch files were added in 1.37.0 but two housekeeping
items were missed: ARCHITECTURE.md component counts (75→79 commands,
72→76 workflows) and the required TEXT_MODE fallback in sketch.md for
non-Claude runtimes (#2012).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(ci): update directory-tree slash command count in ARCHITECTURE.md
Missed the second count in the directory tree (# 75 slash commands → 79).
The prose "Total commands" was updated but the tree annotation was not,
causing command-count-sync.test.cjs to fail.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Introduces `/gsd-spec-phase <phase>` as an optional pre-step before discuss-phase.
Clarifies WHAT a phase delivers (requirements, boundaries, acceptance criteria) with
quantitative ambiguity scoring before discuss-phase handles HOW to implement.
- `commands/gsd/spec-phase.md` — slash command routing to workflow
- `get-shit-done/workflows/spec-phase.md` — full Socratic interview loop (up to 6
rounds, 5 rotating perspectives: Researcher, Simplifier, Boundary Keeper, Failure
Analyst, Seed Closer) with weighted 4-dimension ambiguity gate (≤ 0.20 to write SPEC.md)
- `get-shit-done/templates/spec.md` — SPEC.md template with falsifiable requirements
(Current/Target/Acceptance per requirement), Boundaries, Acceptance Criteria,
Ambiguity Report, and Interview Log; includes two full worked examples
- `get-shit-done/workflows/discuss-phase.md` — new `check_spec` step detects
`{padded_phase}-SPEC.md` at startup; displays "Found SPEC.md — N requirements
locked. Focusing on implementation decisions."; `analyze_phase` respects `spec_loaded`
flag to skip "what/why" gray areas; `write_context` emits `<spec_lock>` section
with boundary summary and canonical ref to SPEC.md
- `docs/ARCHITECTURE.md` — update command/workflow counts (74→75, 71→72)
Closes#2213
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* docs: document required Bash permission patterns for gsd-executor subagents (Closes#2071)
Adds a new "Executor Subagent Gets Permission denied on Bash Commands"
section to USER-GUIDE.md Troubleshooting. Documents the wildcard Bash
patterns that must be added to ~/.claude/settings.json (or per-project
.claude/settings.local.json) for each supported stack so fresh installs
aren't blocked mid-execution.
Covers: git write commands, gh, Rails/Ruby, Python/uv, Node/npm/pnpm/bun,
and Rust/Cargo. Includes a complete example settings.json snippet for Rails.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(phase): preserve zero-padded prefix in renameDecimalPhases
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Extends /gsd-progress with opt-in --forensic mode that appends a
6-check integrity audit after the standard routing report. Default
behavior is byte-for-byte unchanged — the audit only runs when
--forensic is explicitly passed.
Checks: (1) STATE vs artifact consistency, (2) orphaned handoff files,
(3) deferred scope drift, (4) memory-flagged pending work, (5) blocking
operational todos, (6) uncommitted source code. Emits CLEAN or
N INTEGRITY ISSUE(S) FOUND verdict with concrete next actions.
Closes#2189
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds --all to /gsd-discuss-phase so users can skip the AskUserQuestion
area-selection step and jump straight into discussing all gray areas
interactively. Unlike --auto, --all does NOT auto-advance to plan-phase —
it only eliminates the selection friction while keeping full interactive
control over each discussion.
Closes#2188
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* docs: sync ARCHITECTURE.md command count to 74
commands/gsd/ has 74 .md files; the two count references in
ARCHITECTURE.md still said 73. Fixes the command-count-sync
regression test.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: embed model_overrides in Codex TOML and OpenCode agent files (#2256)
Codex and OpenCode use static agent files (TOML / markdown frontmatter)
rather than inline Task(model=...) parameters, so model_overrides set in
~/.gsd/defaults.json was silently ignored — all subagents fell through to
the runtime's default model.
Fix: at install time, read model_overrides from ~/.gsd/defaults.json and
embed the matching model ID into each agent file:
- Codex: model = "..." field in the agent TOML (generateCodexAgentToml)
- OpenCode: model: ... field in agent frontmatter (convertClaudeToOpencodeFrontmatter)
Also adds readGsdGlobalModelOverrides() helper and passes the result
through installCodexConfig() and the OpenCode agent install loop.
Closes#2256
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(commands): add gsd:inbox command for GitHub issue/PR triage
inbox.md was created but not committed, causing the command count
to read 73 in git while ARCHITECTURE.md correctly stated 74.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* test: guard ARCHITECTURE.md component counts against drift (#2258)
Add tests/architecture-counts.test.cjs — 3 tests that dynamically
verify the "Total commands/workflows/agents" counts in
docs/ARCHITECTURE.md match the actual *.md file counts on disk.
Both sides computed at runtime; zero hardcoded numbers.
Also corrects the stale counts in ARCHITECTURE.md:
- commands: 69 → 74
- workflows: 68 → 71
- agents: 24 → 31
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(init): remove literal ~/.claude/ from deprecated root identifiers to pass Cline path-leak test
The cline-install.test.cjs scans installed engine files for literal
~/.claude/(get-shit-done|commands|...) strings that should have been
substituted during install. Two deprecated-legacy entries added by #2261
used tilde-notation string literals for their root identifier, which
triggered this scan.
root is only a display/sort key — filesystem scanning always uses the
path property (already dynamic via path.join). Switching root to the
relative form '.claude/get-shit-done/skills' and '.claude/commands/gsd'
satisfies the Cline path-leak guard without changing runtime behaviour.
Update skill-manifest.test.cjs assertion to match the new root format.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Add tests/command-count-sync.test.cjs which programmatically counts
.md files in commands/gsd/ and compares against the two count
occurrences in docs/ARCHITECTURE.md ("Total commands: N" prose line and
"# N slash commands" directory-tree comment). Counts are extracted from
the doc at runtime — never hardcoded — so future drift is caught
immediately in CI regardless of whether the doc or the filesystem moves.
Fix the current drift: ARCHITECTURE.md said 69 commands; the actual
committed count is 73. Both occurrences updated.
Closes#2257
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
When USER-PROFILE.md signals a non-technical product owner (learning_style: guided,
jargon in frustration_triggers, or high-level explanation_depth), discuss-phase now
reframes gray area labels and advisor_research rationale paragraphs in product-outcome
language. Same technical decisions, translated framing so product owners can participate
meaningfully without needing implementation vocabulary.
Closes#2125
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(workflow): add opt-in TDD pipeline mode (workflow.tdd_mode)
Add workflow.tdd_mode config key (default: false) that enables
red-green-refactor as a first-class phase execution mode. When
enabled, the planner aggressively applies type: tdd to eligible
tasks and the executor enforces RED/GREEN/REFACTOR gate sequence
with fail-fast on unexpected GREEN before RED. An end-of-phase
collaborative review checkpoint verifies gate compliance.
Closes#1871
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(test): allowlist plan-phase.md in prompt injection scan
plan-phase.md exceeds 50K chars after TDD mode integration.
This is legitimate orchestration complexity, not prompt stuffing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* ci: trigger CI run
* ci: trigger CI run
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Document 8 new features (108-115) in FEATURES.md, add --bounce/--cross-ai
flags to COMMANDS.md, new /gsd-extract-learnings command, 8 new config keys
in CONFIGURATION.md, and skill-manifest + --ws flag in CLI-TOOLS.md.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add CURSOR_SESSION_ID env var detection in review.md so Cursor skips
itself as a reviewer (matching the CLAUDE_CODE_ENTRYPOINT pattern).
Add Qwen Review and Cursor Review sections to the REVIEWS.md template.
Update ja-JP and ko-KR FEATURES.md to include --opencode, --qwen, and
--cursor flags in the /gsd-review command signature.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(review): add Qwen Code and Cursor CLI as peer reviewers (#1938, #1960)
Add qwen and cursor to the /gsd-review pipeline following the
established pattern from CodeRabbit and OpenCode integrations:
- CLI detection via command -v
- --qwen and --cursor flags
- Invocation blocks with empty-output fallback
- Install help URLs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(review): correct qwen/cursor invocations and add doc surfaces (#1966)
Address review feedback from trek-e, kturk, and lawsontaylor:
- Use positional form for qwen (qwen "prompt") — -p flag is deprecated
upstream and will be removed in a future version
- Fix cursor invocation to use cursor agent -p --mode ask --trust
instead of cursor --prompt which launches the editor GUI
- Add --qwen and --cursor flags to COMMANDS.md, FEATURES.md, help.md,
commands/gsd/review.md, and localized docs (ja-JP, ko-KR)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Community PRs repeatedly add marketing commentary in parentheses next to
product names (licensing model, parent company, architecture). Product
listings should contain only the product name.
Cleaned across 8 files in 5 languages (EN, KO, JA, ZH, PT) plus
install.js code comments and CHANGELOG. Added static analysis guard
test that prevents this pattern from recurring.
Fixes#1777
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* test: add stale /gsd: colon reference regression guard
Fixes#1748
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: replace 39 stale /gsd: colon references with /gsd- hyphen format
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>