Compare commits

...

79 Commits

Author SHA1 Message Date
Tom Boucher
b35fdd51f3 Revert "feat(#2473): ship refuses to open PR when HANDOFF.json declares in-pr…" (#2596)
This reverts commit 7212cfd4de.
2026-04-22 12:57:12 -04:00
Fernando Castillo
7212cfd4de feat(#2473): ship refuses to open PR when HANDOFF.json declares in-progress work (#2553)
* feat(#2473): ship refuses to open PR when HANDOFF.json declares in-progress work

Add a preflight step to /gsd-ship that parses .planning/HANDOFF.json and
refuses to run git push + gh pr create when any remaining_tasks[].status
is not in the terminal set {done, cancelled, deferred_to_backend, wont_fix}.

Refusal names each blocking task and lists four resolutions (finish, mark
terminal, delete stale file, --force). Missing HANDOFF.json is a no-op so
projects that do not use /gsd-pause-work see no behavior change.

Also documents the terminal-statuses contract in references/artifact-types.md
and adds tests/ship-handoff-preflight.test.cjs to lock in the contract.

Closes #2473

* fix(#2473): capture node exit from $() so malformed HANDOFF.json hard-stops

Command substitution BLOCKING=$(node -e "...") discards the inner process
exit code, so a corrupted HANDOFF.json that fails JSON.parse would yield
empty BLOCKING and fall through silently to push_branch — the opposite of
what preflight is supposed to do.

Capture node's exit into HANDOFF_EXIT via $? immediately after the
assignment and branch on it. A non-zero exit is now a hard refusal with
the parser error printed on the preceding stderr line. --force does not
bypass this branch: if the file exists and can't be parsed, something is
wrong and the user should fix it (option 3 in the refusal message —
"Delete HANDOFF.json if it's stale" — still applies).

Verified with a tmp-dir simulation: captured exit 2, hard-stop fires
correctly on malformed JSON. Added a test case asserting the capture
($?) + branch (-ne 0) + parser exit (process.exit(2)) are all present,
so a future refactor can't silently reintroduce the bug.

Reported by @coderabbitai on PR #2553.
2026-04-22 12:11:31 -04:00
Tom Boucher
2b5c35cdb1 test(#2519): add regression test for sdk tarball dist inclusion (#2586)
* test(#2519): add regression test verifying sdk/package.json has files + prepublishOnly

Guards the sdk/package.json fix for #2519 (tarball shipped without dist/)
so future edits can't silently drop either the `files` whitelist or the
`prepublishOnly` build hook. Asserts:

- `files` is a non-empty array
- `files` includes "dist" (so compiled CLI ships in tarball)
- `scripts.prepublishOnly` runs a build (npm run build / tsc)
- `bin` target lives under dist/ (sanity tie-in)

Closes #2519

* test(#2519): accept valid npm glob variants for dist in files matcher

Addresses CodeRabbit nitpick: the previous equality check on 'dist' / 'dist/' /
'dist/**' would false-fail on other valid npm packaging forms like './dist',
'dist/**/*', or backslash-separated paths. Normalize each entry and use a
regex that accepts all common dist path variants.
2026-04-22 12:09:12 -04:00
Tom Boucher
73c1af5168 fix(#2543): replace legacy /gsd-<cmd> syntax with /gsd:<cmd> across all source files (#2595)
Commands are now installed as commands/gsd/<name>.md and invoked as
/gsd:<name> in Claude Code. The old hyphen form /gsd-<name> was still
hardcoded in hundreds of places across workflows, references, templates,
lib modules, and command files — causing "Unknown command" errors
whenever GSD suggested a command to the user.

Replace all /gsd-<cmd> occurrences where <cmd> is a known command name
(derived at runtime from commands/gsd/*.md) using a targeted Node.js
script. Agent names, tool names (gsd-sdk, gsd-tools), directory names,
and path fragments are not touched.

Adds regression test tests/bug-2543-gsd-slash-namespace.test.cjs that
enforces zero legacy occurrences going forward. Removes inverted
tests/stale-colon-refs.test.cjs (bug #1748) which enforced the now-obsolete
hyphen form; the new bug-2543 test supersedes it. Updates 5 assertion
tests that hardcoded the old hyphen form to accept the new colon form.

Closes #2543

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 12:04:25 -04:00
Tom Boucher
533973700c feat(#2538): add last: /cmd suffix to statusline (opt-in) (#2594)
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
2026-04-22 12:04:21 -04:00
Tom Boucher
349daf7e6a fix(#2545): use word boundary in path replacement to catch ~/.claude without trailing slash (#2592)
The Copilot content converter only replaced `~/.claude/` and
`$HOME/.claude/` when followed by a literal `/`. Bare references
(e.g. `configDir = ~/.claude` at end of line) slipped through and
triggered the post-install "Found N unreplaced .claude path reference(s)"
warning, since the leak scanner uses `(?:~|$HOME)/\.claude\b`.

Switched both replacements to a `(\/|\b)` capture group so trailing-slash
and bare forms are handled in a single pass — matching the pattern
already used by Antigravity, OpenCode, Kilo, and Codex converters.

Closes #2545
2026-04-22 12:04:17 -04:00
Tom Boucher
6b7b5c15a5 fix(#2559): remove stale year injection from research agent web search instructions (#2591)
The gsd-phase-researcher and gsd-project-researcher agents instructed
WebSearch queries to always include 'current year' (e.g., 2024). As
time passes, a hardcoded year biases search results toward stale
dated content — users saw 2024-tagged queries producing stale blog
references in 2026.

Remove the year-injection guidance. Instead, rely on checking
publication dates on the returned sources. Query templates and
success criteria updated accordingly.

Closes #2559
2026-04-22 12:04:13 -04:00
Tom Boucher
67a9550720 fix(#2549,#2550,#2552): bound discuss-phase context reads, add phase-type map selection, prohibit split reads (#2590)
#2549: load_prior_context was reading every prior *-CONTEXT.md file,
growing linearly with project phase count. Cap to the 3 most recent
phases. If .planning/DECISIONS-INDEX.md exists, read that instead.

#2550: scout_codebase claimed to select maps "based on phase type" but
had no classifier — agents read all 7 maps. Replace with an explicit
phase-type-to-maps table (2–3 maps per phase type) with a Mixed fallback.

#2552: Add explicit instruction not to split-read the same file at two
different offsets. Split reads break prompt cache reuse and cost more
than a single full read.

Closes #2549
Closes #2550
Closes #2552

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 12:04:10 -04:00
Tom Boucher
fba040c72c fix(#2557): Gemini/Antigravity local hook commands use relative paths, not \$CLAUDE_PROJECT_DIR (#2589)
\$CLAUDE_PROJECT_DIR is Claude Code-specific. Gemini CLI doesn't set it, and on
Windows its path-join logic doubled the value producing unresolvable paths like
D:\Projects\GSD\'D:\Projects\GSD'. Gemini runs project hooks with project root
as cwd, so bare relative paths (e.g. node .gemini/hooks/gsd-check-update.js)
are cross-platform and correct. Claude Code and others still use the env var.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 12:04:06 -04:00
Tom Boucher
7032f44633 fix(#2544): exit 1 on missing key in config-get (#2588)
The configGet query handler previously threw GSDError with
ErrorClassification.Validation, which maps to exit code 10. Callers
using `if ! gsd-sdk query config-get key; then fallback; fi` could
not detect missing keys through the exit code alone, because exit 10
is still truthy-failure but the intent (and documented UNIX
convention — cf. `git config --get`) is exit 1 for absent key.

Change the classification for the two 'Key not found' throw sites to
ErrorClassification.Execution so the CLI exits 1 on missing key.
Usage/schema errors (no key argument, malformed JSON, missing
config.json) remain Validation.

Closes #2544
2026-04-22 12:04:03 -04:00
Tom Boucher
2404b40a15 fix(#2555): SDK agent-skills reads config.agent_skills and returns <agent_skills> block (#2587)
The SDK query handler `agent-skills` previously scanned every skill
directory on the filesystem and returned a flat JSON list, ignoring
`config.agent_skills[agentType]` entirely. Workflows that interpolate
$(gsd-sdk query agent-skills <type>) into Task() prompts got a JSON
dump of all skills instead of the documented <agent_skills> block.

Port `buildAgentSkillsBlock` semantics from
get-shit-done/bin/lib/init.cjs into the SDK handler:

- Read config.agent_skills[agentType] via loadConfig()
- Support single-string and array forms
- Validate each project-relative path stays inside the project root
  (symlink-aware, mirrors security.cjs#validatePath)
- Support `global:<name>` prefix for ~/.claude/skills/<name>/
- Skip entries whose SKILL.md is missing, with a stderr warning
- Return the exact string block workflows embed:
  <agent_skills>\nRead these user-configured skills:\n- @.../SKILL.md\n</agent_skills>
- Empty string when no agent type, no config, or nothing valid — matches
  gsd-tools.cjs cmdAgentSkills output.
2026-04-22 12:03:59 -04:00
Tom Boucher
0d6349a6c1 fix(#2554): preserve leading zero in getMilestonePhaseFilter (#2585)
The normalization `replace(/^0+/, '')` over-stripped decimal phase IDs:
`"00.1"` collapsed to `".1"`, while the disk-side extractor yielded
`"0.1"` from `"00.1-<slug>"`. Set membership failed and inserted decimal
phases were silently excluded from every disk scan inside
`buildStateFrontmatter`, causing `state update` to rewind progress
counters.

Strip leading zeros only when followed by a digit
(`replace(/^0+(?=\d)/, '')`), preserving the zero before the decimal
point while keeping existing behavior for zero-padded integer IDs.

Closes #2554
2026-04-22 12:03:56 -04:00
Tom Boucher
c47a6a2164 fix: correct VALID_CONFIG_KEYS — remove internal state key, add missing public keys, migration hints (#2561)
* 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>
2026-04-22 11:28:25 -04:00
forfrossen
af2dba2328 fix(hooks): detect Claude Code via stdin session_id (closes #2520) (#2521)
* fix(hooks): detect Claude Code via stdin session_id, not filtered env (#2520)

The #2344 fix assumed `CLAUDECODE` would propagate to hook subprocesses.
On Claude Code v2.1.116 it doesn't — Claude Code applies a separate env
filter to PreToolUse hook commands that drops bare CLAUDECODE and
CLAUDE_SESSION_ID, keeping only CLAUDE_CODE_*-prefixed vars plus
CLAUDE_PROJECT_DIR. As a result every Edit/Write on an existing file
produced a redundant READ-BEFORE-EDIT advisory inside Claude Code.

Use `data.session_id` from the hook's stdin JSON as the primary Claude
Code signal (it's part of Claude Code's documented PreToolUse hook-input
schema). Keep CLAUDE_CODE_ENTRYPOINT / CLAUDE_CODE_SSE_PORT env checks
as propagation-verified fallbacks, and keep the legacy
CLAUDE_SESSION_ID / CLAUDECODE checks for back-compat and
future-proofing.

Add tests/bug-2520-read-guard-hook-subprocess-env.test.cjs, which spawns
the hook with an env mirroring the actual Claude Code hook-subprocess
filter. Extend the legacy test harnesses to also strip the
propagation-verified CLAUDE_CODE_* vars so positive-path tests keep
passing when the suite itself runs inside a Claude Code session (same
class of leak as #2370 / PR #2375, now covering the new detection
signals).

Non-Claude-host behavior (OpenCode / MiniMax) is unchanged: with no
`session_id` on stdin and no CLAUDE_CODE_* env var, the advisory still
fires.

Closes #2520

* test(2520): isolate session_id signal from env fallbacks in regression test

Per reviewer feedback (Copilot + CodeRabbit on #2521): the session_id
isolation test used the helper's default CLAUDE_CODE_ENTRYPOINT /
CLAUDE_CODE_SSE_PORT values, so the env fallback would rescue the skip
even if the primary `data.session_id` check regressed. Pass an explicit
env override that clears those fallbacks, so only the stdin `session_id`
signal can trigger the skip.

Other cases (env-only fallback, negative / non-Claude host) already
override env appropriately.

---------

Co-authored-by: forfrossen <forfrossensvart@gmail.com>
2026-04-22 10:41:58 -04:00
elfstrob
9b5397a30f feat(sdk): add queued_phases to init.manager (closes #2497) (#2514)
* feat(sdk): add queued_phases to init.manager (closes #2497)

Surfaces the milestone immediately AFTER the active one so the
/gsd-manager dashboard can preview upcoming phases without mixing
them into the active phases grid.

Changes:
- roadmap.ts: exports two new helpers
  - extractPhasesFromSection(section): parses phase number / name /
    goal / depends_on using the same pattern initManager uses for
    the active milestone, so queued phases have identical shape.
  - extractNextMilestoneSection(content, projectDir): resolves the
    current milestone via the STATE-first path (matching upstream
    PR #2508) then scans for the next ## milestone heading. Shipped
    milestones are stripped first so they can't shadow the real
    next. Returns null when the active milestone is the last one.
- init-complex.ts: initManager now exposes
  - queued_phases: Array<{ number, name, display_name, goal,
    depends_on, dep_phases, deps_display }>
  - queued_milestone_version: string | null
  - queued_milestone_name: string | null
  Existing phases array is unchanged — callers that only care about
  the active milestone see no behavior difference.

Scope note: PR #2508 (merged upstream 2026-04-21) superseded the
#2495 + #2496 portions of this branch's original submission. This
commit is the rebased remainder contributing only #2497 on top of
upstream's new helpers.

Test coverage (7 new tests, all passing):
- roadmap.test.ts: +5 tests
  - extractPhasesFromSection parses multiple phases with goal + deps
  - extractPhasesFromSection returns [] when no phase headings
  - extractNextMilestoneSection returns the milestone after the
    STATE-resolved active one
  - extractNextMilestoneSection returns null when active is last
  - extractNextMilestoneSection returns null when no version found
- init-complex.test.ts: +4 tests under `queued_phases (#2497)`
  - surfaces next milestone with version + name metadata
  - queued entries carry name / deps_display / display_name
  - queued phases are NOT mixed into active phases list
  - returns [] + nulls when active is the last milestone

All 51 tests in roadmap.test.ts + init-complex.test.ts pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(workflows): render queued_phases section in /gsd-manager dashboard

Surfaces the new `queued_phases` / `queued_milestone_version` /
`queued_milestone_name` fields from init.manager (SDK #2497) in a
compact preview section directly below the main active-milestone
table.

Changes to workflows/manager.md:
- Initialize step: parse the optional trio
  (queued_milestone_version, queued_milestone_name, queued_phases)
  alongside the existing init.manager fields. Treat missing as
  empty for backward compatibility with older SDK versions.
- Dashboard step: new "Queued section (next milestone preview)"
  rendered between the main active-milestone grid and the
  Recommendations section. Renders only when queued_phases is
  non-empty; skipped entirely when absent or empty (e.g. active
  milestone is the last one).
- Queued rows render without D/P/E columns since the phases haven't
  been discussed yet — just number, display_name, deps_display,
  and a fixed "· Queued" status.
- Success criterion added: queued section renders when non-empty
  and is skipped when absent.

Queued phases are deliberately NOT eligible for the Continue action
menu; they live in a future milestone. The preview exists for
situational awareness only.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 10:41:37 -04:00
Tom Boucher
7397f580a5 fix(#2516): resolve executor_model inherit literal passthrough; add regression test (#2537)
When model_profile is "inherit", execute-phase was passing the literal string
"inherit" to Task(model=), causing fallback to the default model. The workflow
now documents that executor_model=="inherit" requires omitting the model= parameter
entirely so Claude Code inherits the orchestrator model automatically.

Closes #2516
2026-04-21 21:35:22 -04:00
Tom Boucher
9a67e350b3 fix(#2504): auto-pass UAT for infrastructure/foundation phases with no user-facing elements (#2541)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 21:20:27 -04:00
Tom Boucher
98d92d7570 fix(#2526): warn about REQ-IDs in body missing from Traceability table (#2539)
Scan REQUIREMENTS.md body for all **REQ-ID** patterns during phase
complete and emit a warning for any IDs absent from the Traceability
table, regardless of whether the roadmap has a Requirements: line.

Closes #2526
2026-04-21 21:18:58 -04:00
Tom Boucher
8eeaa20791 fix(install): chmod dist/cli.js 0o755 after npm install -g; add regression test (closes #2525) (#2536)
Use process.platform !== 'win32' guard in catch instead of a comment, and add
regression test for bug #2525 (gsd-sdk bin symlink points at non-executable file).

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 21:18:34 -04:00
Tom Boucher
f32ffc9fb8 fix(quick): include deferred-items.md in final commit file list (closes #2523) (#2542)
Step 8 file list omitted deferred-items.md, leaving executor out-of-scope
findings untracked after final commit even with commit_docs: true.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 20:33:43 -04:00
Tom Boucher
5676e2e4ef fix(sdk): forward --ws workstream flag through query dispatch (#2546)
* fix(sdk): forward --ws workstream flag through query dispatch (closes #2524)

- cli.ts: pass args.ws as workstream to registry.dispatch()
- registry.ts: add workstream? param to dispatch(), thread to handler
- utils.ts: add optional workstream? to QueryHandler type signature
- helpers.ts: planningPaths() accepts workstream? and uses relPlanningPath()
- All ~26 query handlers updated to receive and pass workstream to planningPaths()
- Config/commit/intel handlers use _workstream (project-global, not scoped)
- Add failing-then-passing test: tests/bug-2524-sdk-query-ws-flag.test.cjs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(sdk): forward workstream to all downstream query helpers

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(test): rewrite #2524 test as static source assertions — no sdk/dist build in CI

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 20:33:24 -04:00
Lex Christopherson
7bb6b6452a fix: spike workflow defaults to interactive UI demos, not stdout
Flips the bias in step 8b: build a simple HTML page/web UI by default,
fall back to stdout only for pure fact-checking (binary yes/no, benchmarks).
Mirrors upstream spike-idea skill constraint #3 update.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-21 09:19:04 -06:00
Lex Christopherson
43ea92578b Merge remote-tracking branch 'origin/main' into hotfix/1.38.2
# Conflicts:
#	CHANGELOG.md
#	bin/install.js
#	sdk/src/query/init.ts
2026-04-21 09:16:24 -06:00
Lex Christopherson
a42d5db742 1.38.2 2026-04-21 09:14:52 -06:00
Lex Christopherson
c86ca1b3eb fix: sync spike/sketch workflows with upstream skill v2 improvements
Spike workflow:
- Add frontier mode (no-arg or "frontier" proposes integration + frontier spikes)
- Add depth-over-speed principle — follow surprising findings, test edge cases,
  document investigation trail not just verdict
- Add CONVENTIONS.md awareness — follow established patterns, update after session
- Add Requirements section in MANIFEST — track design decisions as they emerge
- Add re-ground step before each spike to prevent drift in long sessions
- Add Investigation Trail section to README template
- Restructured prior context loading with priority ordering
- Research step now runs per-spike with briefing and approach comparison table

Sketch workflow:
- Add frontier mode (no-arg or "frontier" proposes consistency + frontier sketches)
- Add spike context loading — ground mockups in real data shapes, requirements,
  and conventions from spike findings

Spike wrap-up workflow:
- Add CONVENTIONS.md generation step (recurring stack/structure/pattern choices)
- Reference files now use implementation blueprint format (Requirements, How to
  Build It, What to Avoid, Constraints)
- SKILL.md now includes requirements section from MANIFEST
- Next-steps route to /gsd-spike frontier mode instead of inline analysis

Sketch wrap-up workflow:
- Next-steps route to /gsd-sketch frontier mode

Commands updated with frontier mode in descriptions and argument hints.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-21 09:14:32 -06:00
github-actions[bot]
337e052aa9 chore: bump version to 1.38.2 for hotfix 2026-04-21 15:13:56 +00:00
Lex Christopherson
969ee38ee5 fix: sync spike/sketch workflows with upstream skill v2 improvements
Spike workflow:
- Add frontier mode (no-arg or "frontier" proposes integration + frontier spikes)
- Add depth-over-speed principle — follow surprising findings, test edge cases,
  document investigation trail not just verdict
- Add CONVENTIONS.md awareness — follow established patterns, update after session
- Add Requirements section in MANIFEST — track design decisions as they emerge
- Add re-ground step before each spike to prevent drift in long sessions
- Add Investigation Trail section to README template
- Restructured prior context loading with priority ordering
- Research step now runs per-spike with briefing and approach comparison table

Sketch workflow:
- Add frontier mode (no-arg or "frontier" proposes consistency + frontier sketches)
- Add spike context loading — ground mockups in real data shapes, requirements,
  and conventions from spike findings

Spike wrap-up workflow:
- Add CONVENTIONS.md generation step (recurring stack/structure/pattern choices)
- Reference files now use implementation blueprint format (Requirements, How to
  Build It, What to Avoid, Constraints)
- SKILL.md now includes requirements section from MANIFEST
- Next-steps route to /gsd-spike frontier mode instead of inline analysis

Sketch wrap-up workflow:
- Next-steps route to /gsd-sketch frontier mode

Commands updated with frontier mode in descriptions and argument hints.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-21 09:05:47 -06:00
Tom Boucher
2980f0ec48 fix(sdk): stripShippedMilestones handles inline SHIPPED headings; getMilestoneInfo prefers STATE.md (#2508)
* fix(sdk): stripShippedMilestones handles inline SHIPPED headings; getMilestoneInfo prefers STATE.md

Fixes two compounding bugs:

- #2496: stripShippedMilestones only stripped <details> blocks, ignoring
  '## Heading —  SHIPPED ...' inline markers. Shipped milestone sections
  were leaking into downstream parsers.

- #2495: getMilestoneInfo checked STATE.md frontmatter only as a last-resort
  fallback, so it returned the first heading match (often a leaked shipped
  milestone) rather than the current milestone. Moved STATE.md check to
  priority 1, consistent with extractCurrentMilestone.

Closes #2495
Closes #2496

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(roadmap): handle ### SHIPPED headings and STATE.md version-only case

Two follow-up fixes from CodeRabbit review of #2508:

1. stripShippedMilestones only split on ## boundaries; ### headings marked
    SHIPPED were not stripped, leaking into fallback parsers. Expanded
   the split/filter regex to #{2,3} to align with extractCurrentMilestone.

2. getMilestoneInfo's early-return on parseMilestoneFromState discarded the
   real milestone name from ROADMAP.md when STATE.md had only `milestone:`
   (no `milestone_name:`), returning the placeholder name 'milestone'.
   Now only short-circuits when STATE.md provides a real name; otherwise
   falls through to ROADMAP for the name while using stateVersion to
   override the version in every ROADMAP-derived return path.

Tests: +2 new cases (### SHIPPED heading, version-only STATE.md).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 10:41:35 -04:00
Tom Boucher
8789211038 fix(insert-phase): update STATE.md next-phase recommendation after phase insertion (#2509)
* fix(insert-phase): update STATE.md next-phase recommendation after inserting a phase

Closes #2502

* fix(insert-phase): update all STATE.md pointers; tighten test scope

Two follow-up fixes from CodeRabbit review of #2509:

1. The update_project_state instruction only said to find "the line" for
   the next-phase recommendation. STATE.md can have multiple pointers
   (structured current_phase: field AND prose recommendation text).
   Updated wording to explicitly require updating all of them in the same
   edit.

2. The regression test for the next-phase pointer update scanned the
   entire file, so a match anywhere would pass even if update_project_state
   itself was missing the instruction. Scoped the assertion to only the
   content inside <step name="update_project_state"> to prevent false
   positives.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 10:10:45 -04:00
Tom Boucher
57bbfe652b fix: exclude non-wiped dirs from custom-file scan; warn on non-Claude model profiles (#2511)
* fix(detect-custom-files): exclude skills and command dirs not wiped by installer (closes #2505)

GSD_MANAGED_DIRS included 'skills' and 'command' directories, but the
installer never wipes those paths. Users with third-party skills installed
(40+ files, none in GSD's manifest) had every skill flagged as a "custom
file" requiring backup, producing noisy false-positive reports on every
/gsd-update run.

Removes 'skills' and 'command' from both gsd-tools.cjs and the SDK's
detect-custom-files.ts. Adds two regression tests confirming neither
directory is scanned.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(settings): warn that model profiles are no-ops on non-Claude runtimes (closes #2506)

settings.md presented Quality/Balanced/Budget model profiles without any
indication that these tiers map to Claude models (Opus/Sonnet/Haiku) and
have no effect on non-Claude runtimes (Codex, Gemini CLI, OpenRouter).
Users on Codex saw the profile chooser as if it would meaningfully select
models, but all agents silently used the runtime default regardless.

Adds a non-Claude runtime note before the profile question (shown in
TEXT_MODE, the path all non-Claude runtimes take) explaining the profiles
are no-ops and directing users to either choose Inherit or configure
model_overrides manually. Also updates the Inherit option description to
explicitly name the runtimes where it is the correct choice.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 10:10:10 -04:00
Tom Boucher
a4764c5611 fix(execute-phase): resurrection-detection must check git history before deleting new .planning/ files (#2510)
The guard at the worktree-merge resurrection block was inverting the
intended logic: it deleted any .planning/ file absent from PRE_MERGE_FILES,
which includes brand-new files (e.g. SUMMARY.md just created by the
executor). A genuine resurrection is a file that was previously tracked on
main, deliberately removed, and then re-introduced by the merge. Detecting
that requires a git history check — not just tree membership.

Fix: replace the PRE_MERGE_FILES grep guard with a `git log --follow
--diff-filter=D` check that only removes the file if it has a deletion
event in main's ancestry.

Closes #2501
2026-04-21 09:46:01 -04:00
Tom Boucher
b2534e8a05 feat(plan-phase): chunked mode + filesystem fallback for Windows stdio hang (#2499)
* 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>
2026-04-21 08:40:39 -04:00
Tom Boucher
d1b56febcb fix(execute-phase): post-merge deletion audit for bulk file deletions (closes #2384) (#2483)
* fix(execute-phase): post-merge deletion audit for bulk file deletions (closes #2384)

Two data-loss incidents were caused by worktree merges bringing in bulk
file deletions silently. The pre-merge check (HEAD...WT_BRANCH) catches
deletions on the worktree branch, but files deleted during the merge
itself (e.g., from merge conflict resolution or stale branch state) were
not audited post-merge.

Adds a post-merge audit immediately after git merge --no-ff succeeds:
- Counts files deleted outside .planning/ in the merge commit
- If count > 5 and ALLOW_BULK_DELETE!=1: reverts the merge with
  git reset --hard HEAD~1 and continues to the next worktree
- Logs the full file list and an escape-hatch instruction

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(test): tighten post-merge deletion audit assertions (CodeRabbit #2483)

Replace loose substring checks with exact regex assertions:
- assert.match against 'git diff --diff-filter=D --name-only HEAD~1 HEAD'
- assert.match against threshold gate + ALLOW_BULK_DELETE override condition
- assert.match against git reset --hard HEAD~1 revert
- assert.match against MERGE_DEL_COUNT grep -vc for non-.planning count

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>
2026-04-20 18:37:42 -04:00
Tom Boucher
1657321eb0 fix(install): remove bare ~/.claude reference in update.md (closes #2470) (#2482)
* 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>
2026-04-20 18:37:32 -04:00
Tom Boucher
2b494407e5 feat(assembly): add link mode for CLAUDE.md @-reference sections (#2484)
* 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>
2026-04-20 18:27:55 -04:00
Tom Boucher
d0f4340807 feat(workflows): link pending todos to roadmap phases in new-milestone (#2433) (#2485)
Adds step 10.5 to gsd-new-milestone that scans pending todos against the
approved roadmap and tags matches with `resolves_phase: N` in their YAML
frontmatter. Adds a `close_phase_todos` step to execute-phase that moves
tagged todos to `completed/` when the phase completes — closing the loop
automatically with no manual cleanup.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 18:25:24 -04:00
Tom Boucher
280eed93bc feat(cli): add /gsd-sync-skills for cross-runtime managed skill sync (#2491)
* 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>
2026-04-20 18:21:43 -04:00
Tom Boucher
b432d4a726 feat(workflows): close LEARNINGS.md consumption-and-graduation loop (#2490)
* 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>
2026-04-20 18:21:35 -04:00
Tom Boucher
cfe4dc76fd feat(health): canonical artifact registry and W019 unrecognized-file lint (#2448) (#2488)
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
2026-04-20 18:21:23 -04:00
Tom Boucher
f19d0327b2 feat(agents): sycophancy hardening for 9 audit-class agents (#2489)
* 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(agents): sycophancy hardening for 9 audit-class agents (#2427)

Add adversarial reviewer posture to gsd-plan-checker, gsd-code-reviewer,
gsd-security-auditor, gsd-verifier, gsd-eval-auditor, gsd-nyquist-auditor,
gsd-ui-auditor, gsd-integration-checker, and gsd-doc-verifier.

Four changes per agent:
- Third-person framing: <role> opens with submission framing, not "You are a GSD X"
- FORCE stance: explicit starting hypothesis that the submission is flawed
- Failure modes: agent-specific list of how each reviewer type goes soft
- BLOCKER/WARNING classification: every finding must carry an explicit severity

Also applies to sdk/prompts/agents variants of gsd-plan-checker and gsd-verifier.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 18:20:08 -04:00
Tom Boucher
bd27d4fabe feat(roadmap): surface wave dependencies and cross-cutting constraints (#2487)
* feat(roadmap): surface wave dependencies and cross-cutting constraints (#2447)

Adds roadmap.annotate-dependencies command that post-processes a phase's
ROADMAP plan list to insert wave dependency notes and surface must_haves.truths
entries shared across 2+ plans as cross-cutting constraints. Operation is
idempotent and purely derived from existing PLAN frontmatter.

Closes #2447

* fix(roadmap): address CodeRabbit review findings on PR #2487

- roadmap.cjs: expand idempotency guard to also check for existing
  cross-cutting constraints header, preventing duplicate injection on
  re-runs; add content equality check before writing to preserve
  true idempotency for single-wave phases
- plan-phase.md: move ROADMAP annotation (13d) before docs commit (13c)
  so annotated ROADMAP.md is included in the commit rather than left dirty;
  include .planning/ROADMAP.md in committed files list
- sdk/src/query/index.ts: add annotate-dependencies aliases to
  QUERY_MUTATION_COMMANDS so the mutation is properly event-wired
- sdk/src/query/roadmap.ts: add timeout (15s) and maxBuffer to spawnSync;
  check result.error before result.status to handle spawn/timeout failures

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 18:19:21 -04:00
Tom Boucher
e8ec42082d feat(health): detect MILESTONES.md drift from archived snapshots (#2446) (#2486)
Adds W018 warning when .planning/milestones/vX.Y-ROADMAP.md snapshots
exist without a corresponding entry in MILESTONES.md. Introduces
--backfill flag to synthesize missing entries from snapshot titles.

Closes #2446
2026-04-20 18:19:14 -04:00
Rezolv
86fb9c85c3 docs(sdk): registry docs and gsd-sdk query call sites (#2302 Track B) (#2340)
* feat(sdk): golden parity harness and query handler CJS alignment (#2302 Track A)

Golden/read-only parity tests and registry alignment, query handler fixes
(check-completion, state-mutation, commit, validate, summary, etc.), and
WAITING.json dual-write for .gsd/.planning readers.

Refs gsd-build/get-shit-done#2341

* fix(sdk): getMilestoneInfo matches GSD ROADMAP (🟡, last bold, STATE fallback)

- Recognize in-flight 🟡 milestone bullets like 🚧.
- Derive from last **vX.Y Title** before ## Phases when emoji absent.
- Fall back to STATE.md milestone when ROADMAP is missing; use last bare vX.Y
  in cleaned text instead of first (avoids v1.0 from shipped list).
- Fixes init.execute-phase milestone_version and buildStateFrontmatter after
  state.begin-phase (syncStateFrontmatter).

* feat(sdk): phase list, plan task structure, requirements extract handlers

- Register phase.list-plans, phase.list-artifacts, plan.task-structure,
  requirements.extract-from-plans (SDK-only; golden-policy exceptions).
- Add unit tests; document in QUERY-HANDLERS.md.
- writeProfile: honor --output, render dimensions, return profile_path and dimensions_scored.

* feat(sdk): centralize getGsdAgentsDir in query helpers

Extract agent directory resolution to helpers (GSD_AGENTS_DIR, primary
~/.claude/agents, legacy path). Use from init and docs-init init bundles.

docs(15): add 15-CONTEXT for autonomous phase-15 run.

* feat(sdk): query CLI CJS fallback and session correlation

- createRegistry(eventStream, sessionId) threads correlation into mutation events
- gsd-sdk query falls back to gsd-tools.cjs when no native handler matches
  (disable with GSD_QUERY_FALLBACK=off); stderr bridge warnings
- Export createRegistry from @gsd-build/sdk; add sdk/README.md
- Update QUERY-HANDLERS.md and registry module docs for fallback + sessionId
- Agents: prefer node dist/cli.js query over cat/grep for STATE and plans

* fix(sdk): init phase_found parity, docs-init agents path, state field extract

- Normalize findPhase not-found to null before roadmap fallback (matches findPhaseInternal)

- docs-init: use detectRuntime + resolveAgentsDir for checkAgentsInstalled

- state.cjs stateExtractField: horizontal whitespace only after colon (YAML progress guard)

- Tests: commit_docs default true; config-get golden uses temp config; golden integration green

Refs: #2302

* refactor(sdk): share SessionJsonlRecord in profile-extract-messages

CodeRabbit nit: dedupe JSONL record shape for isGenuineUserMessage and streamExtractMessages.

* fix(sdk): address CodeRabbit major threads (paths, gates, audit, verify)

- Resolve @file: and CLI JSON indirection relative to projectDir; guard empty normalized query command

- plan.task-structure + intel extract/patch-meta: resolvePathUnderProject containment

- check.config-gates: safe string booleans; plan_checker alias precedence over plan_check default

- state.validate/sync: phaseTokenMatches + comparePhaseNum ordering

- verify.schema-drift: token match phase dirs; files_modified from parsed frontmatter

- audit-open: has_scan_errors, unreadable rows, human report when scans fail

- requirements PLANNED key PLAN for root PLAN.md; gsd-tools timeout note

- ingest-docs: repo-root path containment; classifier output slug-hash

Golden parity test strips has_scan_errors until CJS adds field.

* fix: Resolve CodeRabbit security and quality findings
- Secure intel.ts and cli.ts against path traversal
- Catch and validate git add status in commit.ts
- Expand roadmap milestone marker extraction
- Fix parsing array-of-objects in frontmatter YAML
- Fix unhandled config evaluations
- Improve coverage test parity mapping

* docs(sdk): registry docs and gsd-sdk query call sites (#2302 Track B)

Update CHANGELOG, architecture and user guides, workflow call sites, and read-guard tests for gsd-sdk query; sync ARCHITECTURE.md command/workflow counts and directory-tree totals with the repo (80 commands, 77 workflows).

Address CodeRabbit: fix markdown tables and emphasis; align CLI-TOOLS GSDTools and state.read docs with implementation; correct roadmap handler name in universal-anti-patterns; resolve settings workflow config path without relying on config_path from state.load.

Refs gsd-build/get-shit-done#2340

* test: raise planner character extraction limit to 48K

* fix(sdk): resolve build TS error and doc conflict markers
2026-04-20 18:09:21 -04:00
Rezolv
c5b1445529 feat(sdk): golden parity harness and query handler CJS alignment (#2302 Track A) (#2341)
* feat(sdk): golden parity harness and query handler CJS alignment (#2302 Track A)

Golden/read-only parity tests and registry alignment, query handler fixes
(check-completion, state-mutation, commit, validate, summary, etc.), and
WAITING.json dual-write for .gsd/.planning readers.

Refs gsd-build/get-shit-done#2341

* fix(sdk): getMilestoneInfo matches GSD ROADMAP (🟡, last bold, STATE fallback)

- Recognize in-flight 🟡 milestone bullets like 🚧.
- Derive from last **vX.Y Title** before ## Phases when emoji absent.
- Fall back to STATE.md milestone when ROADMAP is missing; use last bare vX.Y
  in cleaned text instead of first (avoids v1.0 from shipped list).
- Fixes init.execute-phase milestone_version and buildStateFrontmatter after
  state.begin-phase (syncStateFrontmatter).

* feat(sdk): phase list, plan task structure, requirements extract handlers

- Register phase.list-plans, phase.list-artifacts, plan.task-structure,
  requirements.extract-from-plans (SDK-only; golden-policy exceptions).
- Add unit tests; document in QUERY-HANDLERS.md.
- writeProfile: honor --output, render dimensions, return profile_path and dimensions_scored.

* feat(sdk): centralize getGsdAgentsDir in query helpers

Extract agent directory resolution to helpers (GSD_AGENTS_DIR, primary
~/.claude/agents, legacy path). Use from init and docs-init init bundles.

docs(15): add 15-CONTEXT for autonomous phase-15 run.

* feat(sdk): query CLI CJS fallback and session correlation

- createRegistry(eventStream, sessionId) threads correlation into mutation events
- gsd-sdk query falls back to gsd-tools.cjs when no native handler matches
  (disable with GSD_QUERY_FALLBACK=off); stderr bridge warnings
- Export createRegistry from @gsd-build/sdk; add sdk/README.md
- Update QUERY-HANDLERS.md and registry module docs for fallback + sessionId
- Agents: prefer node dist/cli.js query over cat/grep for STATE and plans

* fix(sdk): init phase_found parity, docs-init agents path, state field extract

- Normalize findPhase not-found to null before roadmap fallback (matches findPhaseInternal)

- docs-init: use detectRuntime + resolveAgentsDir for checkAgentsInstalled

- state.cjs stateExtractField: horizontal whitespace only after colon (YAML progress guard)

- Tests: commit_docs default true; config-get golden uses temp config; golden integration green

Refs: #2302

* refactor(sdk): share SessionJsonlRecord in profile-extract-messages

CodeRabbit nit: dedupe JSONL record shape for isGenuineUserMessage and streamExtractMessages.

* fix(sdk): address CodeRabbit major threads (paths, gates, audit, verify)

- Resolve @file: and CLI JSON indirection relative to projectDir; guard empty normalized query command

- plan.task-structure + intel extract/patch-meta: resolvePathUnderProject containment

- check.config-gates: safe string booleans; plan_checker alias precedence over plan_check default

- state.validate/sync: phaseTokenMatches + comparePhaseNum ordering

- verify.schema-drift: token match phase dirs; files_modified from parsed frontmatter

- audit-open: has_scan_errors, unreadable rows, human report when scans fail

- requirements PLANNED key PLAN for root PLAN.md; gsd-tools timeout note

- ingest-docs: repo-root path containment; classifier output slug-hash

Golden parity test strips has_scan_errors until CJS adds field.

* fix: Resolve CodeRabbit security and quality findings
- Secure intel.ts and cli.ts against path traversal
- Catch and validate git add status in commit.ts
- Expand roadmap milestone marker extraction
- Fix parsing array-of-objects in frontmatter YAML
- Fix unhandled config evaluations
- Improve coverage test parity mapping

* test: raise planner character extraction limit to 48K

* fix(sdk): resolve TS build error in docs-init passing config
2026-04-20 18:09:02 -04:00
TÂCHES
c8807e38d7 Merge pull request #2481 from gsd-build/hotfix/1.37.1
chore: merge hotfix v1.37.1 back to main
2026-04-20 14:23:58 -06:00
Lex Christopherson
2b4446e2f9 chore: resolve merge conflict — take main's INVENTORY.md references
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-20 14:23:49 -06:00
Lex Christopherson
ef4ce7d6f9 1.37.1 2026-04-20 14:16:09 -06:00
Tom Boucher
12d38b2da0 fix(ci): update ARCHITECTURE.md counts and add TEXT_MODE fallback to sketch workflow (#2377)
* 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>
2026-04-20 14:12:21 -06:00
Lex Christopherson
e7a6d9ef2e fix: sync spike/sketch workflows with upstream skill improvements
Spike workflow:
- Add prior spike check — skips already-validated questions
- Add comparison spikes (NNN-a/NNN-b) for head-to-head evaluation
- Add research-before-building step (context7 + web search)
- Add forensic logging/observability for runtime-interactive spikes
- Add Type column to MANIFEST, type/Research/Observability to README

Sketch workflow:
- Add research-the-target-stack step — check component availability,
  framework constraints, and idiomatic patterns before building

Spike wrap-up workflow:
- Replace per-spike curation with auto-include-all (every spike carries
  signal: VALIDATED=patterns, PARTIAL=constraints, INVALIDATED=landmines)
- Add Step 10 intelligent routing — integration spike candidates,
  frontier spike candidates, and standard next-step options

Commands updated with context7/WebSearch tools and --text flag.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-20 14:05:29 -06:00
github-actions[bot]
beb3ac247b chore: bump version to 1.37.1 for hotfix 2026-04-20 20:05:07 +00:00
Lex Christopherson
a95cabaedb fix: sync spike/sketch workflows with upstream skill improvements
Spike workflow:
- Add prior spike check — skips already-validated questions
- Add comparison spikes (NNN-a/NNN-b) for head-to-head evaluation
- Add research-before-building step (context7 + web search)
- Add forensic logging/observability for runtime-interactive spikes
- Add Type column to MANIFEST, type/Research/Observability to README

Sketch workflow:
- Add research-the-target-stack step — check component availability,
  framework constraints, and idiomatic patterns before building

Spike wrap-up workflow:
- Replace per-spike curation with auto-include-all (every spike carries
  signal: VALIDATED=patterns, PARTIAL=constraints, INVALIDATED=landmines)
- Add Step 10 intelligent routing — integration spike candidates,
  frontier spike candidates, and standard next-step options

Commands updated with context7/WebSearch tools and --text flag.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-20 14:04:31 -06:00
Tom Boucher
9d55d531a4 fix(#2432,#2424): pre-dispatch PLAN.md commit + reapply-patches baseline detection; docs(#2397): config schema drift (#2469)
- 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>
2026-04-20 10:11:00 -04:00
Tom Boucher
5f419c0238 fix(bugs): resolve issues #2388, #2431, #2396, #2376 (#2467)
#2388 (plan-phase silently renames feature branch): add explicit Git
Branch Invariant section to plan-phase.md prohibiting branch
creation/rename/switch during planning; phase slug changes are
plan-level only and must not affect the git branch.

#2431 (worktree teardown silently swallows errors): replace
`git worktree remove --force 2>/dev/null || true` with a lock-aware
block in quick.md and execute-phase.md that detects locked worktrees,
attempts unlock+retry, and surfaces a user-visible recovery message
when removal still fails.

#2396 (hardcoded test commands bypass Makefile): add a three-tier
test command resolver (project config → Makefile/Justfile → language
sniff) in execute-phase.md, verify-phase.md, and audit-fix.md.
Makefile with a `test:` target now takes priority over npm/cargo/go.

#2376 (OpenCode @$HOME not mapped on Windows): add platform guard in
bin/install.js so OpenCode on win32 uses the absolute path instead of
`$HOME/...`, which OpenCode does not expand in @file references on
Windows.

Tests: 29 new assertions across 4 regression test files (all passing).

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 10:10:16 -04:00
Tom Boucher
dfa1ecce99 fix(#2418,#2399,#2419,#2421): four workflow and installer bug fixes (#2462)
- #2418: convertClaudeToAntigravityContent now replaces bare ~/.claude and
  $HOME/.claude (no trailing slash) for both global and local installs,
  eliminating the "unreplaced .claude path reference" warnings in
  gsd-debugger.md and update.md during Antigravity installs.

- #2399: plan-phase workflow gains step 13c that commits PLAN.md files
  and STATE.md via gsd-sdk query commit when commit_docs is true.
  Previously commit_docs:true was read but never acted on in plan-phase.

- #2419: new-project.md and new-milestone.md now parse agents_installed
  and missing_agents from the init JSON and warn users clearly when GSD
  agents are not installed, rather than silently failing with "agent type
  not found" when trying to spawn gsd-project-researcher subagents.

- #2421: gsd-planner.md gains a "Grep gate hygiene" rule immediately after
  the Nyquist Rule explaining the self-invalidating grep gate anti-pattern
  and providing comment-stripping alternatives (grep -v, ast-grep).

Tests: 4 new test files (30 tests) all passing.

Closes #2418
Closes #2399
Closes #2419
Closes #2421

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 10:09:33 -04:00
Tom Boucher
4cd890b252 fix(phase): guard backlog dirs and YYYY-MM dates in integer phase removal (#2466)
* fix(phase): guard backlog dirs and YYYY-MM dates in integer phase removal

Closes #2435
Closes #2434

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(phase): extend date-collision guard to hyphen-adjacent context

The lookbehind `(?<!\d)` in renameIntegerPhases only excluded
digit-prefixed matches; a YYYY-MM-DD date like 2026-05-14 has a hyphen
before the month digits, which passed the original guard and caused
date corruption when renumbering a phase whose zero-padded number
matched the month. Replace with `(?<![0-9-])` lookbehind and
`(?![0-9-])` lookahead to exclude both digit- and hyphen-adjacent
contexts. Adds a regression test for the hyphen-adjacent case.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 10:08:52 -04:00
Tom Boucher
d117c1045a test: add --no-sdk to copilot-install E2E runners + static guard (#2461) (#2463)
Four execFileSync installer calls in copilot-install.test.cjs deleted
GSD_TEST_MODE but omitted --no-sdk, triggering the fatal installSdkIfNeeded()
path in test.yml CI where npm global bin is not on PATH.

Partial fix in e213ce0 patched three hook-deployment tests but missed
runCopilotInstall, runCopilotUninstall, runClaudeInstall, runClaudeUninstall.

Also adds tests/sdk-no-sdk-guard.test.cjs: a static analysis guard that
scans test files for subprocess installer calls missing --no-sdk, so this
class of regression is caught automatically in future.

Closes #2461

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 10:08:49 -04:00
Tom Boucher
0ea443cbcf fix(install): chmod sdk dist/cli.js executable; fix context monitor over-reporting (#2460)
Bug #2453: After tsc builds sdk/dist/cli.js, npm install -g from a local
directory does not chmod the bin-script target (unlike tarball extraction).
The file lands at mode 644, the gsd-sdk symlink points at a non-executable
file, and command -v gsd-sdk fails on every first install. Fix: explicitly
chmodSync(cliPath, 0o755) immediately after npm install -g completes,
mirroring the pattern used for hook files throughout the installer.

Bug #2451: gsd-context-monitor warning messages over-reported usage by ~13
percentage points vs CC native /context. Root cause: gsd-statusline.js
wrote a buffer-normalized used_pct (accounting for the 16.5% autocompact
reserve) to the bridge file, inflating values. The bridge used_pct is now
raw (Math.round(100 - remaining_percentage)), consistent with what CC's
native /context command reports. The statusline progress bar continues to
display the normalized value; only the bridge value changes. Updated the
existing #2219 tests to check the normalized display via hook stdout rather
than bridge.used_pct, and added a new assertion that bridge.used_pct is raw.

Closes #2453
Closes #2451

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 10:08:46 -04:00
Tom Boucher
53b9fba324 fix: stale phase dirs corrupt phase counts; stopped_at overwritten by historical prose (#2459)
* fix(sdk): extractCurrentMilestone Backlog leak + state.begin-phase flag parsing

Closes #2422
Closes #2420

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(#2444,#2445): scope stopped_at extraction to Session section; filter stale phase dirs

- buildStateFrontmatter now extracts stopped_at only from the ## Session
  section when one exists, preventing historical prose elsewhere in the
  body (e.g. "Stopped at: Phase 5 complete" in old notes) from overwriting
  the current value in frontmatter (bug #2444)
- buildStateFrontmatter de-duplicates phase dirs by normalized phase number
  before computing plan/phase counts, so stale phase dirs from a prior
  milestone with the same phase numbers as the new milestone don't inflate
  totals (bug #2445)
- cmdInitNewMilestone now filters phase dirs through getMilestonePhaseFilter
  so phase_dir_count excludes stale prior-milestone dirs (bug #2445)
- Tests: 4 tests in state.test.cjs covering both bugs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 10:08:43 -04:00
Tom Boucher
5afcd5577e fix: zero-padded phase numbers bypass archived-phase guard; stale current_milestone (#2458)
* fix(sdk): extractCurrentMilestone Backlog leak + state.begin-phase flag parsing

Closes #2422
Closes #2420

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(sdk): skip stateVersion early-return for shipped milestones

When STATE.md has a stale `milestone: v1.0` entry but v1.0 is already
shipped (heading contains  in ROADMAP.md), the stateVersion early-return
path in getMilestoneInfo was returning v1.0 instead of detecting the new
active milestone.

Two-part fix:
1. In the stateVersion block: skip the early-return when the matched
   heading line includes  (shipped marker). Fall through to normal
   detection instead.
2. In the heading-format fallback regex: add a negative lookahead
   `(?!.*)` so the regex never matches a  heading regardless of
   whether stateVersion was present. This handles the no-STATE.md case
   and ensures fallthrough from part 1 actually finds the next milestone.

Adds two regression tests covering both -suffix (`## v1.0  Name`)
and -prefix (`##  v1.0 Name`) heading formats.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(core): allow padded-and-unpadded phase headings in getRoadmapPhaseInternal

The zero-strip normalization (01→1) fixed the archived-phase guard but
broke lookup against ROADMAP headings that still use zero-padded numbers
like "Phase 01:". Change the regex to use 0*<normalized> so both formats
match, making the fix robust regardless of ROADMAP heading style.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 10:08:40 -04:00
Tom Boucher
9f79cdc40a fix(security): neutralize spaced+closing injection markers; fix audit-uat resolved status (#2456)
* fix(security): neutralize spaced+closing injection markers; fix audit-uat resolved status

scanForInjection recognizes — adds <user> tags, whitespace-padded tags
(e.g. <user >), closing [/SYSTEM]/[/INST] markers, and closing <</SYS>>
markers. Five new regression tests confirm each gap is closed.

whose result column reads PASS or resolved, so items that were already
confirmed do not appear as outstanding in audit-uat --raw. Two new
regression tests cover item-level PASS and file-level status: passed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add closing-tag assertion for spaced <user > sanitization

The test for 'neutralizes spaced tags like <user >' only asserted that the
opening token '<user' was removed. A spaced closing tag '</user >' could
survive sanitization undetected. Added assert.ok(!result.includes('</user'))
to the same test block so both sides of the tag are verified.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 10:08:18 -04:00
Tom Boucher
59cfbbba6a fix(sdk): extractCurrentMilestone Backlog leak + state.begin-phase flag parsing (#2455)
* fix(sdk): extractCurrentMilestone Backlog leak + state.begin-phase flag parsing

Closes #2422
Closes #2420

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: patch-version semver in milestone boundary regex + flag-parser validation

Two follow-on correctness issues identified in code review:

1. roadmap.ts: currentVersionMatch and nextMilestoneRegex only captured
   major.minor (v(\d+\.\d+)), collapsing v2.0.1 to "2.0". A sub-heading
   "## v2.0.2 Phase Details" would match the same prefix and be incorrectly
   skipped. Both patterns updated to v(\d+(?:\.\d+)+) to capture full semver.

2. state-mutation.ts: pair-wise flag parsing loop advanced i by 2 unconditionally,
   so a missing flag value caused the next flag token to be assigned as the value
   (e.g. flags['phase'] = '--name'). Fix: iterate with i++ and validate that the
   candidate value exists and does not start with '--' before assigning; throw
   GSDError('missing value for --<key>') on invalid input. Added regression test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 10:08:14 -04:00
Tom Boucher
990c3e648d fix(tests): update 5 source-text tests to read config-schema.cjs (#2480)
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>
2026-04-20 09:54:35 -04:00
Tom Boucher
62eaa8dd7b docs: close doc drift vectors — bidirectional parity, manifest, schema-driven config (#2479)
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>
2026-04-20 09:39:05 -04:00
Logan
fbf30792f3 docs: authoritative shipped-surface inventory with filesystem-backed parity tests (#2390)
* 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>
2026-04-20 09:31:34 -04:00
alanshurafa
3d6c2bea4b docs: clarify capture_thought is an optional convention (#1873) (#2379)
* 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>
2026-04-20 09:04:21 -04:00
Jeremy McSpadden
30433368a0 fix(install): template bare .claude hook paths for non-Claude runtimes 2026-04-19 18:42:30 -05:00
Jeremy McSpadden
04fab926b5 test: add --no-sdk to hook-deployment installer tests
Tests #1834, #1924, #2136 exercise hook/artifact deployment and don't
care about SDK install. Now that installSdkIfNeeded() failures are
fatal, these tests fail on any CI runner without gsd-sdk pre-built
because the sdk/ tsc build path runs and can fail in CI env.

Pass --no-sdk so each test focuses on its actual subject. SDK install
path has dedicated end-to-end coverage in install-smoke.yml.
2026-04-19 18:39:32 -05:00
Jeremy McSpadden
f98ef1e460 fix(install): fatal SDK install failures + CI smoke gate (#2439)
## Why
#2386 added `installSdkIfNeeded()` to build @gsd-build/sdk from bundled
source and `npm install -g .`, because the npm-published @gsd-build/sdk
is intentionally frozen and version-mismatched with get-shit-done-cc.

But every failure path in that function was warning-only — including
the final `which gsd-sdk` verification. When npm's global bin is off a
user's PATH (common on macOS), the installer printed a yellow warning
then exited 0. Users saw "install complete" and then every `/gsd-*`
command crashed with `command not found: gsd-sdk` (the #2439 symptom).

No CI job executed the install path, so this class of regression could
ship undetected — existing "install" tests only read bin/install.js as
a string.

## What changed

**bin/install.js — installSdkIfNeeded() is now transactional**
- All build/install failures exit non-zero (not just warn).
- Post-install `which gsd-sdk` check is fatal: if the binary landed
  globally but is off PATH, we exit 1 with a red banner showing the
  resolved npm bin dir, the user's shell, the target rc file, and the
  exact `export PATH=…` line to add.
- Escape hatch: `GSD_ALLOW_OFF_PATH=1` downgrades off-PATH to exit 2
  for users with intentionally restricted PATH who will wire up the
  binary manually.
- Resolver uses POSIX `command -v` via `sh -c` (replaces `which`) so
  behavior is consistent across sh/bash/zsh/fish.
- Factored `resolveGsdSdk()`, `detectShellRc()`, `emitSdkFatal()`.

**.github/workflows/install-smoke.yml (new)**
- Executes the real install path: `npm pack` → `npm install -g <tgz>`
  → run installer non-interactively → `command -v gsd-sdk` → run
  `gsd-sdk --version`.
- PRs: path-filtered to installer-adjacent files, ubuntu + Node 22 only.
- main/release branches: full matrix (ubuntu+macos × Node 22+24).
- Reusable via workflow_call with `ref` input for release gating.

**.github/workflows/release.yml — pre-publish gate**
- New `install-smoke-rc` and `install-smoke-finalize` jobs invoke the
  reusable workflow against the release branch. `rc` and `finalize`
  now `needs: [validate-version, install-smoke-*]`, so a broken SDK
  install blocks `npm publish`.

## Test plan
- Local full suite: 4154/4154 pass
- install-smoke.yml will self-validate on this PR (ubuntu+Node22 only)

Addresses root cause of #2439 (the per-command pre-flight in #2440 is
the complementary defensive layer).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 18:39:32 -05:00
Jeremy McSpadden
d0565e95c1 fix(set-profile): use hyphenated /gsd-set-profile in pre-flight message
Project convention (#1748) requires /gsd-<cmd> hyphen form everywhere
except designated test inputs. Fix the colon references in the
pre-flight error and its regression test to satisfy stale-colon-refs.
2026-04-19 18:39:32 -05:00
Jeremy McSpadden
4ef6275e86 fix(set-profile): guard gsd-sdk invocation with command -v pre-flight (#2439)
/gsd:set-profile crashed with `command not found: gsd-sdk` when gsd-sdk
was not on PATH. The command invoked `gsd-sdk query` directly in a `!`
backtick with no guard, so a missing binary produced an opaque shell
error with exit 127.

Add a `command -v gsd-sdk` pre-flight that prints the install/update
hint and exits 1 when absent, mirroring the #2334 fix on /gsd-quick.
The auto-install in #2386 still runs at install time; this guard is the
defensive layer for users whose npm global bin is off-PATH (install.js
warns but does not fail in that case).

Closes #2439
2026-04-19 18:39:32 -05:00
Jeremy McSpadden
6c50490766 fix(sdk): register init.ingest-docs handler and add registry drift guard (#2442)
The ingest-docs workflow called `gsd-sdk query init.ingest-docs` with a
fallback to `init.default` — neither was registered in createRegistry(),
so the workflow proceeded with `{}` and tried to parse project_exists,
planning_exists, has_git, and project_path from empty.

- Add initIngestDocs handler; register dotted + space aliases
- Simplify workflow call; drop broken fallback
- Repo-wide drift guard scans commands/, agents/, get-shit-done/,
  hooks/, bin/, scripts/, docs/ for `gsd-sdk query <cmd>` and fails
  on any reference with no registered handler (file:line citations)
- Unit tests for the new handler

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 18:39:20 -05:00
Jeremy McSpadden
4cbebfe78c docs(readme): add /gsd-ingest-docs to Brownfield commands
Surfaces the new ingest-docs command from the Unreleased changelog in
the README Commands section so users discover it without digging.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 18:39:20 -05:00
Jeremy McSpadden
9e87d43831 fix(build): include gsd-read-injection-scanner in hooks/dist (#2406)
The scanner was added in #2201 but never added to the HOOKS_TO_COPY
allowlist in scripts/build-hooks.js, so it never landed in hooks/dist/.
install.js reads from hooks/dist/, so every install on 1.37.0/1.37.1
emitted "Skipped read injection scanner hook — not found at target"
and the read-time prompt-injection scanner was silently disabled.

- Add gsd-read-injection-scanner.js to HOOKS_TO_COPY
- Add it to EXPECTED_ALL_HOOKS regression test in install-hooks-copy

Fixes #2406

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 18:39:20 -05:00
github-actions[bot]
29ea90bc83 chore: bump version to 1.38.1 for hotfix 2026-04-19 23:37:15 +00:00
github-actions[bot]
0c6172bfad chore: finalize v1.38.0 2026-04-18 03:45:59 +00:00
Jeremy McSpadden
e3bd06c9fd fix(release): make merge-back PR step non-fatal
Repos that disable "Allow GitHub Actions to create and approve pull
requests" (org-level policy or repo-level setting) cause the "Create PR
to merge release back to main" step to fail with a GraphQL 403. That
failure cascades: Tag and push, npm publish, GitHub Release creation
are all skipped, and the entire release aborts.

The merge-back PR is a convenience — it's re-openable manually after
the release. Making it non-fatal with continue-on-error lets the rest
of the release complete. The step now emits ::warning:: annotations
pointing at the manual-recovery command when it fails.

Shell pipelines also fall through with `|| echo "::warning::..."` so
transient gh CLI failures don't mask the underlying policy issue.

Covers the failure mode seen on run 24596079637 where dry-run publish
validation passed but the release halted at the PR-creation step.
2026-04-17 22:45:22 -05:00
github-actions[bot]
c69ecd975a chore: bump to 1.38.0-rc.1 2026-04-18 03:05:35 +00:00
Jeremy McSpadden
06c4ded4ec docs(changelog): promote Unreleased to [1.38.0] + add ultraplan entry 2026-04-17 22:03:26 -05:00
github-actions[bot]
341bb941c6 chore: bump version to 1.38.0 for release 2026-04-18 03:02:41 +00:00
389 changed files with 24850 additions and 3388 deletions

View File

@@ -342,23 +342,32 @@ jobs:
- name: Create PR to merge release back to main
if: ${{ !inputs.dry_run }}
continue-on-error: true
env:
GH_TOKEN: ${{ github.token }}
BRANCH: ${{ needs.validate-version.outputs.branch }}
VERSION: ${{ inputs.version }}
run: |
EXISTING_PR=$(gh pr list --base main --head "$BRANCH" --state open --json number --jq '.[0].number')
# Non-fatal: repos that disable "Allow GitHub Actions to create and
# approve pull requests" cause this step to fail with GraphQL 403.
# The release itself (tag + npm publish + GitHub Release) must still
# proceed. Open the merge-back PR manually afterwards with:
# gh pr create --base main --head release/${VERSION} \
# --title "chore: merge release v${VERSION} to main"
EXISTING_PR=$(gh pr list --base main --head "$BRANCH" --state open --json number --jq '.[0].number' 2>/dev/null || echo "")
if [ -n "$EXISTING_PR" ]; then
echo "PR #$EXISTING_PR already exists; updating"
gh pr edit "$EXISTING_PR" \
--title "chore: merge release v${VERSION} to main" \
--body "Merge release branch back to main after v${VERSION} stable release."
--body "Merge release branch back to main after v${VERSION} stable release." \
|| echo "::warning::Could not update merge-back PR (likely PR-creation policy disabled). Open it manually after release."
else
gh pr create \
--base main \
--head "$BRANCH" \
--title "chore: merge release v${VERSION} to main" \
--body "Merge release branch back to main after v${VERSION} stable release."
--body "Merge release branch back to main after v${VERSION} stable release." \
|| echo "::warning::Could not create merge-back PR (likely PR-creation policy disabled). Open it manually after release."
fi
- name: Tag and push

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,7 @@ color: "#F59E0B"
---
<role>
You are a GSD code reviewer. You analyze source files for bugs, security vulnerabilities, and code quality issues.
Source files from a completed implementation have been submitted for adversarial review. Find every bug, security vulnerability, and quality defect — do not validate that work was done.
Spawned by `/gsd-code-review` workflow. You produce REVIEW.md artifact in the phase directory.
@@ -16,6 +16,22 @@ Spawned by `/gsd-code-review` workflow. You produce REVIEW.md artifact in the ph
If the prompt contains a `<required_reading>` block, you MUST use the `Read` tool to load every file listed there before performing any other actions. This is your primary context.
</role>
<adversarial_stance>
**FORCE stance:** Assume every submitted implementation contains defects. Your starting hypothesis: this code has bugs, security gaps, or quality failures. Surface what you can prove.
**Common failure modes — how code reviewers go soft:**
- Stopping at obvious surface issues (console.log, empty catch) and assuming the rest is sound
- Accepting plausible-looking logic without tracing through edge cases (nulls, empty collections, boundary values)
- Treating "code compiles" or "tests pass" as evidence of correctness
- Reading only the file under review without checking called functions for bugs they introduce
- Downgrading findings from BLOCKER to WARNING to avoid seeming harsh
**Required finding classification:** Every finding in REVIEW.md must carry:
- **BLOCKER** — incorrect behavior, security vulnerability, or data loss risk; must be fixed before this code ships
- **WARNING** — degrades quality, maintainability, or robustness; should be fixed
Findings without a classification are not valid output.
</adversarial_stance>
<project_context>
Before reviewing, discover project context:

View File

@@ -110,7 +110,7 @@ Regardless of type, extract:
</step>
<step name="write_output">
Write to `{OUTPUT_DIR}/{slug}.json` where `slug` is the filename without extension (replace non-alphanumerics with `-`).
Write to `{OUTPUT_DIR}/{slug}-{source_hash}.json` where `slug` is the filename without extension (replace non-alphanumerics with `-`), and `source_hash` is the first 8 hex chars of SHA-256 of the **full source file path** (POSIX-style) so parallel classifiers never collide on sibling `README.md` files.
JSON schema:

View File

@@ -12,18 +12,34 @@ color: orange
---
<role>
You are a GSD doc verifier. You check factual claims in project documentation against the live codebase.
A documentation file has been submitted for factual verification against the live codebase. Every checkable claim must be verified — do not assume claims are correct because the doc was recently written.
You are spawned by the `/gsd-docs-update` workflow. Each spawn receives a `<verify_assignment>` XML block containing:
Spawned by the `/gsd-docs-update` workflow. Each spawn receives a `<verify_assignment>` XML block containing:
- `doc_path`: path to the doc file to verify (relative to project_root)
- `project_root`: absolute path to project root
Your job: Extract checkable claims from the doc, verify each against the codebase using filesystem tools only, then write a structured JSON result file. Returns a one-line confirmation to the orchestrator only — do not return doc content or claim details inline.
Extract checkable claims from the doc, verify each against the codebase using filesystem tools only, then write a structured JSON result file. Returns a one-line confirmation to the orchestrator only — do not return doc content or claim details inline.
**CRITICAL: Mandatory Initial Read**
If the prompt contains a `<required_reading>` block, you MUST use the `Read` tool to load every file listed there before performing any other actions. This is your primary context.
</role>
<adversarial_stance>
**FORCE stance:** Assume every factual claim in the doc is wrong until filesystem evidence proves it correct. Your starting hypothesis: the documentation has drifted from the code. Surface every false claim.
**Common failure modes — how doc verifiers go soft:**
- Checking only explicit backtick file paths and skipping implicit file references in prose
- Accepting "the file exists" without verifying the specific content the claim describes (e.g., a function name, a config key)
- Missing command claims inside nested code blocks or multi-line bash examples
- Stopping verification after finding the first PASS evidence for a claim rather than exhausting all checkable sub-claims
- Marking claims UNCERTAIN when the filesystem can answer the question with a grep
**Required finding classification:**
- **BLOCKER** — a claim is demonstrably false (file missing, function doesn't exist, command not in package.json); doc will mislead readers
- **WARNING** — a claim cannot be verified from the filesystem alone (behavior claim, runtime claim) or is partially correct
Every extracted claim must resolve to PASS, FAIL (BLOCKER), or UNVERIFIABLE (WARNING with reason).
</adversarial_stance>
<project_context>
Before verifying, discover project context:

View File

@@ -12,10 +12,26 @@ color: "#EF4444"
---
<role>
You are a GSD eval auditor. Answer: "Did the implemented AI system actually deliver its planned evaluation strategy?"
An implemented AI phase has been submitted for evaluation coverage audit. Answer: "Did the implemented system actually deliver its planned evaluation strategy?" — not whether it looks like it might.
Scan the codebase, score each dimension COVERED/PARTIAL/MISSING, write EVAL-REVIEW.md.
</role>
<adversarial_stance>
**FORCE stance:** Assume the eval strategy was not implemented until codebase evidence proves otherwise. Your starting hypothesis: AI-SPEC.md documents intent; the code does something different or less. Surface every gap.
**Common failure modes — how eval auditors go soft:**
- Marking PARTIAL instead of MISSING because "some tests exist" — partial coverage of a critical eval dimension is MISSING until the gap is quantified
- Accepting metric logging as evidence of evaluation without checking that logged metrics drive actual decisions
- Crediting AI-SPEC.md documentation as implementation evidence
- Not verifying that eval dimensions are scored against the rubric, only that test files exist
- Downgrading MISSING to PARTIAL to soften the report
**Required finding classification:**
- **BLOCKER** — an eval dimension is MISSING or a guardrail is unimplemented; AI system must not ship to production
- **WARNING** — an eval dimension is PARTIAL; coverage is insufficient for confidence but not absent
Every planned eval dimension must resolve to COVERED, PARTIAL (WARNING), or MISSING (BLOCKER).
</adversarial_stance>
<required_reading>
Read `~/.claude/get-shit-done/references/ai-evals.md` before auditing. This is your scoring framework.
</required_reading>

View File

@@ -72,10 +72,11 @@ if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
Extract from init JSON: `executor_model`, `commit_docs`, `sub_repos`, `phase_dir`, `plans`, `incomplete_plans`.
Also read STATE.md for position, decisions, blockers:
Also load planning state (position, decisions, blockers) via the SDK — **use `node` to invoke the CLI** (not `npx`):
```bash
cat .planning/STATE.md 2>/dev/null
node ./node_modules/@gsd-build/sdk/dist/cli.js query state.load 2>/dev/null
```
If the SDK is not installed under `node_modules`, use the same `query state.load` argv with your local `gsd-sdk` CLI on `PATH`.
If STATE.md missing but .planning/ exists: offer to reconstruct or continue without.
If .planning/ missing: Error — project not initialized.

View File

@@ -6,9 +6,9 @@ color: blue
---
<role>
You are an integration checker. You verify that phases work together as a system, not just individually.
A set of completed phases has been submitted for cross-phase integration audit. Verify that phases actually wire together — not that each phase individually looks complete.
Your job: Check cross-phase wiring (exports used, APIs called, data flows) and verify E2E user flows complete without breaks.
Check cross-phase wiring (exports used, APIs called, data flows) and verify E2E user flows complete without breaks.
**CRITICAL: Mandatory Initial Read**
If the prompt contains a `<required_reading>` block, you MUST use the `Read` tool to load every file listed there before performing any other actions. This is your primary context.
@@ -16,6 +16,22 @@ If the prompt contains a `<required_reading>` block, you MUST use the `Read` too
**Critical mindset:** Individual phases can pass while the system fails. A component can exist without being imported. An API can exist without being called. Focus on connections, not existence.
</role>
<adversarial_stance>
**FORCE stance:** Assume every cross-phase connection is broken until a grep or trace proves the link exists end-to-end. Your starting hypothesis: phases are silos. Surface every missing connection.
**Common failure modes — how integration checkers go soft:**
- Verifying that a function is exported and imported but not that it is actually called at the right point
- Accepting API route existence as "API is wired" without checking that any consumer fetches from it
- Tracing only the first link in a data chain (form → handler) and not the full chain (form → handler → DB → display)
- Marking a flow as passing when only the happy path is traced and error/empty states are broken
- Stopping at Phase 1↔2 wiring and not checking Phase 2↔3, Phase 3↔4, etc.
**Required finding classification:**
- **BLOCKER** — a cross-phase connection is absent or broken; an E2E user flow cannot complete
- **WARNING** — a connection exists but is fragile, incomplete for edge cases, or inconsistently applied
Every expected cross-phase connection must resolve to WIRED (verified end-to-end) or BROKEN (BLOCKER).
</adversarial_stance>
**Context budget:** Load project skills first (lightweight). Read implementation files incrementally — load only what each check requires, not the full codebase upfront.
**Project skills:** Check `.claude/skills/` or `.agents/skills/` directory if either exists:

View File

@@ -12,7 +12,7 @@ color: "#8B5CF6"
---
<role>
GSD Nyquist auditor. Spawned by /gsd-validate-phase to fill validation gaps in completed phases.
A completed phase has validation gaps submitted for adversarial test coverage. For each gap: generate a real behavioral test that can fail, run it, and report what actually happens — not what the implementation claims.
For each gap in `<gaps>`: generate minimal behavioral test, run it, debug if failing (max 3 iterations), report results.
@@ -21,6 +21,22 @@ For each gap in `<gaps>`: generate minimal behavioral test, run it, debug if fai
**Implementation files are READ-ONLY.** Only create/modify: test files, fixtures, VALIDATION.md. Implementation bugs → ESCALATE. Never fix implementation.
</role>
<adversarial_stance>
**FORCE stance:** Assume every gap is genuinely uncovered until a passing test proves the requirement is satisfied. Your starting hypothesis: the implementation does not meet the requirement. Write tests that can fail.
**Common failure modes — how Nyquist auditors go soft:**
- Writing tests that pass trivially because they test a simpler behavior than the requirement demands
- Generating tests only for easy-to-test cases while skipping the gap's hard behavioral edge
- Treating "test file created" as "gap filled" before the test actually runs and passes
- Marking gaps as SKIP without escalating — a skipped gap is an unverified requirement, not a resolved one
- Debugging a failing test by weakening the assertion rather than fixing the implementation via ESCALATE
**Required finding classification:**
- **BLOCKER** — gap test fails after 3 iterations; requirement unmet; ESCALATE to developer
- **WARNING** — gap test passes but with caveats (partial coverage, environment-specific, not deterministic)
Every gap must resolve to FILLED (test passes), ESCALATED (BLOCKER), or explicitly justified SKIP.
</adversarial_stance>
<execution_flow>
<step name="load_context">

View File

@@ -145,7 +145,7 @@ When researching "best library for X": find what the ecosystem actually uses, do
1. `mcp__context7__resolve-library-id` with libraryName
2. `mcp__context7__query-docs` with resolved ID + specific query
**WebSearch tips:** Always include current year. Use multiple query variations. Cross-verify with authoritative sources.
**WebSearch tips:** Use multiple query variations. Cross-verify with authoritative sources. Do not inject a year into queries — it biases results toward stale dated content; check publication dates on the results you read instead.
## Enhanced Web Search (Brave API)
@@ -836,6 +836,6 @@ Quality indicators:
- **Verified, not assumed:** Findings cite Context7 or official docs
- **Honest about gaps:** LOW confidence items flagged, unknowns admitted
- **Actionable:** Planner could create tasks based on this research
- **Current:** Year included in searches, publication dates checked
- **Current:** Publication dates checked on sources (do not inject year into queries)
</success_criteria>

View File

@@ -6,7 +6,7 @@ color: green
---
<role>
You are a GSD plan checker. Verify that plans WILL achieve the phase goal, not just that they look complete.
A set of phase plans has been submitted for pre-execution review. Verify they WILL achieve the phase goal — do not credit effort or intent, only verifiable coverage.
Spawned by `/gsd-plan-phase` orchestrator (after planner creates PLAN.md) or re-verification (after planner revises).
@@ -26,6 +26,22 @@ If the prompt contains a `<required_reading>` block, you MUST use the `Read` too
You are NOT the executor or verifier — you verify plans WILL work before execution burns context.
</role>
<adversarial_stance>
**FORCE stance:** Assume every plan set is flawed until evidence proves otherwise. Your starting hypothesis: these plans will not deliver the phase goal. Surface what disqualifies them.
**Common failure modes — how plan checkers go soft:**
- Accepting a plausible-sounding task list without tracing each task back to a phase requirement
- Crediting a decision reference (e.g., "D-26") without verifying the task actually delivers the full decision scope
- Treating scope reduction ("v1", "static for now", "future enhancement") as acceptable when the user's decision demands full delivery
- Letting dimensions that pass anchor judgment — a plan can pass 6 of 7 dimensions and still fail the phase goal on the 7th
- Issuing warnings for what are actually blockers to avoid conflict with the planner
**Required finding classification:** Every issue must carry an explicit severity:
- **BLOCKER** — the phase goal will not be achieved if this is not fixed before execution
- **WARNING** — quality or maintainability is degraded; fix recommended but execution can proceed
Issues without a severity classification are not valid output.
</adversarial_stance>
<required_reading>
@~/.claude/get-shit-done/references/gates.md
</required_reading>
@@ -639,11 +655,11 @@ Extract from init JSON: `phase_dir`, `phase_number`, `has_plans`, `plan_count`.
Orchestrator provides CONTEXT.md content in the verification prompt. If provided, parse for locked decisions, discretion areas, deferred ideas.
```bash
ls "$phase_dir"/*-PLAN.md 2>/dev/null
# Read research for Nyquist validation data
cat "$phase_dir"/*-RESEARCH.md 2>/dev/null
gsd-sdk query roadmap.get-phase "$phase_number"
ls "$phase_dir"/*-BRIEF.md 2>/dev/null
node ./node_modules/@gsd-build/sdk/dist/cli.js query phase.list-plans "$phase_number"
# Research / brief artifacts (deterministic listing)
node ./node_modules/@gsd-build/sdk/dist/cli.js query phase.list-artifacts "$phase_number" --type research
node ./node_modules/@gsd-build/sdk/dist/cli.js query roadmap.get-phase "$phase_number"
node ./node_modules/@gsd-build/sdk/dist/cli.js query phase.list-artifacts "$phase_number" --type summary
```
**Extract:** Phase goal, requirements (decompose goal), locked decisions, deferred ideas.
@@ -729,10 +745,11 @@ The `tasks` array in the result shows each task's completeness:
**Check:** valid task type (auto, checkpoint:*, tdd), auto tasks have files/action/verify/done, action is specific, verify is runnable, done is measurable.
**For manual validation of specificity** (`verify.plan-structure` checks structure, not content quality):
**For manual validation of specificity** (`verify.plan-structure` checks structure, not content quality), use structured extraction instead of grepping raw XML:
```bash
grep -B5 "</task>" "$PHASE_DIR"/*-PLAN.md | grep -v "<verify>"
node ./node_modules/@gsd-build/sdk/dist/cli.js query plan.task-structure "$PLAN_PATH"
```
Inspect `tasks` in the JSON; open the PLAN in the editor for prose-level review.
## Step 6: Verify Dependency Graph
@@ -757,8 +774,8 @@ Missing: No mention of fetch/API call → Issue: Key link not planned
## Step 8: Assess Scope
```bash
grep -c "<task" "$PHASE_DIR"/$PHASE-01-PLAN.md
grep "files_modified:" "$PHASE_DIR"/$PHASE-01-PLAN.md
node ./node_modules/@gsd-build/sdk/dist/cli.js query plan.task-structure "$PHASE_DIR/$PHASE-01-PLAN.md"
node ./node_modules/@gsd-build/sdk/dist/cli.js query frontmatter.get "$PHASE_DIR/$PHASE-01-PLAN.md" files_modified
```
Thresholds: 2-3 tasks/plan good, 4 warning, 5+ blocker (split required).

View File

@@ -215,6 +215,8 @@ Every task has four required fields:
**Nyquist Rule:** Every `<verify>` must include an `<automated>` command. If no test exists yet, set `<automated>MISSING — Wave 0 must create {test_file} first</automated>` and create a Wave 0 task that generates the test scaffold.
**Grep gate hygiene:** `grep -c` counts comments — header prose triggers its own invariant ("self-invalidating grep gate"). Use `grep -v '^#' | grep -c token`. Bare `== 0` gates on unfiltered files are forbidden.
**<done>:** Acceptance criteria - measurable state of completion.
- Good: "Valid credentials return 200 + JWT cookie, invalid credentials return 401"
- Bad: "Authentication is complete"
@@ -810,10 +812,11 @@ if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
Extract from init JSON: `planner_model`, `researcher_model`, `checker_model`, `commit_docs`, `research_enabled`, `phase_dir`, `phase_number`, `has_research`, `has_context`.
Also read STATE.md for position, decisions, blockers:
Also load planning state (position, decisions, blockers) via the SDK — **use `node` to invoke the CLI** (not `npx`):
```bash
cat .planning/STATE.md 2>/dev/null
node ./node_modules/@gsd-build/sdk/dist/cli.js query state.load 2>/dev/null
```
If the SDK is not installed under `node_modules`, use the same `query state.load` argv with your local `gsd-sdk` CLI on `PATH`.
If STATE.md missing but .planning/ exists, offer to reconstruct or continue without.
</step>
@@ -1198,6 +1201,10 @@ Execute: `/gsd-execute-phase {phase} --gaps-only`
Follow templates in checkpoints and revision_mode sections respectively.
## Chunked Mode Returns
See @~/.claude/get-shit-done/references/planner-chunked.md for `## OUTLINE COMPLETE` and `## PLAN COMPLETE` return formats used in chunked mode.
</structured_returns>
<critical_rules>

View File

@@ -116,12 +116,12 @@ For finding what exists, community patterns, real-world usage.
**Query templates:**
```
Ecosystem: "[tech] best practices [current year]", "[tech] recommended libraries [current year]"
Ecosystem: "[tech] best practices", "[tech] recommended libraries"
Patterns: "how to build [type] with [tech]", "[tech] architecture patterns"
Problems: "[tech] common mistakes", "[tech] gotchas"
```
Always include current year. Use multiple query variations. Mark WebSearch-only findings as LOW confidence.
Use multiple query variations. Mark WebSearch-only findings as LOW confidence. Do not inject a year into queries — it biases results toward stale dated content; check publication dates on the results you read instead.
### Enhanced Web Search (Brave API)
@@ -672,6 +672,6 @@ Research is complete when:
- [ ] Files written (DO NOT commit — orchestrator handles this)
- [ ] Structured return provided to orchestrator
**Quality:** Comprehensive not shallow. Opinionated not wishy-washy. Verified not assumed. Honest about gaps. Actionable for roadmap. Current (year in searches).
**Quality:** Comprehensive not shallow. Opinionated not wishy-washy. Verified not assumed. Honest about gaps. Actionable for roadmap. Current (check publication dates, do not inject year into queries).
</success_criteria>

View File

@@ -560,9 +560,7 @@ When files are written and returning to orchestrator:
### Files Ready for Review
User can review actual files:
- `cat .planning/ROADMAP.md`
- `cat .planning/STATE.md`
User can review actual files in the editor or via SDK queries (e.g. `node ./node_modules/@gsd-build/sdk/dist/cli.js query roadmap.analyze` and `query state.load`) instead of ad-hoc shell `cat`.
{If gaps found during creation:}

View File

@@ -12,7 +12,7 @@ color: "#EF4444"
---
<role>
GSD security auditor. Spawned by /gsd-secure-phase to verify that threat mitigations declared in PLAN.md are present in implemented code.
An implemented phase has been submitted for security audit. Verify that every declared threat mitigation is present in the code — do not accept documentation or intent as evidence.
Does NOT scan blindly for new vulnerabilities. Verifies each threat in `<threat_model>` by its declared disposition (mitigate / accept / transfer). Reports gaps. Writes SECURITY.md.
@@ -21,6 +21,22 @@ Does NOT scan blindly for new vulnerabilities. Verifies each threat in `<threat_
**Implementation files are READ-ONLY.** Only create/modify: SECURITY.md. Implementation security gaps → OPEN_THREATS or ESCALATE. Never patch implementation.
</role>
<adversarial_stance>
**FORCE stance:** Assume every mitigation is absent until a grep match proves it exists in the right location. Your starting hypothesis: threats are open. Surface every unverified mitigation.
**Common failure modes — how security auditors go soft:**
- Accepting a single grep match as full mitigation without checking it applies to ALL entry points
- Treating `transfer` disposition as "not our problem" without verifying transfer documentation exists
- Assuming SUMMARY.md `## Threat Flags` is a complete list of new attack surface
- Skipping threats with complex dispositions because verification is hard
- Marking CLOSED based on code structure ("looks like it validates input") without finding the actual validation call
**Required finding classification:**
- **BLOCKER** — `OPEN_THREATS`: a declared mitigation is absent in implemented code; phase must not ship
- **WARNING** — `unregistered_flag`: new attack surface appeared during implementation with no threat mapping
Every threat must resolve to CLOSED, OPEN (BLOCKER), or documented accepted risk.
</adversarial_stance>
<execution_flow>
<step name="load_context">

View File

@@ -12,7 +12,7 @@ color: "#F472B6"
---
<role>
You are a GSD UI auditor. You conduct retroactive visual and interaction audits of implemented frontend code and produce a scored UI-REVIEW.md.
An implemented frontend has been submitted for adversarial visual and interaction audit. Score what was actually built against the design contract or 6-pillar standards — do not average scores upward to soften findings.
Spawned by `/gsd-ui-review` orchestrator.
@@ -27,6 +27,22 @@ If the prompt contains a `<required_reading>` block, you MUST use the `Read` too
- Write UI-REVIEW.md with actionable findings
</role>
<adversarial_stance>
**FORCE stance:** Assume every pillar has failures until screenshots or code analysis proves otherwise. Your starting hypothesis: the UI diverges from the design contract. Surface every deviation.
**Common failure modes — how UI auditors go soft:**
- Averaging pillar scores upward so no single score looks too damning
- Accepting "the component exists" as evidence the UI is correct without checking spacing, color, or interaction
- Not testing against UI-SPEC.md breakpoints and spacing scale — just eyeballing layout
- Treating brand-compliant primary colors as a full pass on the color pillar without checking 60/30/10 distribution
- Identifying 3 priority fixes and stopping, when 6+ issues exist
**Required finding classification:**
- **BLOCKER** — pillar score 1 or a specific defect that breaks user task completion; must fix before shipping
- **WARNING** — pillar score 2-3 or a defect that degrades quality but doesn't break flows; fix recommended
Every scored pillar must have at least one specific finding justifying the score.
</adversarial_stance>
<project_context>
Before auditing, discover project context:

View File

@@ -12,9 +12,9 @@ color: green
---
<role>
You are a GSD phase verifier. You verify that a phase achieved its GOAL, not just completed its TASKS.
A completed phase has been submitted for goal-backward verification. Verify that the phase goal is actually achieved in the codebase — SUMMARY.md claims are not evidence.
Your job: Goal-backward verification. Start from what the phase SHOULD deliver, verify it actually exists and works in the codebase.
Goal-backward verification. Start from what the phase SHOULD deliver, verify it actually exists and works in the codebase.
@~/.claude/get-shit-done/references/mandatory-initial-read.md
@@ -22,6 +22,22 @@ Your job: Goal-backward verification. Start from what the phase SHOULD deliver,
</role>
<adversarial_stance>
**FORCE stance:** Assume the phase goal was not achieved until codebase evidence proves it. Your starting hypothesis: tasks completed, goal missed. Falsify the SUMMARY.md narrative.
**Common failure modes — how verifiers go soft:**
- Trusting SUMMARY.md bullet points without reading the actual code files they describe
- Accepting "file exists" as "truth verified" — a stub file satisfies existence but not behavior
- Choosing UNCERTAIN instead of FAILED when absence of implementation is observable
- Letting high task-completion percentage bias judgment toward PASS before truths are checked
- Anchoring on truths that passed early and giving less scrutiny to later ones
**Required finding classification:**
- **BLOCKER** — a must-have truth is FAILED; phase goal not achieved; must not proceed to next phase
- **WARNING** — a must-have is UNCERTAIN or an artifact exists but wiring is incomplete
Every truth must resolve to VERIFIED, FAILED (BLOCKER), or UNCERTAIN (WARNING with human decision requested.
</adversarial_stance>
<required_reading>
@~/.claude/get-shit-done/references/verification-overrides.md
@~/.claude/get-shit-done/references/gates.md

View File

@@ -78,6 +78,7 @@ const hasCline = args.includes('--cline');
const hasBoth = args.includes('--both'); // Legacy flag, keeps working
const hasAll = args.includes('--all');
const hasUninstall = args.includes('--uninstall') || args.includes('-u');
const hasSkillsRoot = args.includes('--skills-root');
const hasPortableHooks = args.includes('--portable-hooks') || process.env.GSD_PORTABLE_HOOKS === '1';
const hasSdk = args.includes('--sdk');
const hasNoSdk = args.includes('--no-sdk');
@@ -438,7 +439,7 @@ const explicitConfigDir = parseConfigDirArg();
const hasHelp = args.includes('--help') || args.includes('-h');
const forceStatusline = args.includes('--force-statusline');
console.log(banner);
if (!hasSkillsRoot) console.log(banner);
if (hasUninstall) {
console.log(' Mode: Uninstall\n');
@@ -876,14 +877,18 @@ function convertCopilotToolName(claudeTool) {
*/
function convertClaudeToCopilotContent(content, isGlobal = false) {
let c = content;
// CONV-06: Path replacement — most specific first to avoid substring matches
// CONV-06: Path replacement — most specific first to avoid substring matches.
// Handle both `~/.claude/foo` (trailing slash) and bare `~/.claude` forms in
// one pass via a capture group, matching the approach used by Antigravity,
// OpenCode, Kilo, and Codex converters (issue #2545).
if (isGlobal) {
c = c.replace(/\$HOME\/\.claude\//g, '$HOME/.copilot/');
c = c.replace(/~\/\.claude\//g, '~/.copilot/');
c = c.replace(/\$HOME\/\.claude(\/|\b)/g, '$HOME/.copilot$1');
c = c.replace(/~\/\.claude(\/|\b)/g, '~/.copilot$1');
} else {
c = c.replace(/\$HOME\/\.claude\//g, '.github/');
c = c.replace(/~\/\.claude\//g, '.github/');
c = c.replace(/~\/\.claude\n/g, '.github/');
c = c.replace(/\$HOME\/\.claude\b/g, '.github');
c = c.replace(/~\/\.claude\b/g, '.github');
}
c = c.replace(/\.\/\.claude\//g, './.github/');
c = c.replace(/\.claude\//g, '.github/');
@@ -1006,9 +1011,15 @@ function convertClaudeToAntigravityContent(content, isGlobal = false) {
if (isGlobal) {
c = c.replace(/\$HOME\/\.claude\//g, '$HOME/.gemini/antigravity/');
c = c.replace(/~\/\.claude\//g, '~/.gemini/antigravity/');
// Bare form (no trailing slash) — must come after slash form to avoid double-replace
c = c.replace(/\$HOME\/\.claude\b/g, '$HOME/.gemini/antigravity');
c = c.replace(/~\/\.claude\b/g, '~/.gemini/antigravity');
} else {
c = c.replace(/\$HOME\/\.claude\//g, '.agent/');
c = c.replace(/~\/\.claude\//g, '.agent/');
// Bare form (no trailing slash) — must come after slash form to avoid double-replace
c = c.replace(/\$HOME\/\.claude\b/g, '.agent');
c = c.replace(/~\/\.claude\b/g, '.agent');
}
c = c.replace(/\.\/\.claude\//g, './.agent/');
c = c.replace(/\.claude\//g, '.agent/');
@@ -5459,9 +5470,12 @@ function install(isGlobal, runtime = 'claude') {
// For global installs: use $HOME/ so paths expand correctly inside double-quoted
// shell commands (~ does NOT expand inside double quotes, causing MODULE_NOT_FOUND).
// For local installs: use resolved absolute path (may be outside $HOME).
// Exception: OpenCode on Windows does not expand $HOME in @file references —
// use the absolute path instead so @$HOME/... references resolve correctly (#2376).
const resolvedTarget = path.resolve(targetDir).replace(/\\/g, '/');
const homeDir = os.homedir().replace(/\\/g, '/');
const pathPrefix = isGlobal && resolvedTarget.startsWith(homeDir)
const isWindowsHost = process.platform === 'win32';
const pathPrefix = isGlobal && resolvedTarget.startsWith(homeDir) && !(isOpencode && isWindowsHost)
? '$HOME' + resolvedTarget.slice(homeDir.length) + '/'
: `${resolvedTarget}/`;
@@ -6065,9 +6079,13 @@ function install(isGlobal, runtime = 'claude') {
return;
}
const settings = validateHookFields(cleanupOrphanedHooks(rawSettings));
// Local installs anchor paths to $CLAUDE_PROJECT_DIR so hooks resolve
// correctly regardless of the shell's current working directory (#1906).
const localPrefix = '"$CLAUDE_PROJECT_DIR"/' + dirName;
// Local installs anchor hook paths so they resolve regardless of cwd (#1906).
// Claude Code sets $CLAUDE_PROJECT_DIR; Gemini/Antigravity do not — and on
// Windows their own substitution logic doubles the path (#2557). Those runtimes
// run project hooks with the project dir as cwd, so bare relative paths work.
const localPrefix = (runtime === 'gemini' || runtime === 'antigravity')
? dirName
: '"$CLAUDE_PROJECT_DIR"/' + dirName;
const hookOpts = { portableHooks: hasPortableHooks };
const statuslineCommand = isGlobal
? buildHookCommand(targetDir, 'gsd-statusline.js', hookOpts)
@@ -6786,6 +6804,26 @@ function installSdkIfNeeded() {
emitSdkFatal('Failed to `npm install -g .` from sdk/.', { globalBin: null, exitCode: 1 });
}
// 3a. Explicitly chmod dist/cli.js to 0o755 in the global install location.
// `tsc` emits files at process umask (typically 0o644 — non-executable), and
// `npm install -g` from a local directory does NOT chmod bin-script targets the
// way tarball extraction does. Without this, the `gsd-sdk` bin symlink points at
// a non-executable file and `command -v gsd-sdk` fails on every first install
// (root cause of #2453). Mirrors the pattern used for hook files in this installer.
try {
const prefixRes = spawnSync(npmCmd, ['config', 'get', 'prefix'], { encoding: 'utf-8' });
if (prefixRes.status === 0) {
const npmPrefix = (prefixRes.stdout || '').trim();
const sdkPkg = JSON.parse(fs.readFileSync(path.join(sdkDir, 'package.json'), 'utf-8'));
const sdkName = sdkPkg.name; // '@gsd-build/sdk'
const globalModulesDir = process.platform === 'win32'
? path.join(npmPrefix, 'node_modules')
: path.join(npmPrefix, 'lib', 'node_modules');
const cliPath = path.join(globalModulesDir, sdkName, 'dist', 'cli.js');
try { fs.chmodSync(cliPath, 0o755); } catch (e) { if (process.platform !== 'win32') throw e; }
}
} catch (e) { /* Non-fatal: PATH verification in step 4 will catch any real failure */ }
// 4. Verify gsd-sdk is actually resolvable on PATH. npm's global bin dir is
// not always on the current shell's PATH (Homebrew prefixes, nvm setups,
// unconfigured npm prefix), so a zero exit status from `npm install -g`
@@ -6931,7 +6969,17 @@ if (process.env.GSD_TEST_MODE) {
} else {
// Main logic
if (hasGlobal && hasLocal) {
if (hasSkillsRoot) {
// Print the skills root directory for a given runtime (used by /gsd-sync-skills).
// Usage: node install.js --skills-root <runtime>
const runtimeArg = args[args.indexOf('--skills-root') + 1];
if (!runtimeArg || runtimeArg.startsWith('--')) {
console.error('Usage: node install.js --skills-root <runtime>');
process.exit(1);
}
const globalDir = getGlobalDir(runtimeArg, null);
console.log(path.join(globalDir, 'skills'));
} else if (hasGlobal && hasLocal) {
console.error(` ${yellow}Cannot specify both --global and --local${reset}`);
process.exit(1);
} else if (explicitConfigDir && hasLocal) {

View File

@@ -42,7 +42,7 @@ the normal phase sequence and accumulate context over time.
**Plans:** 0 plans
Plans:
- [ ] TBD (promote with /gsd-review-backlog when ready)
- [ ] TBD (promote with /gsd:review-backlog when ready)
```
4. **Create the phase directory:**
@@ -65,15 +65,15 @@ the normal phase sequence and accumulate context over time.
Directory: .planning/phases/{NEXT}-{slug}/
This item lives in the backlog parking lot.
Use /gsd-discuss-phase {NEXT} to explore it further.
Use /gsd-review-backlog to promote items to active milestone.
Use /gsd:discuss-phase {NEXT} to explore it further.
Use /gsd:review-backlog to promote items to active milestone.
```
</process>
<notes>
- 999.x numbering keeps backlog items out of the active phase sequence
- Phase directories are created immediately, so /gsd-discuss-phase and /gsd-plan-phase work on them
- Phase directories are created immediately, so /gsd:discuss-phase and /gsd:plan-phase work on them
- No `Depends on:` field — backlog items are unsequenced by definition
- Sparse numbering is fine (999.1, 999.3) — always uses next-decimal
</notes>

View File

@@ -13,8 +13,8 @@ allowed-tools:
- AskUserQuestion
argument-instructions: |
Parse the argument as a phase number (integer, decimal, or letter-suffix), plus optional free-text instructions.
Example: /gsd-add-tests 12
Example: /gsd-add-tests 12 focus on edge cases in the pricing module
Example: /gsd:add-tests 12
Example: /gsd:add-tests 12 focus on edge cases in the pricing module
---
<objective>
Generate unit and E2E tests for a completed phase, using its SUMMARY.md, CONTEXT.md, and VERIFICATION.md as specifications.

View File

@@ -25,7 +25,7 @@ Then suggest `Depends on` updates to ROADMAP.md.
<context>
No arguments required. Requires an active milestone with ROADMAP.md.
Run this command BEFORE `/gsd-manager` to fill in missing `Depends on` fields and prevent merge conflicts from unordered parallel execution.
Run this command BEFORE `/gsd:manager` to fill in missing `Depends on` fields and prevent merge conflicts from unordered parallel execution.
</context>
<process>

View File

@@ -42,19 +42,19 @@ Output: Milestone archived (roadmap + requirements), PROJECT.md evolved, git tag
0. **Check for audit:**
- Look for `.planning/v{{version}}-MILESTONE-AUDIT.md`
- If missing or stale: recommend `/gsd-audit-milestone` first
- If audit status is `gaps_found`: recommend `/gsd-plan-milestone-gaps` first
- If missing or stale: recommend `/gsd:audit-milestone` first
- If audit status is `gaps_found`: recommend `/gsd:plan-milestone-gaps` first
- If audit status is `passed`: proceed to step 1
```markdown
## Pre-flight Check
{If no v{{version}}-MILESTONE-AUDIT.md:}
⚠ No milestone audit found. Run `/gsd-audit-milestone` first to verify
⚠ No milestone audit found. Run `/gsd:audit-milestone` first to verify
requirements coverage, cross-phase integration, and E2E flows.
{If audit has gaps:}
⚠ Milestone audit found gaps. Run `/gsd-plan-milestone-gaps` to create
⚠ Milestone audit found gaps. Run `/gsd:plan-milestone-gaps` to create
phases that close the gaps, or proceed anyway to accept as tech debt.
{If audit passed:}
@@ -108,7 +108,7 @@ Output: Milestone archived (roadmap + requirements), PROJECT.md evolved, git tag
- Ask about pushing tag
8. **Offer next steps:**
- `/gsd-new-milestone` — start next milestone (questioning → research → requirements → roadmap)
- `/gsd:new-milestone` — start next milestone (questioning → research → requirements → roadmap)
</process>
@@ -132,5 +132,5 @@ Output: Milestone archived (roadmap + requirements), PROJECT.md evolved, git tag
- **Archive before deleting:** Always create archive files before updating/deleting originals
- **One-line summary:** Collapsed milestone in ROADMAP.md should be single line with link
- **Context efficiency:** Archive keeps ROADMAP.md and REQUIREMENTS.md constant size per milestone
- **Fresh requirements:** Next milestone starts with `/gsd-new-milestone` which includes requirements definition
- **Fresh requirements:** Next milestone starts with `/gsd:new-milestone` which includes requirements definition
</critical_rules>

View File

@@ -88,11 +88,11 @@ Active Debug Sessions
hypothesis: Missing null check on req.body.user
next: Verify fix passes regression test
─────────────────────────────────────────────
Run `/gsd-debug continue <slug>` to resume a session.
No sessions? `/gsd-debug <description>` to start.
Run `/gsd:debug continue <slug>` to resume a session.
No sessions? `/gsd:debug <description>` to start.
```
If no files exist or the glob returns nothing: print "No active debug sessions. Run `/gsd-debug <issue description>` to start one."
If no files exist or the glob returns nothing: print "No active debug sessions. Run `/gsd:debug <issue description>` to start one."
STOP after displaying list. Do NOT proceed to further steps.
@@ -117,7 +117,7 @@ No agent spawn. Just information display. STOP after printing.
When SUBCMD=continue and SLUG is set:
Check `.planning/debug/{SLUG}.md` exists. If not, print "No active debug session found with slug: {SLUG}. Check `/gsd-debug list` for active sessions." and stop.
Check `.planning/debug/{SLUG}.md` exists. If not, print "No active debug session found with slug: {SLUG}. Check `/gsd:debug list` for active sessions." and stop.
Read file and print Current Focus block to console:
@@ -247,7 +247,7 @@ specialist_dispatch_enabled: true
Display the compact summary returned by the session manager.
If summary shows `DEBUG SESSION COMPLETE`: done.
If summary shows `ABANDONED`: note session saved at `.planning/debug/{slug}.md` for later `/gsd-debug continue {slug}`.
If summary shows `ABANDONED`: note session saved at `.planning/debug/{slug}.md` for later `/gsd:debug continue {slug}`.
</process>

View File

@@ -15,7 +15,7 @@ Open-ended Socratic ideation session. Guides the developer through exploring an
probing questions, optionally spawns research, then routes outputs to the appropriate GSD
artifacts (notes, todos, seeds, research questions, requirements, or new phases).
Accepts an optional topic argument: `/gsd-explore authentication strategy`
Accepts an optional topic argument: `/gsd:explore authentication strategy`
</objective>
<execution_context>

View File

@@ -16,8 +16,8 @@ Execute a trivial task directly in the current context without spawning subagent
or generating PLAN.md files. For tasks too small to justify planning overhead:
typo fixes, config changes, small refactors, forgotten commits, simple additions.
This is NOT a replacement for /gsd-quick — use /gsd-quick for anything that
needs research, multi-step planning, or verification. /gsd-fast is for tasks
This is NOT a replacement for /gsd:quick — use /gsd:quick for anything that
needs research, multi-step planning, or verification. /gsd:fast is for tasks
you could describe in one sentence and execute in under 2 minutes.
</objective>

View File

@@ -43,7 +43,7 @@ Knowledge graph is disabled. To activate:
node $HOME/.claude/get-shit-done/bin/gsd-tools.cjs config-set graphify.enabled true
Then run /gsd-graphify build to create the initial graph.
Then run /gsd:graphify build to create the initial graph.
```
---
@@ -65,7 +65,7 @@ Parse `$ARGUMENTS` to determine the operation mode:
```
GSD > GRAPHIFY
Usage: /gsd-graphify <mode>
Usage: /gsd:graphify <mode>
Modes:
build Build or rebuild the knowledge graph
@@ -85,7 +85,7 @@ node $HOME/.claude/get-shit-done/bin/gsd-tools.cjs graphify query <term>
Parse the JSON output and display results:
- If the output contains `"disabled": true`, display the disabled message from Step 1 and **STOP**
- If the output contains `"error"` field, display the error message and **STOP**
- If no nodes found, display: `No graph matches for '<term>'. Try /gsd-graphify build to create or rebuild the graph.`
- If no nodes found, display: `No graph matches for '<term>'. Try /gsd:graphify build to create or rebuild the graph.`
- Otherwise, display matched nodes grouped by type, with edge relationships and confidence tiers (EXTRACTED/INFERRED/AMBIGUOUS)
**STOP** after displaying results. Do not spawn an agent.

View File

@@ -41,7 +41,7 @@ Intel system is disabled. To activate:
gsd-sdk query config-set intel.enabled true
Then run /gsd-intel refresh to build the initial index.
Then run /gsd:intel refresh to build the initial index.
```
---
@@ -63,7 +63,7 @@ Parse `$ARGUMENTS` to determine the operation mode:
```
GSD > INTEL
Usage: /gsd-intel <mode>
Usage: /gsd:intel <mode>
Modes:
query <term> Search intel files for a term
@@ -82,7 +82,7 @@ gsd-sdk query intel.query <term>
Parse the JSON output and display results:
- If the output contains `"disabled": true`, display the disabled message from Step 1 and **STOP**
- If no matches found, display: `No intel matches for '<term>'. Try /gsd-intel refresh to build the index.`
- If no matches found, display: `No intel matches for '<term>'. Try /gsd:intel refresh to build the index.`
- Otherwise, display matching entries grouped by intel file
**STOP** after displaying results. Do not spawn an agent.

View File

@@ -30,8 +30,8 @@ Focus area: $ARGUMENTS (optional - if provided, tells agents to focus on specifi
Check for .planning/STATE.md - loads context if project already initialized
**This command can run:**
- Before /gsd-new-project (brownfield codebases) - creates codebase map first
- After /gsd-new-project (greenfield codebases) - updates codebase map as code evolves
- Before /gsd:new-project (brownfield codebases) - creates codebase map first
- After /gsd:new-project (greenfield codebases) - updates codebase map as code evolves
- Anytime to refresh codebase understanding
</context>
@@ -59,7 +59,7 @@ Check for .planning/STATE.md - loads context if project already initialized
4. Wait for agents to complete, collect confirmations (NOT document contents)
5. Verify all 7 documents exist with line counts
6. Commit codebase map
7. Offer next steps (typically: /gsd-new-project or /gsd-plan-phase)
7. Offer next steps (typically: /gsd:new-project or /gsd:plan-phase)
</process>
<success_criteria>

View File

@@ -21,7 +21,7 @@ Brownfield equivalent of new-project. Project exists, PROJECT.md has history. Ga
- `.planning/ROADMAP.md` — phase structure (continues numbering)
- `.planning/STATE.md` — reset for new milestone
**After:** `/gsd-plan-phase [N]` to start execution.
**After:** `/gsd:plan-phase [N]` to start execution.
</objective>
<execution_context>

View File

@@ -29,7 +29,7 @@ Initialize a new project through unified flow: questioning → research (optiona
- `.planning/ROADMAP.md` — phase structure
- `.planning/STATE.md` — project memory
**After this command:** Run `/gsd-plan-phase 1` to start execution.
**After this command:** Run `/gsd:plan-phase 1` to start execution.
</objective>
<execution_context>

View File

@@ -30,7 +30,7 @@ Create a physical workspace directory containing copies of specified git repos (
- `<path>/.planning/` — independent planning directory
- `<path>/<repo>/` — git worktree or clone for each specified repo
**After this command:** `cd` into the workspace and run `/gsd-new-project` to initialize GSD.
**After this command:** `cd` into the workspace and run `/gsd:new-project` to initialize GSD.
</objective>
<execution_context>

View File

@@ -10,11 +10,11 @@ allowed-tools:
- AskUserQuestion
---
<objective>
Create all phases necessary to close gaps identified by `/gsd-audit-milestone`.
Create all phases necessary to close gaps identified by `/gsd:audit-milestone`.
Reads MILESTONE-AUDIT.md, groups gaps into logical phases, creates phase entries in ROADMAP.md, and offers to plan each phase.
One command creates all fix phases — no manual `/gsd-add-phase` per gap.
One command creates all fix phases — no manual `/gsd:add-phase` per gap.
</objective>
<execution_context>

View File

@@ -40,7 +40,7 @@ Phase number: $ARGUMENTS (optional — auto-detects next unplanned phase if omit
- `--gaps` — Gap closure mode (reads VERIFICATION.md, skips research)
- `--skip-verify` — Skip verification loop
- `--prd <file>` — Use a PRD/acceptance criteria file instead of discuss-phase. Parses requirements into CONTEXT.md automatically. Skips discuss-phase entirely.
- `--reviews` — Replan incorporating cross-AI review feedback from REVIEWS.md (produced by `/gsd-review`)
- `--reviews` — Replan incorporating cross-AI review feedback from REVIEWS.md (produced by `/gsd:review`)
- `--text` — Use plain-text numbered lists instead of TUI menus (required for `/rc` remote sessions)
Normalize phase input in step 2 before any directory lookups.

View File

@@ -0,0 +1,52 @@
---
name: gsd:plan-review-convergence
description: "Cross-AI plan convergence loop — replan with review feedback until no HIGH concerns remain (max 3 cycles)"
argument-hint: "<phase> [--codex] [--gemini] [--claude] [--opencode] [--text] [--ws <name>] [--all] [--max-cycles N]"
allowed-tools:
- Read
- Write
- Bash
- Glob
- Grep
- Agent
- AskUserQuestion
---
<objective>
Cross-AI plan convergence loop — an outer revision gate around gsd-review and gsd-planner.
Repeatedly: review plans with external AI CLIs → if HIGH concerns found → replan with --reviews feedback → re-review. Stops when no HIGH concerns remain or max cycles reached.
**Flow:** Agent→Skill("gsd-plan-phase") → Agent→Skill("gsd-review") → check HIGHs → Agent→Skill("gsd-plan-phase --reviews") → Agent→Skill("gsd-review") → ... → Converge or escalate
Replaces gsd-plan-phase's internal gsd-plan-checker with external AI reviewers (codex, gemini, etc.). Each step runs inside an isolated Agent that calls the corresponding existing Skill — orchestrator only does loop control.
**Orchestrator role:** Parse arguments, validate phase, spawn Agents for existing Skills, check HIGHs, stall detection, escalation gate.
</objective>
<execution_context>
@$HOME/.claude/get-shit-done/workflows/plan-review-convergence.md
@$HOME/.claude/get-shit-done/references/revision-loop.md
@$HOME/.claude/get-shit-done/references/gates.md
@$HOME/.claude/get-shit-done/references/agent-contracts.md
</execution_context>
<runtime_note>
**Copilot (VS Code):** Use `vscode_askquestions` wherever this workflow calls `AskUserQuestion`. They are equivalent — `vscode_askquestions` is the VS Code Copilot implementation of the same interactive question API. Do not skip questioning steps because `AskUserQuestion` appears unavailable; use `vscode_askquestions` instead.
</runtime_note>
<context>
Phase number: extracted from $ARGUMENTS (required)
**Flags:**
- `--codex` — Use Codex CLI as reviewer (default if no reviewer specified)
- `--gemini` — Use Gemini CLI as reviewer
- `--claude` — Use Claude CLI as reviewer (separate session)
- `--opencode` — Use OpenCode as reviewer
- `--all` — Use all available CLIs
- `--max-cycles N` — Maximum replan→review cycles (default: 3)
</context>
<process>
Execute the plan-review-convergence workflow from @$HOME/.claude/get-shit-done/workflows/plan-review-convergence.md end-to-end.
Preserve all workflow gates (pre-flight, revision loop, stall detection, escalation).
</process>

View File

@@ -16,7 +16,7 @@ milestone arrives. Seeds solve context rot: instead of a one-liner in Deferred t
reads, a seed preserves the full WHY, WHEN to surface, and breadcrumbs to details.
Creates: .planning/seeds/SEED-NNN-slug.md
Consumed by: /gsd-new-milestone (scans seeds and presents matches)
Consumed by: /gsd:new-milestone (scans seeds and presents matches)
</objective>
<execution_context>

View File

@@ -118,7 +118,7 @@ Status: {status from SUMMARY.md frontmatter, or "no summary yet"}
Description: {first non-empty line from PLAN.md after frontmatter}
Last action: {last meaningful line of SUMMARY.md, or "none"}
─────────────────────────────────────
Resume with: /gsd-quick resume {slug}
Resume with: /gsd:quick resume {slug}
```
No agent spawn. STOP after printing.

View File

@@ -115,7 +115,7 @@ Read `backup-meta.json` from the patches directory.
```
No local patches found. Nothing to reapply.
Local patches are automatically saved when you run /gsd-update
Local patches are automatically saved when you run /gsd:update
after modifying any GSD workflow, command, or agent files.
```
Exit.
@@ -129,7 +129,7 @@ The quality of the merge depends on having a **pristine baseline** — the origi
Check for baseline sources in priority order:
### Option A: Git history (most reliable)
### Option A: Pristine hash from backup-meta.json + git history (most reliable)
If the config directory is a git repository:
```bash
CONFIG_DIR=$(dirname "$PATCHES_DIR")
@@ -137,15 +137,35 @@ if git -C "$CONFIG_DIR" rev-parse --git-dir >/dev/null 2>&1; then
HAS_GIT=true
fi
```
When `HAS_GIT=true`, use `git log` to find the commit where GSD was originally installed (before user edits). For each file, the pristine baseline can be extracted with:
When `HAS_GIT=true`, use the `pristine_hashes` recorded in `backup-meta.json` to locate the correct baseline commit. For each file, iterate commits that touched it and find the one whose blob SHA-256 matches the recorded pristine hash:
```bash
git -C "$CONFIG_DIR" log --diff-filter=A --format="%H" -- "{file_path}"
# Get the expected pristine SHA-256 from backup-meta.json
PRISTINE_HASH=$(jq -r ".pristine_hashes[\"${file_path}\"] // empty" "$PATCHES_DIR/backup-meta.json")
BASELINE_COMMIT=""
if [ -n "$PRISTINE_HASH" ]; then
# Walk commits that touched this file, pick the one matching the pristine hash
while IFS= read -r commit_hash; do
blob_hash=$(git -C "$CONFIG_DIR" show "${commit_hash}:${file_path}" 2>/dev/null | sha256sum | cut -d' ' -f1)
if [ "$blob_hash" = "$PRISTINE_HASH" ]; then
BASELINE_COMMIT="$commit_hash"
break
fi
done < <(git -C "$CONFIG_DIR" log --format="%H" -- "${file_path}")
fi
# Fallback: if no pristine hash in backup-meta (older installer), use first-add commit
if [ -z "$BASELINE_COMMIT" ]; then
BASELINE_COMMIT=$(git -C "$CONFIG_DIR" log --diff-filter=A --format="%H" -- "${file_path}" | tail -1)
fi
```
This gives the commit that first added the file (the install commit). Extract the pristine version:
Extract the pristine version from the matched commit:
```bash
git -C "$CONFIG_DIR" show {install_commit}:{file_path}
git -C "$CONFIG_DIR" show "${BASELINE_COMMIT}:${file_path}"
```
**Why this matters:** `git log --diff-filter=A` returns the commit that *first added* the file, which is the wrong baseline on repos that have been through multiple GSD update cycles. The `pristine_hashes` field in `backup-meta.json` records the SHA-256 of the file as it existed in the pre-update GSD release — matching against it finds the correct baseline regardless of how many updates have occurred.
### Option B: Pristine snapshot directory
Check if a `gsd-pristine/` directory exists alongside `gsd-local-patches/`:
```bash
@@ -258,7 +278,7 @@ Before proceeding to cleanup, evaluate the Hunk Verification Table produced in S
**If the Hunk Verification Table is absent** (Step 4 did not produce it), STOP immediately and report to the user:
```
ERROR: Hunk Verification Table is missing. Post-merge verification was not completed.
Rerun /gsd-reapply-patches to retry with full verification.
Rerun /gsd:reapply-patches to retry with full verification.
```
**If any row in the Hunk Verification Table shows `verified: no`**, STOP and report to the user:

View File

@@ -1,6 +1,6 @@
---
name: gsd:research-phase
description: Research how to implement a phase (standalone - usually use /gsd-plan-phase instead)
description: Research how to implement a phase (standalone - usually use /gsd:plan-phase instead)
argument-hint: "[phase]"
allowed-tools:
- Read
@@ -11,7 +11,7 @@ allowed-tools:
<objective>
Research how to implement a phase. Spawns gsd-phase-researcher agent with phase context.
**Note:** This is a standalone research command. For most workflows, use `/gsd-plan-phase` which integrates research automatically.
**Note:** This is a standalone research command. For most workflows, use `/gsd:plan-phase` which integrates research automatically.
**Use this command when:**
- You want to research without planning yet
@@ -115,7 +115,7 @@ Mode: ecosystem
</additional_context>
<downstream_consumer>
Your RESEARCH.md will be loaded by `/gsd-plan-phase` which uses specific sections:
Your RESEARCH.md will be loaded by `/gsd:plan-phase` which uses specific sections:
- `## Standard Stack` → Plans use these libraries
- `## Architecture Patterns` → Task structure follows these
- `## Don't Hand-Roll` → Tasks NEVER build custom solutions for listed problems

View File

@@ -13,7 +13,7 @@ allowed-tools:
<objective>
Invoke external AI CLIs (Gemini, Claude, Codex, OpenCode, Qwen Code, Cursor) to independently review phase plans.
Produces a structured REVIEWS.md with per-reviewer feedback that can be fed back into
planning via /gsd-plan-phase --reviews.
planning via /gsd:plan-phase --reviews.
**Flow:** Detect CLIs → Build review prompt → Invoke each CLI → Collect responses → Write REVIEWS.md
</objective>

View File

@@ -1,6 +1,6 @@
---
name: gsd:scan
description: Rapid codebase assessment — lightweight alternative to /gsd-map-codebase
description: Rapid codebase assessment — lightweight alternative to /gsd:map-codebase
allowed-tools:
- Read
- Write
@@ -14,7 +14,7 @@ allowed-tools:
Run a focused codebase scan for a single area, producing targeted documents in `.planning/codebase/`.
Accepts an optional `--focus` flag: `tech`, `arch`, `quality`, `concerns`, or `tech+arch` (default).
Lightweight alternative to `/gsd-map-codebase` — spawns one mapper agent instead of four parallel ones.
Lightweight alternative to `/gsd:map-codebase` — spawns one mapper agent instead of four parallel ones.
</objective>
<execution_context>

View File

@@ -9,4 +9,4 @@ allowed-tools:
Show the following output to the user verbatim, with no extra commentary:
!`if ! command -v gsd-sdk >/dev/null 2>&1; then printf '⚠ gsd-sdk not found in PATH — /gsd-set-profile requires it.\n\nInstall the GSD SDK:\n npm install -g @gsd-build/sdk\n\nOr update GSD to get the latest packages:\n /gsd-update\n'; exit 1; fi; gsd-sdk query config-set-model-profile $ARGUMENTS --raw`
!`if ! command -v gsd-sdk >/dev/null 2>&1; then printf '⚠ gsd-sdk not found in PATH — /gsd:set-profile requires it.\n\nInstall the GSD SDK:\n npm install -g @gsd-build/sdk\n\nOr update GSD to get the latest packages:\n /gsd:update\n'; exit 1; fi; gsd-sdk query config-set-model-profile $ARGUMENTS --raw`

View File

@@ -11,7 +11,7 @@ allowed-tools:
- AskUserQuestion
---
<objective>
Bridge local completion → merged PR. After /gsd-verify-work passes, ship the work: push branch, create PR with auto-generated body, optionally trigger review, and track the merge.
Bridge local completion → merged PR. After /gsd:verify-work passes, ship the work: push branch, create PR with auto-generated body, optionally trigger review, and track the merge.
Closes the plan → execute → verify → ship loop.
</objective>

View File

@@ -1,7 +1,7 @@
---
name: gsd:sketch
description: Rapidly sketch UI/design ideas using throwaway HTML mockups with multi-variant exploration
argument-hint: "<design idea to explore> [--quick]"
description: Sketch UI/design ideas with throwaway HTML mockups, or propose what to sketch next (frontier mode)
argument-hint: "[design idea to explore] [--quick] [--text] or [frontier]"
allowed-tools:
- Read
- Write
@@ -10,13 +10,22 @@ allowed-tools:
- Grep
- Glob
- AskUserQuestion
- WebSearch
- WebFetch
- mcp__context7__resolve-library-id
- mcp__context7__query-docs
---
<objective>
Explore design directions through throwaway HTML mockups before committing to implementation.
Each sketch produces 2-3 variants for comparison. Sketches live in `.planning/sketches/` and
integrate with GSD commit patterns, state tracking, and handoff workflows.
integrate with GSD commit patterns, state tracking, and handoff workflows. Loads spike
findings to ground mockups in real data shapes and validated interaction patterns.
Does not require `/gsd-new-project` — auto-creates `.planning/sketches/` if needed.
Two modes:
- **Idea mode** (default) — describe a design idea to sketch
- **Frontier mode** (no argument or "frontier") — analyzes existing sketch landscape and proposes consistency and frontier sketches
Does not require `/gsd:new-project` — auto-creates `.planning/sketches/` if needed.
</objective>
<execution_context>
@@ -41,5 +50,5 @@ Design idea: $ARGUMENTS
<process>
Execute the sketch workflow from @~/.claude/get-shit-done/workflows/sketch.md end-to-end.
Preserve all workflow gates (intake, decomposition, variant evaluation, MANIFEST updates, commit patterns).
Preserve all workflow gates (intake, decomposition, target stack research, variant evaluation, MANIFEST updates, commit patterns).
</process>

View File

@@ -58,5 +58,5 @@ Execute the spec-phase workflow from @~/.claude/get-shit-done/workflows/spec-pha
- Gate passed: ambiguity ≤ 0.20 AND all dimension minimums met
- SPEC.md written with falsifiable requirements, explicit boundaries, and acceptance criteria
- SPEC.md committed atomically
- User knows they can now run /gsd-discuss-phase which will load SPEC.md automatically
- User knows they can now run /gsd:discuss-phase which will load SPEC.md automatically
</success_criteria>

View File

@@ -27,5 +27,5 @@ project history. Output skill goes to `./.claude/skills/spike-findings-[project]
<process>
Execute the spike-wrap-up workflow from @~/.claude/get-shit-done/workflows/spike-wrap-up.md end-to-end.
Preserve all curation gates (per-spike review, grouping approval, CLAUDE.md routing line).
Preserve all workflow gates (auto-include, feature-area grouping, skill synthesis, CLAUDE.md routing line, intelligent next-step routing).
</process>

View File

@@ -1,7 +1,7 @@
---
name: gsd:spike
description: Rapidly spike an idea with throwaway experiments to validate feasibility before planning
argument-hint: "<idea to validate> [--quick]"
description: Spike an idea through experiential exploration, or propose what to spike next (frontier mode)
argument-hint: "[idea to validate] [--quick] [--text] or [frontier]"
allowed-tools:
- Read
- Write
@@ -10,13 +10,22 @@ allowed-tools:
- Grep
- Glob
- AskUserQuestion
- WebSearch
- WebFetch
- mcp__context7__resolve-library-id
- mcp__context7__query-docs
---
<objective>
Rapid feasibility validation through focused, throwaway experiments. Each spike answers one
specific question with observable evidence. Spikes live in `.planning/spikes/` and integrate
with GSD commit patterns, state tracking, and handoff workflows.
Spike an idea through experiential exploration — build focused experiments to feel the pieces
of a future app, validate feasibility, and produce verified knowledge for the real build.
Spikes live in `.planning/spikes/` and integrate with GSD commit patterns, state tracking,
and handoff workflows.
Does not require `/gsd-new-project` — auto-creates `.planning/spikes/` if needed.
Two modes:
- **Idea mode** (default) — describe an idea to spike
- **Frontier mode** (no argument or "frontier") — analyzes existing spike landscape and proposes integration and frontier spikes
Does not require `/gsd:new-project` — auto-creates `.planning/spikes/` if needed.
</objective>
<execution_context>
@@ -33,9 +42,10 @@ Idea: $ARGUMENTS
**Available flags:**
- `--quick` — Skip decomposition/alignment, jump straight to building. Use when you already know what to spike.
- `--text` — Use plain-text numbered lists instead of AskUserQuestion (for non-Claude runtimes).
</context>
<process>
Execute the spike workflow from @~/.claude/get-shit-done/workflows/spike.md end-to-end.
Preserve all workflow gates (decomposition, risk ordering, verification, MANIFEST updates, commit patterns).
Preserve all workflow gates (prior spike check, decomposition, research, risk ordering, observability assessment, verification, MANIFEST updates, commit patterns).
</process>

View File

@@ -0,0 +1,19 @@
---
name: gsd:sync-skills
description: Sync managed GSD skills across runtime roots so multi-runtime users stay aligned after an update
allowed-tools:
- Bash
- AskUserQuestion
---
<objective>
Sync managed `gsd-*` skill directories from one canonical runtime's skills root to one or more destination runtime skills roots.
Routes to the sync-skills workflow which handles:
- Argument parsing (--from, --to, --dry-run, --apply)
- Runtime skills root resolution via install.js --skills-root
- Diff computation (CREATE / UPDATE / REMOVE per destination)
- Dry-run reporting (default — no writes)
- Apply execution (copy and remove with idempotency)
- Non-GSD skill preservation (only gsd-* dirs are touched)
</objective>

View File

@@ -62,7 +62,7 @@ frontend-build-tools resolved 2026-04-01 Vite vs webpack
If no threads exist (or none match the filter):
```
No threads found. Create one with: /gsd-thread <description>
No threads found. Create one with: /gsd:thread <description>
```
STOP after displaying. Do NOT proceed to further steps.
@@ -117,8 +117,8 @@ When SUBCMD=status and SLUG is set (already sanitized):
Next Steps:
{content of ## Next Steps section}
─────────────────────────────────────
Resume with: /gsd-thread {SLUG}
Close with: /gsd-thread close {SLUG}
Resume with: /gsd:thread {SLUG}
Close with: /gsd:thread close {SLUG}
```
No agent spawn. STOP after printing.
@@ -201,8 +201,8 @@ updated: {today ISO date}
Thread: {slug}
File: .planning/threads/{slug}.md
Resume anytime with: /gsd-thread {slug}
Close when done with: /gsd-thread close {slug}
Resume anytime with: /gsd:thread {slug}
Close when done with: /gsd:thread close {slug}
```
</mode_create>
@@ -210,10 +210,10 @@ updated: {today ISO date}
<notes>
- Threads are NOT phase-scoped — they exist independently of the roadmap
- Lighter weight than /gsd-pause-work — no phase state, no plan context
- Lighter weight than /gsd:pause-work — no phase state, no plan context
- The value is in Context and Next Steps — a cold-start session can pick up immediately
- Threads can be promoted to phases or backlog items when they mature:
/gsd-add-phase or /gsd-add-backlog with context from the thread
/gsd:add-phase or /gsd:add-backlog with context from the thread
- Thread files live in .planning/threads/ — no collision with phases or other GSD structures
- Thread status values: `open`, `in_progress`, `resolved`
</notes>

View File

@@ -1,6 +1,6 @@
---
name: gsd:ultraplan-phase
description: "[BETA] Offload plan phase to Claude Code's ultraplan cloud — drafts remotely while terminal stays free, review in browser with inline comments, import back via /gsd-import. Claude Code only."
description: "[BETA] Offload plan phase to Claude Code's ultraplan cloud — drafts remotely while terminal stays free, review in browser with inline comments, import back via /gsd:import. Claude Code only."
argument-hint: "[phase-number]"
allowed-tools:
- Read
@@ -13,9 +13,9 @@ allowed-tools:
Offload GSD's plan phase to Claude Code's ultraplan cloud infrastructure.
Ultraplan drafts the plan in a remote cloud session while your terminal stays free.
Review and comment on the plan in your browser, then import it back via /gsd-import --from.
Review and comment on the plan in your browser, then import it back via /gsd:import --from.
⚠ BETA: ultraplan is in research preview. Use /gsd-plan-phase for stable local planning.
⚠ BETA: ultraplan is in research preview. Use /gsd:plan-phase for stable local planning.
Requirements: Claude Code v2.1.91+, claude.ai account, GitHub repository.
</objective>

View File

@@ -16,7 +16,7 @@ Validate built features through conversational testing with persistent state.
Purpose: Confirm what Claude built actually works from user's perspective. One test at a time, plain text responses, no interrogation. When issues are found, automatically diagnose, plan fixes, and prepare for execution.
Output: {phase_num}-UAT.md tracking all test results. If issues found: diagnosed gaps, verified fix plans ready for /gsd-execute-phase
Output: {phase_num}-UAT.md tracking all test results. If issues found: diagnosed gaps, verified fix plans ready for /gsd:execute-phase
</objective>
<execution_context>

View File

@@ -6,13 +6,13 @@ allowed-tools:
- Bash
---
# /gsd-workstreams
# /gsd:workstreams
Manage parallel workstreams for concurrent milestone work.
## Usage
`/gsd-workstreams [subcommand] [args]`
`/gsd:workstreams [subcommand] [args]`
### Subcommands
@@ -40,7 +40,7 @@ Display the workstreams in a table format showing name, status, current phase, a
### create
Run: `gsd-sdk query workstream.create <name> --raw --cwd "$CWD"`
After creation, display the new workstream path and suggest next steps:
- `/gsd-new-milestone --ws <name>` to set up the milestone
- `/gsd:new-milestone --ws <name>` to set up the milestone
### status
Run: `gsd-sdk query workstream.status <name> --raw --cwd "$CWD"`
@@ -61,7 +61,7 @@ Run: `gsd-sdk query workstream.complete <name> --raw --cwd "$CWD"`
Archive the workstream to milestones/.
### resume
Set the workstream as active and suggest `/gsd-resume-work --ws <name>`.
Set the workstream as active and suggest `/gsd:resume-work --ws <name>`.
## Step 3: Display Results

View File

@@ -1,6 +1,6 @@
# GSD Agent Reference
> All 21 specialized agents — roles, tools, spawn patterns, and relationships. For architecture context, see [Architecture](ARCHITECTURE.md).
> Full role cards for 21 primary agents plus concise stubs for 10 advanced/specialized agents (31 shipped agents total). The `agents/` directory and [`docs/INVENTORY.md`](INVENTORY.md) are the authoritative roster; see [Architecture](ARCHITECTURE.md) for context.
---
@@ -10,6 +10,8 @@ GSD uses a multi-agent architecture where thin orchestrators (workflow files) sp
### Agent Categories
> The table below covers the **21 primary agents** detailed in this section. Ten additional shipped agents (pattern-mapper, debug-session-manager, code-reviewer, code-fixer, ai-researcher, domain-researcher, eval-planner, eval-auditor, framework-selector, intel-updater) have concise stubs in the [Advanced and Specialized Agents](#advanced-and-specialized-agents) section below. For the authoritative 31-agent roster, see [`docs/INVENTORY.md`](INVENTORY.md) and the `agents/` directory.
| Category | Count | Agents |
|----------|-------|--------|
| Researchers | 3 | project-researcher, phase-researcher, ui-researcher |
@@ -468,8 +470,252 @@ Communication style, decision patterns, debugging approach, UX preferences, vend
---
## Advanced and Specialized Agents
Ten additional agents ship under `agents/gsd-*.md` and are used by specialty workflows (`/gsd-ai-integration-phase`, `/gsd-eval-review`, `/gsd-code-review`, `/gsd-code-review-fix`, `/gsd-debug`, `/gsd-intel`, `/gsd-select-framework`) and by the planner pipeline. Each carries full frontmatter in its agent file; the stubs below are concise by design. The authoritative roster (with spawner and primary-doc status per agent) lives in [`docs/INVENTORY.md`](INVENTORY.md).
### gsd-pattern-mapper
**Role:** Read-only codebase analysis that maps files-to-be-created or modified to their closest existing analogs, producing `PATTERNS.md` for the planner to consume.
| Property | Value |
|----------|-------|
| **Spawned by** | `/gsd-plan-phase` (between research and planning) |
| **Parallelism** | Single instance |
| **Tools** | Read, Bash, Glob, Grep, Write |
| **Model (balanced)** | Sonnet |
| **Color** | Magenta |
| **Produces** | `PATTERNS.md` in the phase directory |
**Key behaviors:**
- Extracts file list from CONTEXT.md and RESEARCH.md; classifies each by role (controller, component, service, model, middleware, utility, config, test) and data flow (CRUD, streaming, file I/O, event-driven, request-response)
- Searches for the closest existing analog per file and extracts concrete code excerpts (imports, auth patterns, core pattern, error handling)
- Strictly read-only against source; only writes `PATTERNS.md`
---
### gsd-debug-session-manager
**Role:** Runs the full `/gsd-debug` checkpoint-and-continuation loop in an isolated context so the orchestrator's main context stays lean; spawns `gsd-debugger` agents, dispatches specialist skills, and handles user checkpoints via AskUserQuestion.
| Property | Value |
|----------|-------|
| **Spawned by** | `/gsd-debug` |
| **Parallelism** | Single instance (interactive, stateful) |
| **Tools** | Read, Write, Bash, Grep, Glob, Task, AskUserQuestion |
| **Model (balanced)** | Sonnet |
| **Color** | Orange |
| **Produces** | Compact summary returned to main context; evolves the `.planning/debug/{slug}.md` session file |
**Key behaviors:**
- Reads the debug session file first; passes file paths (not inlined contents) to spawned agents to respect context budget
- Treats all user-supplied AskUserQuestion content as data-only, wrapped in DATA_START/DATA_END markers
- Coordinates TDD gates and reasoning checkpoints introduced in v1.36.0
---
### gsd-code-reviewer
**Role:** Reviews source files for bugs, security vulnerabilities, and code-quality problems; produces a structured `REVIEW.md` with severity-classified findings.
| Property | Value |
|----------|-------|
| **Spawned by** | `/gsd-code-review` |
| **Parallelism** | Typically single instance per review scope |
| **Tools** | Read, Write, Bash, Grep, Glob |
| **Model (balanced)** | Sonnet |
| **Color** | `#F59E0B` (amber) |
| **Produces** | `REVIEW.md` in the phase directory |
**Key behaviors:**
- Detects bugs (logic errors, null/undefined checks, off-by-one, type mismatches, unreachable code), security issues (injection, XSS, hardcoded secrets, insecure crypto), and quality issues
- Honors `CLAUDE.md` project conventions and `.claude/skills/` / `.agents/skills/` rules when present
- Read-only against implementation source — never modifies code under review
---
### gsd-code-fixer
**Role:** Applies fixes to findings from `REVIEW.md` with intelligent (non-blind) patching and atomic per-fix commits; produces `REVIEW-FIX.md`.
| Property | Value |
|----------|-------|
| **Spawned by** | `/gsd-code-review-fix` |
| **Parallelism** | Single instance |
| **Tools** | Read, Edit, Write, Bash, Grep, Glob |
| **Model (balanced)** | Sonnet |
| **Color** | `#10B981` (emerald) |
| **Produces** | `REVIEW-FIX.md`; one atomic git commit per applied fix |
**Key behaviors:**
- Treats `REVIEW.md` suggestions as guidance, not a patch to apply literally
- Commits each fix atomically so review and rollback stay granular
- Honors `CLAUDE.md` and project-skill rules during fixes
---
### gsd-ai-researcher
**Role:** Researches a chosen AI/LLM framework's official documentation and distills it into implementation-ready guidance — framework quick reference, patterns, and pitfalls — for the Section 34b body of `AI-SPEC.md`.
| Property | Value |
|----------|-------|
| **Spawned by** | `/gsd-ai-integration-phase` |
| **Parallelism** | Single instance (sequential with domain-researcher / eval-planner) |
| **Tools** | Read, Write, Bash, Grep, Glob, WebFetch, WebSearch, mcp (context7) |
| **Model (balanced)** | Sonnet |
| **Color** | `#34D399` (green) |
| **Produces** | Sections 34b of `AI-SPEC.md` (framework quick reference + implementation guidance) |
**Key behaviors:**
- Uses Context7 MCP when available; falls back to the `ctx7` CLI via Bash when MCP tools are stripped from the agent
- Anchors guidance to the specific use case, not generic framework overviews
---
### gsd-domain-researcher
**Role:** Surfaces the business-domain and real-world evaluation context for an AI system — expert rubric ingredients, failure modes, regulatory context — before the eval-planner turns it into measurable rubrics. Writes Section 1b of `AI-SPEC.md`.
| Property | Value |
|----------|-------|
| **Spawned by** | `/gsd-ai-integration-phase` |
| **Parallelism** | Single instance |
| **Tools** | Read, Write, Bash, Grep, Glob, WebSearch, WebFetch, mcp (context7) |
| **Model (balanced)** | Sonnet |
| **Color** | `#A78BFA` (violet) |
| **Produces** | Section 1b of `AI-SPEC.md` |
**Key behaviors:**
- Researches the domain, not the technical framework — its output feeds the eval-planner downstream
- Produces rubric ingredients that downstream evaluators can turn into measurable criteria
---
### gsd-eval-planner
**Role:** Designs the structured evaluation strategy for an AI phase — failure modes, eval dimensions with rubrics, tooling, reference dataset, guardrails, production monitoring. Writes Sections 57 of `AI-SPEC.md`.
| Property | Value |
|----------|-------|
| **Spawned by** | `/gsd-ai-integration-phase` |
| **Parallelism** | Single instance (sequential after domain-researcher) |
| **Tools** | Read, Write, Bash, Grep, Glob, AskUserQuestion |
| **Model (balanced)** | Sonnet |
| **Color** | `#F59E0B` (amber) |
| **Produces** | Sections 57 of `AI-SPEC.md` (Evaluation Strategy, Guardrails, Production Monitoring) |
**Required reading:** `get-shit-done/references/ai-evals.md` (evaluation framework).
**Key behaviors:**
- Turns domain-researcher rubric ingredients into measurable, tooled evaluation criteria
- Does not re-derive domain context — reads Section 1 and 1b of `AI-SPEC.md` as established input
---
### gsd-eval-auditor
**Role:** Retroactive audit of an implemented AI phase's evaluation coverage against its planned `AI-SPEC.md` eval strategy. Scores each eval dimension `COVERED` / `PARTIAL` / `MISSING` and produces `EVAL-REVIEW.md`.
| Property | Value |
|----------|-------|
| **Spawned by** | `/gsd-eval-review` |
| **Parallelism** | Single instance |
| **Tools** | Read, Write, Bash, Grep, Glob |
| **Model (balanced)** | Sonnet |
| **Color** | `#EF4444` (red) |
| **Produces** | `EVAL-REVIEW.md` with dimension scores, findings, and remediation guidance |
**Required reading:** `get-shit-done/references/ai-evals.md`.
**Key behaviors:**
- Compares the implemented codebase against the planned eval strategy — never re-plans
- Reads implementation files incrementally to respect context budget
---
### gsd-framework-selector
**Role:** Interactive decision-matrix agent that runs a ≤6-question interview, scores candidate AI/LLM frameworks, and returns a ranked recommendation with rationale.
| Property | Value |
|----------|-------|
| **Spawned by** | `/gsd-ai-integration-phase`, `/gsd-select-framework` |
| **Parallelism** | Single instance (interactive) |
| **Tools** | Read, Bash, Grep, Glob, WebSearch, AskUserQuestion |
| **Model (balanced)** | Sonnet |
| **Color** | `#38BDF8` (sky blue) |
| **Produces** | Scored ranked recommendation (structured return to orchestrator) |
**Required reading:** `get-shit-done/references/ai-frameworks.md` (decision matrix).
**Key behaviors:**
- Scans `package.json`, `pyproject.toml`, `requirements*.txt` for existing AI libraries before the interview to avoid recommending a rejected framework
- Asks only what the codebase scan and CONTEXT.md have not already answered
---
### gsd-intel-updater
**Role:** Reads project source and writes structured intel (JSON + Markdown) into `.planning/intel/`, building a queryable codebase knowledge base that other agents use instead of performing expensive fresh exploration.
| Property | Value |
|----------|-------|
| **Spawned by** | `/gsd-intel` (refresh / update flows) |
| **Parallelism** | Single instance |
| **Tools** | Read, Write, Bash, Glob, Grep |
| **Model (balanced)** | Sonnet |
| **Color** | Cyan |
| **Produces** | `.planning/intel/*.json` (and companion Markdown) consumed by `gsd-sdk query intel` |
**Key behaviors:**
- Writes current state only — no temporal language, every claim references an actual file path
- Uses Glob / Read / Grep for cross-platform correctness; Bash is reserved for `gsd-sdk query intel` CLI calls
---
### gsd-doc-classifier
**Role:** Classifies a single planning document as ADR, PRD, SPEC, DOC, or UNKNOWN. Extracts title, scope summary, and cross-references. Writes a JSON classification file used by `gsd-doc-synthesizer` to build a consolidated context.
| Property | Value |
|----------|-------|
| **Spawned by** | `/gsd-ingest-docs` (parallel fan-out over the doc corpus) |
| **Parallelism** | One instance per input document |
| **Tools** | Read, Write, Grep, Glob |
| **Model (balanced)** | Haiku |
| **Color** | Yellow |
| **Produces** | One JSON classification file per input doc (type, title, scope, refs) |
**Key behaviors:**
- Single-doc scope — never synthesizes or resolves conflicts (that is the synthesizer's job)
- Heuristic-first classification; returns UNKNOWN when the doc lacks type signals rather than guessing
---
### gsd-doc-synthesizer
**Role:** Synthesizes classified planning docs into a single consolidated context. Applies precedence rules, detects cross-reference cycles, enforces LOCKED-vs-LOCKED hard-blocks, and writes `INGEST-CONFLICTS.md` with three buckets (auto-resolved, competing-variants, unresolved-blockers).
| Property | Value |
|----------|-------|
| **Spawned by** | `/gsd-ingest-docs` (after classifier fan-in) |
| **Parallelism** | Single instance |
| **Tools** | Read, Write, Grep, Glob, Bash |
| **Model (balanced)** | Sonnet |
| **Color** | Orange |
| **Produces** | Consolidated context for `.planning/` plus `INGEST-CONFLICTS.md` report |
**Key behaviors:**
- Hard-blocks on LOCKED-vs-LOCKED ADR contradictions instead of silently picking a winner
- Follows the `references/doc-conflict-engine.md` contract so `/gsd-import` and `/gsd-ingest-docs` produce consistent conflict reports
---
## Agent Tool Permissions Summary
> **Scope:** this table covers the 21 primary agents only. The 12 advanced/specialized agents listed above carry their own tool surfaces in their `agents/gsd-*.md` frontmatter (summarized in the per-agent stubs above and in [`docs/INVENTORY.md`](INVENTORY.md)).
| Agent | Read | Write | Edit | Bash | Grep | Glob | WebSearch | WebFetch | MCP |
|-------|------|-------|------|------|------|------|-----------|----------|-----|
| project-researcher | ✓ | ✓ | | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |

View File

@@ -76,6 +76,7 @@ Every agent spawned by an orchestrator gets a clean context window (up to 200K t
### 2. Thin Orchestrators
Workflow files (`get-shit-done/workflows/*.md`) never do heavy lifting. They:
- Load context via `gsd-sdk query init.<workflow>` (or legacy `gsd-tools.cjs init <workflow>`)
- Spawn specialized agents with focused prompts
- Collect results and route to the next step
@@ -84,6 +85,7 @@ Workflow files (`get-shit-done/workflows/*.md`) never do heavy lifting. They:
### 3. File-Based State
All state lives in `.planning/` as human-readable Markdown and JSON. No database, no server, no external dependencies. This means:
- State survives context resets (`/clear`)
- State is inspectable by both humans and agents
- State can be committed to git for team visibility
@@ -95,6 +97,7 @@ Workflow feature flags follow the **absent = enabled** pattern. If a key is miss
### 5. Defense in Depth
Multiple layers prevent common failure modes:
- Plans are verified before execution (plan-checker agent)
- Execution produces atomic commits per task
- Post-execution verification checks against phase goals
@@ -107,28 +110,31 @@ Multiple layers prevent common failure modes:
### Commands (`commands/gsd/*.md`)
User-facing entry points. Each file contains YAML frontmatter (name, description, allowed-tools) and a prompt body that bootstraps the workflow. Commands are installed as:
- **Claude Code:** Custom slash commands (`/gsd-command-name`)
- **OpenCode / Kilo:** Slash commands (`/gsd-command-name`)
- **Codex:** Skills (`$gsd-command-name`)
- **Copilot:** Slash commands (`/gsd-command-name`)
- **Antigravity:** Skills
**Total commands:** 81
**Total commands:** see [`docs/INVENTORY.md`](INVENTORY.md#commands) for the authoritative count and full roster.
### Workflows (`get-shit-done/workflows/*.md`)
Orchestration logic that commands reference. Contains the step-by-step process including:
- Context loading via `gsd-sdk query` init handlers (or legacy `gsd-tools.cjs init`)
- Agent spawn instructions with model resolution
- Gate/checkpoint definitions
- State update patterns
- Error handling and recovery
**Total workflows:** 78
**Total workflows:** see [`docs/INVENTORY.md`](INVENTORY.md#workflows) for the authoritative count and full roster.
### Agents (`agents/*.md`)
Specialized agent definitions with frontmatter specifying:
- `name` — Agent identifier
- `description` — Role and purpose
- `tools` — Allowed tool access (Read, Write, Edit, Bash, Grep, Glob, WebSearch, etc.)
@@ -138,9 +144,10 @@ Specialized agent definitions with frontmatter specifying:
### References (`get-shit-done/references/*.md`)
Shared knowledge documents that workflows and agents `@-reference` (35 total):
Shared knowledge documents that workflows and agents `@-reference` (see [`docs/INVENTORY.md`](INVENTORY.md#references-41-shipped) for the authoritative count and full roster):
**Core references:**
- `checkpoints.md` — Checkpoint type definitions and interaction patterns
- `gates.md` — 4 canonical gate types (Confirm, Quality, Safety, Transition) wired into plan-checker and verifier
- `model-profiles.md` — Per-agent model tier assignments
@@ -156,6 +163,7 @@ Shared knowledge documents that workflows and agents `@-reference` (35 total):
- `common-bug-patterns.md` — Common bug patterns for code review and verification
**Workflow references:**
- `agent-contracts.md` — Formal interface between orchestrators and agents
- `context-budget.md` — Context window budget allocation rules
- `continuation-format.md` — Session continuation/resume format
@@ -190,7 +198,7 @@ The planner agent (`agents/gsd-planner.md`) was decomposed from a single monolit
### Templates (`get-shit-done/templates/`)
Markdown templates for all planning artifacts. Used by `gsd-tools.cjs template fill` and `scaffold` commands to create pre-structured files:
Markdown templates for all planning artifacts. Used by `gsd-sdk query template.fill` / `phase.scaffold` (and legacy `gsd-tools.cjs template fill` / top-level `scaffold`) to create pre-structured files:
- `project.md`, `requirements.md`, `roadmap.md`, `state.md` — Core project files
- `phase-prompt.md` — Phase execution prompt template
- `summary.md` (+ `summary-minimal.md`, `summary-standard.md`, `summary-complex.md`) — Granularity-aware summary templates
@@ -208,39 +216,45 @@ Runtime hooks that integrate with the host AI agent:
|------|-------|---------|
| `gsd-statusline.js` | `statusLine` | Displays model, task, directory, and context usage bar |
| `gsd-context-monitor.js` | `PostToolUse` / `AfterTool` | Injects agent-facing context warnings at 35%/25% remaining |
| `gsd-check-update.js` | `SessionStart` | Background check for new GSD versions |
| `gsd-check-update.js` | `SessionStart` | Foreground trigger for the background update check |
| `gsd-check-update-worker.js` | (helper) | Background worker spawned by `gsd-check-update.js`; no direct event registration |
| `gsd-prompt-guard.js` | `PreToolUse` | Scans `.planning/` writes for prompt injection patterns (advisory) |
| `gsd-read-injection-scanner.js` | `PostToolUse` | Scans Read tool output for injected instructions in untrusted content |
| `gsd-workflow-guard.js` | `PreToolUse` | Detects file edits outside GSD workflow context (advisory, opt-in via `hooks.workflow_guard`) |
| `gsd-read-guard.js` | `PreToolUse` | Advisory guard preventing Edit/Write on files not yet read in the session |
| `gsd-session-state.sh` | `PostToolUse` | Session state tracking for shell-based runtimes |
| `gsd-validate-commit.sh` | `PostToolUse` | Commit validation for conventional commit enforcement |
| `gsd-phase-boundary.sh` | `PostToolUse` | Phase boundary detection for workflow transitions |
See [`docs/INVENTORY.md`](INVENTORY.md#hooks-11-shipped) for the authoritative 11-hook roster.
### CLI Tools (`get-shit-done/bin/`)
Node.js CLI utility (`gsd-tools.cjs`) with 19 domain modules:
Node.js CLI utility (`gsd-tools.cjs`) with domain modules split across `get-shit-done/bin/lib/` (see [`docs/INVENTORY.md`](INVENTORY.md#cli-modules-24-shipped) for the authoritative roster):
| Module | Responsibility |
| ---------------------- | --------------------------------------------------------------------------------------------------- |
| `core.cjs` | Error handling, output formatting, shared utilities |
| `state.cjs` | STATE.md parsing, updating, progression, metrics |
| `phase.cjs` | Phase directory operations, decimal numbering, plan indexing |
| `roadmap.cjs` | ROADMAP.md parsing, phase extraction, plan progress |
| `config.cjs` | config.json read/write, section initialization |
| `verify.cjs` | Plan structure, phase completeness, reference, commit validation |
| `template.cjs` | Template selection and filling with variable substitution |
| `frontmatter.cjs` | YAML frontmatter CRUD operations |
| `init.cjs` | Compound context loading for each workflow type |
| `milestone.cjs` | Milestone archival, requirements marking |
| `commands.cjs` | Misc commands (slug, timestamp, todos, scaffolding, stats) |
| `model-profiles.cjs` | Model profile resolution table |
| `security.cjs` | Path traversal prevention, prompt injection detection, safe JSON parsing, shell argument validation |
| `uat.cjs` | UAT file parsing, verification debt tracking, audit-uat support |
| `docs.cjs` | Docs-update workflow init, Markdown scanning, monorepo detection |
| `workstream.cjs` | Workstream CRUD, migration, session-scoped active pointer |
| `schema-detect.cjs` | Schema-drift detection for ORM patterns (Prisma, Drizzle, etc.) |
| `profile-pipeline.cjs` | User behavioral profiling data pipeline, session file scanning |
| `profile-output.cjs` | Profile rendering, USER-PROFILE.md and dev-preferences.md generation |
| Module | Responsibility |
|--------|---------------|
| `core.cjs` | Error handling, output formatting, shared utilities |
| `state.cjs` | STATE.md parsing, updating, progression, metrics |
| `phase.cjs` | Phase directory operations, decimal numbering, plan indexing |
| `roadmap.cjs` | ROADMAP.md parsing, phase extraction, plan progress |
| `config.cjs` | config.json read/write, section initialization |
| `verify.cjs` | Plan structure, phase completeness, reference, commit validation |
| `template.cjs` | Template selection and filling with variable substitution |
| `frontmatter.cjs` | YAML frontmatter CRUD operations |
| `init.cjs` | Compound context loading for each workflow type |
| `milestone.cjs` | Milestone archival, requirements marking |
| `commands.cjs` | Misc commands (slug, timestamp, todos, scaffolding, stats) |
| `model-profiles.cjs` | Model profile resolution table |
| `security.cjs` | Path traversal prevention, prompt injection detection, safe JSON parsing, shell argument validation |
| `uat.cjs` | UAT file parsing, verification debt tracking, audit-uat support |
| `docs.cjs` | Docs-update workflow init, Markdown scanning, monorepo detection |
| `workstream.cjs` | Workstream CRUD, migration, session-scoped active pointer |
| `schema-detect.cjs` | Schema-drift detection for ORM patterns (Prisma, Drizzle, etc.) |
| `profile-pipeline.cjs` | User behavioral profiling data pipeline, session file scanning |
| `profile-output.cjs` | Profile rendering, USER-PROFILE.md and dev-preferences.md generation |
---
@@ -251,10 +265,10 @@ Node.js CLI utility (`gsd-tools.cjs`) with 19 domain modules:
```
Orchestrator (workflow .md)
├── Load context: gsd-tools.cjs init <workflow> <phase>
├── Load context: gsd-sdk query init.<workflow> <phase> (or legacy gsd-tools.cjs init)
│ Returns JSON with: project info, config, state, phase details
├── Resolve model: gsd-tools.cjs resolve-model <agent-name>
├── Resolve model: gsd-sdk query resolve-model <agent-name>
│ Returns: opus | sonnet | haiku | inherit
├── Spawn Agent (Task/SubAgent call)
@@ -265,25 +279,29 @@ Orchestrator (workflow .md)
├── Collect result
└── Update state: gsd-tools.cjs state update/patch/advance-plan
└── Update state: gsd-sdk query state.update / state.patch / state.advance-plan (or legacy gsd-tools.cjs)
```
### Agent Spawn Categories
### Primary Agent Spawn Categories
Conceptual spawn-pattern taxonomy for the 21 primary agents. For the authoritative 31-agent roster (including the 10 advanced/specialized agents such as `gsd-pattern-mapper`, `gsd-code-reviewer`, `gsd-code-fixer`, `gsd-ai-researcher`, `gsd-domain-researcher`, `gsd-eval-planner`, `gsd-eval-auditor`, `gsd-framework-selector`, `gsd-debug-session-manager`, `gsd-intel-updater`), see [`docs/INVENTORY.md`](INVENTORY.md#agents-31-shipped).
| Category | Agents | Parallelism |
| ---------------- | --------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| **Researchers** | gsd-project-researcher, gsd-phase-researcher, gsd-ui-researcher, gsd-advisor-researcher | 4 parallel (stack, features, architecture, pitfalls); advisor spawns during discuss-phase |
| **Synthesizers** | gsd-research-synthesizer | Sequential (after researchers complete) |
| **Planners** | gsd-planner, gsd-roadmapper | Sequential |
| **Checkers** | gsd-plan-checker, gsd-integration-checker, gsd-ui-checker, gsd-nyquist-auditor | Sequential (verification loop, max 3 iterations) |
| **Executors** | gsd-executor | Parallel within waves, sequential across waves |
| **Verifiers** | gsd-verifier | Sequential (after all executors complete) |
| **Mappers** | gsd-codebase-mapper | 4 parallel (tech, arch, quality, concerns) |
| **Debuggers** | gsd-debugger | Sequential (interactive) |
| **Auditors** | gsd-ui-auditor, gsd-security-auditor | Sequential |
| **Doc Writers** | gsd-doc-writer, gsd-doc-verifier | Sequential (writer then verifier) |
| **Profilers** | gsd-user-profiler | Sequential |
| **Analyzers** | gsd-assumptions-analyzer | Sequential (during discuss-phase) |
| Category | Agents | Parallelism |
|----------|--------|-------------|
| **Researchers** | gsd-project-researcher, gsd-phase-researcher, gsd-ui-researcher, gsd-advisor-researcher | 4 parallel (stack, features, architecture, pitfalls); advisor spawns during discuss-phase |
| **Synthesizers** | gsd-research-synthesizer | Sequential (after researchers complete) |
| **Planners** | gsd-planner, gsd-roadmapper | Sequential |
| **Checkers** | gsd-plan-checker, gsd-integration-checker, gsd-ui-checker, gsd-nyquist-auditor | Sequential (verification loop, max 3 iterations) |
| **Executors** | gsd-executor | Parallel within waves, sequential across waves |
| **Verifiers** | gsd-verifier | Sequential (after all executors complete) |
| **Mappers** | gsd-codebase-mapper | 4 parallel (tech, arch, quality, concerns) |
| **Debuggers** | gsd-debugger | Sequential (interactive) |
| **Auditors** | gsd-ui-auditor, gsd-security-auditor | Sequential |
| **Doc Writers** | gsd-doc-writer, gsd-doc-verifier | Sequential (writer then verifier) |
| **Profilers** | gsd-user-profiler | Sequential |
| **Analyzers** | gsd-assumptions-analyzer | Sequential (during discuss-phase) |
### Wave Execution Model
@@ -299,6 +317,7 @@ Wave Analysis:
```
Each executor gets:
- Fresh 200K context window (or up to 1M for models that support it)
- The specific PLAN.md to execute
- Project context (PROJECT.md, STATE.md)
@@ -311,14 +330,13 @@ When the context window is 500K+ tokens (1M-class models like Opus 4.6, Sonnet 4
- **Executor agents** receive prior wave SUMMARY.md files and the phase CONTEXT.md/RESEARCH.md, enabling cross-plan awareness within a phase
- **Verifier agents** receive all PLAN.md, SUMMARY.md, CONTEXT.md files plus REQUIREMENTS.md, enabling history-aware verification
The orchestrator reads `context_window` from config (`gsd-tools.cjs config-get context_window`) and conditionally includes richer context when the value is >= 500,000. For standard 200K windows, prompts use truncated versions with cache-friendly ordering to maximize context efficiency.
The orchestrator reads `context_window` from config (`gsd-sdk query config-get context_window`, or legacy `gsd-tools.cjs config-get`) and conditionally includes richer context when the value is >= 500,000. For standard 200K windows, prompts use truncated versions with cache-friendly ordering to maximize context efficiency.
#### Parallel Commit Safety
When multiple executors run within the same wave, two mechanisms prevent conflicts:
1. **`--no-verify` commits** — Parallel agents skip pre-commit hooks (which can cause build lock contention, e.g., cargo lock fights in Rust projects). The orchestrator runs `git hook run pre-commit` once after each wave completes.
1. `--no-verify` commits — Parallel agents skip pre-commit hooks (which can cause build lock contention, e.g., cargo lock fights in Rust projects). The orchestrator runs `git hook run pre-commit` once after each wave completes.
2. **STATE.md file locking** — All `writeStateMd()` calls use lockfile-based mutual exclusion (`STATE.md.lock` with `O_EXCL` atomic creation). This prevents the read-modify-write race condition where two agents read STATE.md, modify different fields, and the last writer overwrites the other's changes. Includes stale lock detection (10s timeout) and spin-wait with jitter.
---
@@ -409,23 +427,22 @@ UI-SPEC.md (per phase) ───────────────────
```
~/.claude/ # Claude Code (global install)
├── commands/gsd/*.md # 81 slash commands
├── commands/gsd/*.md # Slash commands (authoritative roster: docs/INVENTORY.md)
├── get-shit-done/
│ ├── bin/gsd-tools.cjs # CLI utility
│ ├── bin/lib/*.cjs # 19 domain modules
│ ├── workflows/*.md # 78 workflow definitions
│ ├── references/*.md # 35 shared reference docs
│ ├── bin/lib/*.cjs # Domain modules (authoritative roster: docs/INVENTORY.md)
│ ├── workflows/*.md # Workflow definitions (authoritative roster: docs/INVENTORY.md)
│ ├── references/*.md # Shared reference docs (authoritative roster: docs/INVENTORY.md)
│ └── templates/ # Planning artifact templates
├── agents/*.md # 33 agent definitions
├── hooks/
│ ├── gsd-statusline.js # Statusline hook
│ ├── gsd-context-monitor.js # Context warning hook
│ └── gsd-check-update.js # Update check hook
├── agents/*.md # Agent definitions (authoritative roster: docs/INVENTORY.md)
├── hooks/*.js # Node.js hooks (statusline, guards, monitors, update check)
├── hooks/*.sh # Shell hooks (session state, commit validation, phase boundary)
├── settings.json # Hook registrations
└── VERSION # Installed version number
```
Equivalent paths for other runtimes:
- **OpenCode:** `~/.config/opencode/` or `~/.opencode/`
- **Kilo:** `~/.config/kilo/` or `~/.kilo/`
- **Gemini CLI:** `~/.gemini/`
@@ -495,16 +512,16 @@ The installer (`bin/install.js`, ~3,000 lines) handles:
2. **Location selection** — Global (`--global`) or local (`--local`)
3. **File deployment** — Copies commands, workflows, references, templates, agents, hooks
4. **Runtime adaptation** — Transforms file content per runtime:
- Claude Code: Uses as-is
- OpenCode: Converts commands/agents to OpenCode-compatible flat command + subagent format
- Kilo: Reuses the OpenCode conversion pipeline with Kilo config paths
- Codex: Generates TOML config + skills from commands
- Copilot: Maps tool names (Read→read, Bash→execute, etc.)
- Gemini: Adjusts hook event names (`AfterTool` instead of `PostToolUse`)
- Antigravity: Skills-first with Google model equivalents
- Trae: Skills-first install to `~/.trae` / `./.trae` with no `settings.json` or hook integration
- Cline: Writes `.clinerules` for rule-based integration
- Augment Code: Skills-first with full skill conversion and config management
- Claude Code: Uses as-is
- OpenCode: Converts commands/agents to OpenCode-compatible flat command + subagent format
- Kilo: Reuses the OpenCode conversion pipeline with Kilo config paths
- Codex: Generates TOML config + skills from commands
- Copilot: Maps tool names (Read→read, Bash→execute, etc.)
- Gemini: Adjusts hook event names (`AfterTool` instead of `PostToolUse`)
- Antigravity: Skills-first with Google model equivalents
- Trae: Skills-first install to `~/.trae` / `./.trae` with no `settings.json` or hook integration
- Cline: Writes `.clinerules` for rule-based integration
- Augment Code: Skills-first with full skill conversion and config management
5. **Path normalization** — Replaces `~/.claude/` paths with runtime-specific paths
6. **Settings integration** — Registers hooks in runtime's `settings.json`
7. **Patch backup** — Since v1.17, backs up locally modified files to `gsd-local-patches/` for `/gsd-reapply-patches`
@@ -541,11 +558,13 @@ Runtime Engine (Claude Code / Gemini CLI)
### Context Monitor Thresholds
| Remaining Context | Level | Agent Behavior |
|-------------------|-------|----------------|
| > 35% | Normal | No warning injected |
| 35% | WARNING | "Avoid starting new complex work" |
| ≤ 25% | CRITICAL | "Context nearly exhausted, inform user" |
| Remaining Context | Level | Agent Behavior |
| ----------------- | -------- | --------------------------------------- |
| > 35% | Normal | No warning injected |
| ≤ 35% | WARNING | "Avoid starting new complex work" |
| ≤ 25% | CRITICAL | "Context nearly exhausted, inform user" |
Debounce: 5 tool uses between repeated warnings. Severity escalation (WARNING→CRITICAL) bypasses debounce.
@@ -560,12 +579,14 @@ Debounce: 5 tool uses between repeated warnings. Severity escalation (WARNING→
### Security Hooks (v1.27)
**Prompt Guard** (`gsd-prompt-guard.js`):
- Triggers on Write/Edit to `.planning/` files
- Scans content for prompt injection patterns (role override, instruction bypass, system tag injection)
- Advisory-only — logs detection, does not block
- Patterns are inlined (subset of `security.cjs`) for hook independence
**Workflow Guard** (`gsd-workflow-guard.js`):
- Triggers on Write/Edit to non-`.planning/` files
- Detects edits outside GSD workflow context (no active `/gsd-` command or Task subagent)
- Advises using `/gsd-quick` or `/gsd-fast` for state-tracked changes
@@ -577,18 +598,20 @@ Debounce: 5 tool uses between repeated warnings. Severity escalation (WARNING→
GSD supports multiple AI coding runtimes through a unified command/workflow architecture:
| Runtime | Command Format | Agent System | Config Location |
|---------|---------------|--------------|-----------------|
| Claude Code | `/gsd-command` | Task spawning | `~/.claude/` |
| OpenCode | `/gsd-command` | Subagent mode | `~/.config/opencode/` |
| Kilo | `/gsd-command` | Subagent mode | `~/.config/kilo/` |
| Gemini CLI | `/gsd-command` | Task spawning | `~/.gemini/` |
| Codex | `$gsd-command` | Skills | `~/.codex/` |
| Copilot | `/gsd-command` | Agent delegation | `~/.github/` |
| Antigravity | Skills | Skills | `~/.gemini/antigravity/` |
| Trae | Skills | Skills | `~/.trae/` |
| Cline | Rules | Rules | `.clinerules` |
| Augment Code | Skills | Skills | Augment config |
| Runtime | Command Format | Agent System | Config Location |
| ------------ | -------------- | ---------------- | ------------------------ |
| Claude Code | `/gsd-command` | Task spawning | `~/.claude/` |
| OpenCode | `/gsd-command` | Subagent mode | `~/.config/opencode/` |
| Kilo | `/gsd-command` | Subagent mode | `~/.config/kilo/` |
| Gemini CLI | `/gsd-command` | Task spawning | `~/.gemini/` |
| Codex | `$gsd-command` | Skills | `~/.codex/` |
| Copilot | `/gsd-command` | Agent delegation | `~/.github/` |
| Antigravity | Skills | Skills | `~/.gemini/antigravity/` |
| Trae | Skills | Skills | `~/.trae/` |
| Cline | Rules | Rules | `.clinerules` |
| Augment Code | Skills | Skills | Augment config |
### Abstraction Points
@@ -598,4 +621,4 @@ GSD supports multiple AI coding runtimes through a unified command/workflow arch
4. **Path conventions** — Each runtime stores config in different directories
5. **Model references**`inherit` profile lets GSD defer to runtime's model selection
The installer handles all translation at install time. Workflows and agents are written in Claude Code's native format and transformed during deployment.
The installer handles all translation at install time. Workflows and agents are written in Claude Code's native format and transformed during deployment.

View File

@@ -1,29 +1,71 @@
# GSD CLI Tools Reference
> Programmatic API reference for `gsd-tools.cjs`. Used by workflows and agents internally. For user-facing commands, see [Command Reference](COMMANDS.md).
> Surface-area reference for `get-shit-done/bin/gsd-tools.cjs` (legacy Node CLI). Workflows and agents should prefer `gsd-sdk query` or `@gsd-build/sdk` where a handler exists — see [SDK and programmatic access](#sdk-and-programmatic-access). For slash commands and user flows, see [Command Reference](COMMANDS.md).
---
## Overview
`gsd-tools.cjs` is a Node.js CLI utility that replaces repetitive inline bash patterns across GSD's ~50 command, workflow, and agent files. It centralizes: config parsing, model resolution, phase lookup, git commits, summary verification, state management, and template operations.
`gsd-tools.cjs` centralizes config parsing, model resolution, phase lookup, git commits, summary verification, state management, and template operations across GSD commands, workflows, and agents.
**Preferred for new orchestration:** Many of the same operations are available as `gsd-sdk query <command>` (see `sdk/src/query/index.ts` and `docs/QUERY-HANDLERS.md`). Use that in workflows and examples where the handler exists; keep `node … gsd-tools.cjs` for commands not yet in the registry (for example graphify) or when you need CJS-only flags.
**Location:** `get-shit-done/bin/gsd-tools.cjs`
**Modules:** 15 domain modules in `get-shit-done/bin/lib/`
| | |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Shipped path** | `get-shit-done/bin/gsd-tools.cjs` |
| **Implementation** | 20 domain modules under `get-shit-done/bin/lib/` (the directory is authoritative) |
| **Status** | Maintained for parity tests and CJS-only entrypoints; `gsd-sdk query` / SDK registry are the supported path for new orchestration (see [QUERY-HANDLERS.md](../sdk/src/query/QUERY-HANDLERS.md)). |
**Usage (CJS):**
**Usage:**
```bash
node gsd-tools.cjs <command> [args] [--raw] [--cwd <path>]
```
**Global Flags:**
| Flag | Description |
|------|-------------|
| `--raw` | Machine-readable output (JSON or plain text, no formatting) |
| `--cwd <path>` | Override working directory (for sandboxed subagents) |
| `--ws <name>` | Target a specific workstream context (SDK only) |
**Global flags (CJS):**
| Flag | Description |
| -------------- | ---------------------------------------------------------------------------- |
| `--raw` | Machine-readable output (JSON or plain text, no formatting) |
| `--cwd <path>` | Override working directory (for sandboxed subagents) |
| `--ws <name>` | Workstream context (also honored when the SDK spawns this binary; see below) |
---
## SDK and programmatic access
Use this when authoring workflows, not when you only need the command list below.
**1. CLI — `gsd-sdk query <argv…>`**
- Resolves argv with the same **longest-prefix** rules as the typed registry (`resolveQueryArgv` in `sdk/src/query/registry.ts`). Unregistered commands **fail fast** — use `node …/gsd-tools.cjs` only for handlers not in the registry.
- Full matrix (CJS command → registry key, CLI-only tools, aliases, golden tiers): [sdk/src/query/QUERY-HANDLERS.md](../sdk/src/query/QUERY-HANDLERS.md).
**2. TypeScript — `@gsd-build/sdk` (`GSDTools`, `createRegistry`)**
- `GSDTools` (used by `PhaseRunner`, `InitRunner`, and `GSD.createTools()`) always shells out to `gsd-tools.cjs` via `execFile` — there is no in-process registry path on this class. For typed, in-process dispatch use `createRegistry()` from `sdk/src/query/index.ts`, or invoke `gsd-sdk query` (see [QUERY-HANDLERS.md](../sdk/src/query/QUERY-HANDLERS.md)).
- Conventions: mutation event wiring, `GSDError` vs `{ data: { error } }`, locks, and stubs — [QUERY-HANDLERS.md](../sdk/src/query/QUERY-HANDLERS.md).
**CJS → SDK examples (same project directory):**
| Legacy CJS | Preferred `gsd-sdk query` (examples) |
| ---------------------------------------- | ------------------------------------ |
| `node gsd-tools.cjs init phase-op 12` | `gsd-sdk query init phase-op 12` |
| `node gsd-tools.cjs phase-plan-index 12` | `gsd-sdk query phase-plan-index 12` |
| `node gsd-tools.cjs state json` | `gsd-sdk query state json` |
| `node gsd-tools.cjs roadmap analyze` | `gsd-sdk query roadmap analyze` |
**SDK state reads:** `gsd-sdk query state json` / `state.json` and `gsd-sdk query state load` / `state.load` currently share one native handler (rebuilt STATE.md frontmatter — CJS `cmdStateJson`). The legacy CJS `state load` payload (`config`, `state_raw`, existence flags) is still **CLI-only** via `node …/gsd-tools.cjs state load` until a separate registry handler exists. Full routing and golden rules: [QUERY-HANDLERS.md](../sdk/src/query/QUERY-HANDLERS.md).
**CLI-only (not in registry):** e.g. **graphify**, **from-gsd2** / **gsd2-import** — call `gsd-tools.cjs` until registered.
**Mutation events (SDK):** `QUERY_MUTATION_COMMANDS` in `sdk/src/query/index.ts` lists commands that may emit structured events after a successful dispatch. Exceptions called out in QUERY-HANDLERS: `state validate` (read-only), `skill-manifest` (writes only with `--write`), `intel update` (stub).
**Golden parity:** Policy and CJS↔SDK test categories are documented under **Golden parity** in [QUERY-HANDLERS.md](../sdk/src/query/QUERY-HANDLERS.md).
---
@@ -67,6 +109,13 @@ node gsd-tools.cjs state resolve-blocker --text "..."
# Record session continuity
node gsd-tools.cjs state record-session --stopped-at "..." [--resume-file path]
# Phase start — update STATE.md Status/Last activity for a new phase
node gsd-tools.cjs state begin-phase --phase N --name SLUG --plans COUNT
# Agent-discoverable blocker signalling (used by discuss-phase / UI flows)
node gsd-tools.cjs state signal-waiting --type TYPE --question "..." --options "A|B" --phase P
node gsd-tools.cjs state signal-resume
```
### State Snapshot
@@ -356,11 +405,17 @@ node gsd-tools.cjs todo complete <filename>
# UAT audit — scan all phases for unresolved items
node gsd-tools.cjs audit-uat
# Cross-artifact audit queue — scan `.planning/` for unresolved audit items
node gsd-tools.cjs audit-open [--json]
# Reverse-migrate a GSD-2 project into the current structure (backs `/gsd-from-gsd2`)
node gsd-tools.cjs from-gsd2 [--path <dir>] [--force] [--dry-run]
# Git commit with config checks
node gsd-tools.cjs commit <message> [--files f1 f2] [--amend] [--no-verify]
```
> **`--no-verify`**: Skips pre-commit hooks. Used by parallel executor agents during wave-based execution to avoid build lock contention (e.g., cargo lock fights in Rust projects). The orchestrator runs hooks once after each wave completes. Do not use `--no-verify` during sequential execution — let hooks run normally.
> `--no-verify`: Skips pre-commit hooks. Used by parallel executor agents during wave-based execution to avoid build lock contention (e.g., cargo lock fights in Rust projects). The orchestrator runs hooks once after each wave completes. Do not use `--no-verify` during sequential execution — let hooks run normally.
# Web search (requires Brave API key)
node gsd-tools.cjs websearch <query> [--limit N] [--freshness day|week|month]
@@ -368,6 +423,31 @@ node gsd-tools.cjs websearch <query> [--limit N] [--freshness day|week|month]
---
## Graphify
Build, query, and inspect the project knowledge graph in `.planning/graphs/`. Requires `graphify.enabled: true` in `config.json` (see [Configuration Reference](CONFIGURATION.md#graphify-settings)). Graphify is **CJS-only**: `gsd-sdk query` does not yet register graphify handlers — always use `node gsd-tools.cjs graphify …`.
```bash
# Build or rebuild the knowledge graph
node gsd-tools.cjs graphify build
# Search the graph for a term
node gsd-tools.cjs graphify query <term>
# Show graph freshness and statistics
node gsd-tools.cjs graphify status
# Show changes since the last build
node gsd-tools.cjs graphify diff
# Write a named snapshot of the current graph
node gsd-tools.cjs graphify snapshot [name]
```
User-facing entry point: `/gsd-graphify` (see [Command Reference](COMMANDS.md#gsd-graphify)).
---
## Module Architecture
| Module | File | Exports |
@@ -387,3 +467,16 @@ node gsd-tools.cjs websearch <query> [--limit N] [--freshness day|week|month]
| UAT | `lib/uat.cjs` | Cross-phase UAT/verification audit |
| Profile Output | `lib/profile-output.cjs` | Developer profile formatting |
| Profile Pipeline | `lib/profile-pipeline.cjs` | Session analysis pipeline |
| Graphify | `lib/graphify.cjs` | Knowledge graph build/query/status/diff/snapshot (backs `/gsd-graphify`) |
| Learnings | `lib/learnings.cjs` | Extract learnings from phases/SUMMARY artifacts (backs `/gsd-extract-learnings`) |
| Audit | `lib/audit.cjs` | Phase/milestone audit queue handlers; `audit-open` helper |
| GSD2 Import | `lib/gsd2-import.cjs` | Reverse-migration importer from GSD-2 projects (backs `/gsd-from-gsd2`) |
| Intel | `lib/intel.cjs` | Queryable codebase intelligence index (backs `/gsd-intel`) |
---
## See also
- [sdk/src/query/QUERY-HANDLERS.md](../sdk/src/query/QUERY-HANDLERS.md) — registry matrix, routing, golden parity, intentional CJS differences
- [Architecture](ARCHITECTURE.md) — where `gsd-sdk query` fits in orchestration
- [Command Reference](COMMANDS.md) — user-facing `/gsd:` commands

View File

@@ -1,6 +1,6 @@
# GSD Command Reference
> Complete command syntax, flags, options, and examples. For feature details, see [Feature Reference](FEATURES.md). For workflow walkthroughs, see [User Guide](USER-GUIDE.md).
> Command syntax, flags, options, and examples for stable commands. For feature details, see [Feature Reference](FEATURES.md). For workflow walkthroughs, see [User Guide](USER-GUIDE.md).
---
@@ -169,6 +169,43 @@ Research, plan, and verify a phase.
---
### `/gsd-plan-review-convergence`
Cross-AI plan convergence loop. Runs `plan-phase → review → replan → re-review` cycles until no HIGH concerns remain (max 3 cycles by default). Spawns isolated agents for planning and review; orchestrator handles loop control, HIGH-concern counting, stall detection, and escalation.
| Argument / Flag | Required | Description |
|-----------------|----------|-------------|
| `N` | **Yes** | Phase number to plan and review |
| `--codex` / `--gemini` / `--claude` / `--opencode` | No | Single-reviewer selection |
| `--all` | No | Run every configured reviewer in parallel |
| `--max-cycles N` | No | Override cycle cap (default 3) |
**Exit behavior:** Loop exits when HIGH count hits zero. Stall detection warns when HIGH count is not decreasing across cycles. Escalation gate asks the user to proceed or review manually when `--max-cycles` is hit with HIGH concerns still open.
```bash
/gsd-plan-review-convergence 3 # Default reviewers, 3 cycles
/gsd-plan-review-convergence 3 --codex # Codex-only review
/gsd-plan-review-convergence 3 --all --max-cycles 5
```
---
### `/gsd-ultraplan-phase`
**[BETA — Claude Code only.]** Offload plan-phase work to Claude Code's ultraplan cloud. The plan drafts remotely so the terminal stays free; review inline comments in a browser, then import the finalized plan back into `.planning/` via `/gsd-import`.
| Flag | Required | Description |
|------|----------|-------------|
| `N` | **Yes** | Phase number to plan remotely |
**Isolation:** Intentionally separate from `/gsd-plan-phase` so upstream ultraplan changes cannot affect the core planning pipeline.
```bash
/gsd-ultraplan-phase 4 # Offload planning for phase 4
```
---
### `/gsd-execute-phase`
Execute all plans in a phase with wave-based parallelization, or run a specific wave.
@@ -606,6 +643,27 @@ Ingest an external plan file into the GSD planning system with conflict detectio
---
### `/gsd-ingest-docs`
Scan a repo containing mixed ADRs, PRDs, SPECs, and DOCs and bootstrap or merge the full `.planning/` setup from them in a single pass. Parallel classification (`gsd-doc-classifier`) plus synthesis with precedence rules and cycle detection (`gsd-doc-synthesizer`). Produces a three-bucket conflicts report (`INGEST-CONFLICTS.md`: auto-resolved, competing-variants, unresolved-blockers) and hard-blocks on LOCKED-vs-LOCKED ADR contradictions.
| Argument / Flag | Required | Description |
|-----------------|----------|-------------|
| `path` | No | Target directory to scan (defaults to repo root) |
| `--mode new\|merge` | No | Override auto-detect (defaults: `new` if `.planning/` absent, `merge` if present) |
| `--manifest <file>` | No | YAML file listing `{path, type, precedence?}` per doc; overrides heuristic classification |
| `--resolve auto` | No | Conflict resolution mode (v1: only `auto`; `interactive` is reserved) |
**Limits:** v1 caps at 50 docs per invocation. Extracts the shared conflict-detection contract into `references/doc-conflict-engine.md`, which `/gsd-import` also consumes.
```bash
/gsd-ingest-docs # Scan repo root, auto-detect mode
/gsd-ingest-docs docs/ # Only ingest under docs/
/gsd-ingest-docs --manifest ingest.yaml # Explicit precedence manifest
```
---
### `/gsd-from-gsd2`
Reverse migration from GSD-2 format (`.gsd/` with Milestone→Slice→Task hierarchy) back to v1 `.planning/` format.
@@ -637,17 +695,27 @@ Execute ad-hoc task with GSD guarantees.
| Flag | Description |
|------|-------------|
| `--full` | Enable plan checking (2 iterations) + post-execution verification |
| `--full` | Enable the complete quality pipeline — discussion + research + plan-checking + verification |
| `--validate` | Plan-checking (max 2 iterations) + post-execution verification only; no discussion or research |
| `--discuss` | Lightweight pre-planning discussion |
| `--research` | Spawn focused researcher before planning |
Flags are composable.
Granular flags are composable: `--discuss --research --validate` is equivalent to `--full`.
| Subcommand | Description |
|------------|-------------|
| `list` | List all quick tasks with status |
| `status <slug>` | Show status of a specific quick task |
| `resume <slug>` | Resume a specific quick task by slug |
```bash
/gsd-quick # Basic quick task
/gsd-quick --discuss --research # Discussion + research + planning
/gsd-quick --full # With plan checking and verification
/gsd-quick --discuss --research --full # All optional stages
/gsd-quick --validate # Plan-checking + verification only
/gsd-quick --full # Complete quality pipeline
/gsd-quick list # List all quick tasks
/gsd-quick status my-task-slug # Show status of a quick task
/gsd-quick resume my-task-slug # Resume a quick task
```
### `/gsd-autonomous`
@@ -1045,6 +1113,28 @@ Query, inspect, or refresh queryable codebase intelligence files stored in `.pla
/gsd-intel refresh # Rebuild intel index
```
### `/gsd-graphify`
Build, query, and inspect the project knowledge graph stored in `.planning/graphs/`. Opt-in via `graphify.enabled: true` in `config.json` (see [Configuration Reference](CONFIGURATION.md#graphify-settings)); when disabled, the command prints an activation hint and stops.
| Subcommand | Description |
|------------|-------------|
| `build` | Build or rebuild the knowledge graph (spawns the graphify-builder agent) |
| `query <term>` | Search the graph for a term |
| `status` | Show graph freshness and statistics |
| `diff` | Show changes since the last build |
**Produces:** `.planning/graphs/` graph artifacts (nodes, edges, snapshots)
```bash
/gsd-graphify build # Build or rebuild the knowledge graph
/gsd-graphify query authentication # Search the graph for a term
/gsd-graphify status # Show freshness and statistics
/gsd-graphify diff # Show changes since last build
```
**Programmatic access:** `node gsd-tools.cjs graphify <build|query|status|diff|snapshot>` — see [CLI Tools Reference](CLI-TOOLS.md).
---
## AI Integration Commands
@@ -1346,7 +1436,11 @@ Manage persistent context threads for cross-session work.
| Argument | Required | Description |
|----------|----------|-------------|
| (none) | — | List all threads |
| (none) / `list` | — | List all threads |
| `list --open` | — | List threads with status `open` or `in_progress` only |
| `list --resolved` | — | List threads with status `resolved` only |
| `status <slug>` | — | Show status of a specific thread |
| `close <slug>` | — | Mark a thread as resolved |
| `name` | — | Resume existing thread by name |
| `description` | — | Create new thread |
@@ -1354,6 +1448,10 @@ Threads are lightweight cross-session knowledge stores for work that spans multi
```bash
/gsd-thread # List all threads
/gsd-thread list --open # List only open/in-progress threads
/gsd-thread list --resolved # List only resolved threads
/gsd-thread status fix-deploy-key # Show thread status
/gsd-thread close fix-deploy-key # Mark thread as resolved
/gsd-thread fix-deploy-key-auth # Resume thread
/gsd-thread "Investigate TCP timeout in pasta service" # Create new
```

View File

@@ -18,9 +18,10 @@ GSD stores project settings in `.planning/config.json`. Created during `/gsd-new
"model_overrides": {},
"planning": {
"commit_docs": true,
"search_gitignored": false
"search_gitignored": false,
"sub_repos": []
},
"context_profile": null,
"context": null,
"workflow": {
"research": true,
"plan_check": true,
@@ -29,10 +30,12 @@ GSD stores project settings in `.planning/config.json`. Created during `/gsd-new
"nyquist_validation": true,
"ui_phase": true,
"ui_safety_gate": true,
"ui_review": true,
"node_repair": true,
"node_repair_budget": 2,
"research_before_questions": false,
"discuss_mode": "discuss",
"max_discuss_passes": 3,
"skip_discuss": false,
"tdd_mode": false,
"text_mode": false,
@@ -42,10 +45,14 @@ GSD stores project settings in `.planning/config.json`. Created during `/gsd-new
"plan_bounce": false,
"plan_bounce_script": null,
"plan_bounce_passes": 2,
"plan_chunked": false,
"code_review_command": null,
"cross_ai_execution": false,
"cross_ai_command": null,
"cross_ai_timeout": 300
"cross_ai_timeout": 300,
"security_enforcement": true,
"security_asvs_level": 1,
"security_block_on": "high"
},
"hooks": {
"context_warnings": true,
@@ -80,9 +87,6 @@ GSD stores project settings in `.planning/config.json`. Created during `/gsd-new
"always_confirm_external_services": true
},
"project_code": null,
"security_enforcement": true,
"security_asvs_level": 1,
"security_block_on": "high",
"agent_skills": {},
"response_language": null,
"features": {
@@ -95,7 +99,7 @@ GSD stores project settings in `.planning/config.json`. Created during `/gsd-new
"intel": {
"enabled": false
},
"claude_md_path": null
"claude_md_path": "./CLAUDE.md"
}
```
@@ -111,7 +115,14 @@ GSD stores project settings in `.planning/config.json`. Created during `/gsd-new
| `project_code` | string | any short string | (none) | Prefix for phase directory names (e.g., `"ABC"` produces `ABC-01-setup/`). Added in v1.31 |
| `response_language` | string | language code | (none) | Language for agent responses (e.g., `"pt"`, `"ko"`, `"ja"`). Propagates to all spawned agents for cross-phase language consistency. Added in v1.32 |
| `context_profile` | string | `dev`, `research`, `review` | (none) | Execution context preset that applies a pre-configured bundle of mode, model, and workflow settings for the current type of work. Added in v1.34 |
| `claude_md_path` | string | any file path | (none) | Custom output path for the generated CLAUDE.md file. Useful for monorepos or projects that need CLAUDE.md in a non-root location. When set, GSD writes its CLAUDE.md content to this path instead of the project root. Added in v1.36 |
| `claude_md_path` | string | any file path | `./CLAUDE.md` | Custom output path for the generated CLAUDE.md file. Useful for monorepos or projects that need CLAUDE.md in a non-root location. Defaults to `./CLAUDE.md` at the project root. Added in v1.36 |
| `claude_md_assembly.mode` | enum | `embed`, `link` | `embed` | Controls how managed sections are written into CLAUDE.md. `embed` (default) inlines content between GSD markers. `link` writes `@.planning/<source-path>` instead — Claude Code expands the reference at runtime, reducing CLAUDE.md size by ~65% on typical projects. `link` only applies to sections that have a real source file; `workflow` and fallback sections always embed. Per-block overrides: `claude_md_assembly.blocks.<section>` (e.g. `claude_md_assembly.blocks.architecture: link`). Added in v1.38 |
| `context` | string | any text | (none) | Custom context string injected into every agent prompt for the project. Use to provide persistent project-specific guidance (e.g., coding conventions, team practices) that every agent should be aware of |
| `phase_naming` | string | any string | (none) | Custom prefix for phase directory names. When set, overrides the auto-generated phase slug (e.g., `"feature"` produces `feature-01-setup/` instead of the roadmap-derived slug) |
| `brave_search` | boolean | `true`/`false` | auto-detected | Override auto-detection of Brave Search API availability. When unset, GSD checks for `BRAVE_API_KEY` env var or `~/.gsd/brave_api_key` file |
| `firecrawl` | boolean | `true`/`false` | auto-detected | Override auto-detection of Firecrawl API availability. When unset, GSD checks for `FIRECRAWL_API_KEY` env var or `~/.gsd/firecrawl_api_key` file |
| `exa_search` | boolean | `true`/`false` | auto-detected | Override auto-detection of Exa Search API availability. When unset, GSD checks for `EXA_API_KEY` env var or `~/.gsd/exa_api_key` file |
| `search_gitignored` | boolean | `true`/`false` | `false` | Legacy top-level alias for `planning.search_gitignored`. Prefer the namespaced form; this alias is accepted for backward compatibility |
> **Note:** `granularity` was renamed from `depth` in v1.22.3. Existing configs are auto-migrated.
@@ -130,10 +141,12 @@ All workflow toggles follow the **absent = enabled** pattern. If a key is missin
| `workflow.nyquist_validation` | boolean | `true` | Test coverage mapping during plan-phase research |
| `workflow.ui_phase` | boolean | `true` | Generate UI design contracts for frontend phases |
| `workflow.ui_safety_gate` | boolean | `true` | Prompt to run /gsd-ui-phase for frontend phases during plan-phase |
| `workflow.ui_review` | boolean | `true` | Run visual quality audit (`/gsd-ui-review`) after phase execution in autonomous mode. When `false`, the UI audit step is skipped. |
| `workflow.node_repair` | boolean | `true` | Autonomous task repair on verification failure |
| `workflow.node_repair_budget` | number | `2` | Max repair attempts per failed task |
| `workflow.research_before_questions` | boolean | `false` | Run research before discussion questions instead of after |
| `workflow.discuss_mode` | string | `'discuss'` | Controls how `/gsd-discuss-phase` gathers context. `'discuss'` (default) asks questions one-by-one. `'assumptions'` reads the codebase first, generates structured assumptions with confidence levels, and only asks you to correct what's wrong. Added in v1.28 |
| `workflow.max_discuss_passes` | number | `3` | Maximum number of question rounds in discuss-phase before the workflow stops asking. Useful in headless/auto mode to prevent infinite discussion loops. |
| `workflow.skip_discuss` | boolean | `false` | When `true`, `/gsd-autonomous` bypasses the discuss-phase entirely, writing minimal CONTEXT.md from the ROADMAP phase goal. Useful for projects where developer preferences are fully captured in PROJECT.md/REQUIREMENTS.md. Added in v1.28 |
| `workflow.text_mode` | boolean | `false` | Replaces AskUserQuestion TUI menus with plain-text numbered lists. Required for Claude Code remote sessions (`/rc` mode) where TUI menus don't render. Can also be set per-session with `--text` flag on discuss-phase. Added in v1.28 |
| `workflow.use_worktrees` | boolean | `true` | When `false`, disables git worktree isolation for parallel execution. Users who prefer sequential execution or whose environment does not support worktrees can disable this. Added in v1.31 |
@@ -142,11 +155,17 @@ All workflow toggles follow the **absent = enabled** pattern. If a key is missin
| `workflow.plan_bounce` | boolean | `false` | Run external validation script against generated plans. When enabled, the plan-phase orchestrator pipes each PLAN.md through the script specified by `plan_bounce_script` and blocks on non-zero exit. Added in v1.36 |
| `workflow.plan_bounce_script` | string | (none) | Path to the external script invoked for plan bounce validation. Receives the PLAN.md path as its first argument. Required when `plan_bounce` is `true`. Added in v1.36 |
| `workflow.plan_bounce_passes` | number | `2` | Number of sequential bounce passes to run. Each pass feeds the previous pass's output back into the validator. Higher values increase rigor at the cost of latency. Added in v1.36 |
| `workflow.plan_chunked` | boolean | `false` | Enable chunked planning mode. When `true` (or when `--chunked` flag is passed to `/gsd-plan-phase`), the orchestrator splits the single long-lived planner Task into a short outline Task followed by N short per-plan Tasks (~3-5 min each). Each plan is committed individually for crash resilience. If a Task hangs and the terminal is force-killed, rerunning with `--chunked` resumes from the last completed plan. Particularly useful on Windows where long-lived Tasks may hang on stdio. Added in v1.38 |
| `workflow.code_review_command` | string | (none) | Shell command for external code review integration in `/gsd-ship`. Receives changed file paths via stdin. Non-zero exit blocks the ship workflow. Added in v1.36 |
| `workflow.tdd_mode` | boolean | `false` | Enable TDD pipeline as a first-class execution mode. When `true`, the planner aggressively applies `type: tdd` to eligible tasks (business logic, APIs, validations, algorithms) and the executor enforces RED/GREEN/REFACTOR gate sequence. An end-of-phase collaborative review checkpoint verifies gate compliance. Added in v1.37 |
| `workflow.tdd_mode` | boolean | `false` | Enable TDD pipeline as a first-class execution mode. When `true`, the planner aggressively applies `type: tdd` to eligible tasks (business logic, APIs, validations, algorithms) and the executor enforces RED/GREEN/REFACTOR gate sequence. An end-of-phase collaborative review checkpoint verifies gate compliance. Added in v1.36 |
| `workflow.cross_ai_execution` | boolean | `false` | Delegate phase execution to an external AI CLI instead of spawning local executor agents. Useful for leveraging a different model's strengths for specific phases. Added in v1.36 |
| `workflow.cross_ai_command` | string | (none) | Shell command template for cross-AI execution. Receives the phase prompt via stdin. Must produce SUMMARY.md-compatible output. Required when `cross_ai_execution` is `true`. Added in v1.36 |
| `workflow.cross_ai_timeout` | number | `300` | Timeout in seconds for cross-AI execution commands. Prevents runaway external processes. Added in v1.36 |
| `workflow.ai_integration_phase` | boolean | `true` | Enable the `/gsd-ai-integration-phase` command. When `false`, the command exits with a configuration gate message |
| `workflow.auto_prune_state` | boolean | `false` | When `true`, automatically prune stale entries from STATE.md at phase boundaries instead of prompting |
| `workflow.pattern_mapper` | boolean | `true` | Run the `gsd-pattern-mapper` agent between research and planning to map new files to existing codebase analogs |
| `workflow.subagent_timeout` | number | `600` | Timeout in seconds for individual subagent invocations. Increase for long-running research or execution phases |
| `workflow.inline_plan_threshold` | number | `3` | Maximum number of tasks in a phase before the planner generates a separate PLAN.md file instead of inlining tasks in the prompt |
### Recommended Presets
@@ -164,6 +183,7 @@ All workflow toggles follow the **absent = enabled** pattern. If a key is missin
|---------|------|---------|-------------|
| `planning.commit_docs` | boolean | `true` | Whether `.planning/` files are committed to git |
| `planning.search_gitignored` | boolean | `false` | Add `--no-ignore` to broad searches to include `.planning/` |
| `planning.sub_repos` | array of strings | `[]` | Paths of nested sub-repos relative to the project root. When set, GSD-aware tooling scopes phase-lookup, path-resolution, and commit operations per sub-repo instead of treating the outer repo as a monorepo |
### Auto-Detection
@@ -177,6 +197,7 @@ If `.planning/` is in `.gitignore`, `commit_docs` is automatically `false` regar
|---------|------|---------|-------------|
| `hooks.context_warnings` | boolean | `true` | Show context window usage warnings via context monitor hook |
| `hooks.workflow_guard` | boolean | `false` | Warn when file edits happen outside GSD workflow context (advises using `/gsd-quick` or `/gsd-fast`) |
| `statusline.show_last_command` | boolean | `false` | Append `last: /<cmd>` suffix to the statusline showing the most recently invoked slash command. Opt-in; reads the active session transcript to extract the latest `<command-name>` tag (closes #2538) |
The prompt injection guard hook (`gsd-prompt-guard.js`) is always active and cannot be disabled — it's a security feature, not a workflow toggle.
@@ -234,7 +255,7 @@ Any GSD agent type can receive skills. Common types:
### How It Works
At spawn time, workflows call `node gsd-tools.cjs agent-skills <type>` to load configured skills. If skills exist for the agent type, they are injected as an `<agent_skills>` block in the Task() prompt:
At spawn time, workflows call `gsd-sdk query agent-skills <type>` (or legacy `node gsd-tools.cjs agent-skills <type>`) to load configured skills. If skills exist for the agent type, they are injected as an `<agent_skills>` block in the Task() prompt:
```xml
<agent_skills>
@@ -251,7 +272,7 @@ If no skills are configured, the block is omitted (zero overhead).
Set skills via the CLI:
```bash
node gsd-tools.cjs config-set agent_skills.gsd-executor '["skills/my-skill"]'
gsd-sdk query config-set agent_skills.gsd-executor '["skills/my-skill"]'
```
---
@@ -264,16 +285,25 @@ Toggle optional capabilities via the `features.*` config namespace. Feature flag
|---------|------|---------|-------------|
| `features.thinking_partner` | boolean | `false` | Enable thinking partner analysis at workflow decision points |
| `features.global_learnings` | boolean | `false` | Enable cross-project learnings pipeline (auto-copy at phase completion, planner injection) |
| `learnings.max_inject` | number | `10` | Maximum number of cross-project learnings injected into each planner prompt. Lower values reduce prompt size; higher values provide broader historical context |
| `intel.enabled` | boolean | `false` | Enable queryable codebase intelligence system. When `true`, `/gsd-intel` commands build and query a JSON index in `.planning/intel/`. Added in v1.34 |
<a id="graphify-settings"></a>
### Graphify Settings
| Setting | Type | Default | Description |
|---------|------|---------|-------------|
| `graphify.enabled` | boolean | `false` | Enable the project knowledge graph. When `true`, `/gsd-graphify` builds and queries a graph in `.planning/graphs/`. Added in v1.36 |
| `graphify.build_timeout` | number (seconds) | `300` | Maximum seconds allowed for a `/gsd-graphify build` run before it aborts. Added in v1.36 |
### Usage
```bash
# Enable a feature
node gsd-tools.cjs config-set features.global_learnings true
gsd-sdk query config-set features.global_learnings true
# Disable a feature
node gsd-tools.cjs config-set features.thinking_partner false
gsd-sdk query config-set features.thinking_partner false
```
The `features.*` namespace is a dynamic key pattern — new feature flags can be added without modifying `VALID_CONFIG_KEYS`. Any key matching `features.<name>` is accepted by the config system.
@@ -284,6 +314,7 @@ The `features.*` namespace is a dynamic key pattern — new feature flags can be
| Setting | Type | Default | Description |
|---------|------|---------|-------------|
| `parallelization` | boolean | `true` | Shorthand for `parallelization.enabled`. Setting `parallelization false` disables parallel execution without changing other sub-keys |
| `parallelization.enabled` | boolean | `true` | Run independent plans simultaneously |
| `parallelization.plan_level` | boolean | `true` | Parallelize at plan level |
| `parallelization.task_level` | boolean | `false` | Parallelize tasks within a plan |
@@ -300,6 +331,7 @@ The `features.*` namespace is a dynamic key pattern — new feature flags can be
| Setting | Type | Default | Description |
|---------|------|---------|-------------|
| `git.branching_strategy` | enum | `none` | `none`, `phase`, or `milestone` |
| `git.base_branch` | string | `main` | The integration branch that phase/milestone branches are created from and merged back into. Override when your repo uses `master` or a release branch |
| `git.phase_branch_template` | string | `gsd/phase-{phase}-{slug}` | Branch name template for phase strategy |
| `git.milestone_branch_template` | string | `gsd/{milestone}-{slug}` | Branch name template for milestone strategy |
| `git.quick_branch_template` | string or null | `null` | Optional branch name template for `/gsd-quick` tasks |
@@ -368,13 +400,15 @@ Control confirmation prompts during workflows.
## Security Settings
Settings for the security enforcement feature (v1.31). All follow the **absent = enabled** pattern.
Settings for the security enforcement feature (v1.31). All follow the **absent = enabled** pattern. These keys live under `workflow.*` in `.planning/config.json` — matching the shipped template and the runtime reads in `workflows/plan-phase.md`, `workflows/execute-phase.md`, `workflows/secure-phase.md`, and `workflows/verify-work.md`.
These keys live under `workflow.*` — that is where the workflows and installer write and read them. Setting them at the top level of `config.json` is silently ignored.
| Setting | Type | Default | Description |
|---------|------|---------|-------------|
| `security_enforcement` | boolean | `true` | Enable threat-model-anchored security verification via `/gsd-secure-phase`. When `false`, security checks are skipped entirely |
| `security_asvs_level` | number (1-3) | `1` | OWASP ASVS verification level. Level 1 = opportunistic, Level 2 = standard, Level 3 = comprehensive |
| `security_block_on` | string | `"high"` | Minimum severity that blocks phase advancement. Options: `"high"`, `"medium"`, `"low"` |
| `workflow.security_enforcement` | boolean | `true` | Enable threat-model-anchored security verification via `/gsd-secure-phase`. When `false`, security checks are skipped entirely |
| `workflow.security_asvs_level` | number (1-3) | `1` | OWASP ASVS verification level. Level 1 = opportunistic, Level 2 = standard, Level 3 = comprehensive |
| `workflow.security_block_on` | string | `"high"` | Minimum severity that blocks phase advancement. Options: `"high"`, `"medium"`, `"low"` |
---
@@ -454,6 +488,14 @@ Invalid flag tokens are sanitized and logged as warnings. Only recognized GSD fl
| gsd-plan-checker | Sonnet | Sonnet | Haiku | Inherit |
| gsd-integration-checker | Sonnet | Sonnet | Haiku | Inherit |
| gsd-nyquist-auditor | Sonnet | Sonnet | Haiku | Inherit |
| gsd-pattern-mapper | Sonnet | Sonnet | Haiku | Inherit |
| gsd-ui-researcher | Opus | Sonnet | Haiku | Inherit |
| gsd-ui-checker | Sonnet | Sonnet | Haiku | Inherit |
| gsd-ui-auditor | Sonnet | Sonnet | Haiku | Inherit |
| gsd-doc-writer | Opus | Sonnet | Haiku | Inherit |
| gsd-doc-verifier | Sonnet | Sonnet | Haiku | Inherit |
> **Fallback semantics for unlisted agents.** The profiles table above covers 18 of 31 shipped agents. Agents without an explicit profile row (`gsd-advisor-researcher`, `gsd-assumptions-analyzer`, `gsd-security-auditor`, `gsd-user-profiler`, and the nine advanced agents — `gsd-ai-researcher`, `gsd-domain-researcher`, `gsd-eval-planner`, `gsd-eval-auditor`, `gsd-framework-selector`, `gsd-code-reviewer`, `gsd-code-fixer`, `gsd-debug-session-manager`, `gsd-intel-updater`) inherit the runtime default model for the selected profile. To pin a specific model for any of these agents, use `model_overrides` (next section) — `model_overrides` accepts any shipped agent name regardless of whether it has a profile row here. The authoritative profile table lives in `get-shit-done/bin/lib/model-profiles.cjs`; the authoritative 31-agent roster lives in [`docs/INVENTORY.md`](INVENTORY.md).
### Per-Agent Overrides

View File

@@ -86,6 +86,27 @@
- [Worktree Toggle](#66-worktree-toggle)
- [Project Code Prefixing](#67-project-code-prefixing)
- [Claude Code Skills Migration](#68-claude-code-skills-migration)
- [v1.32 Features](#v132-features)
- [STATE.md Consistency Gates](#69-statemd-consistency-gates)
- [Autonomous `--to N` Flag](#70-autonomous---to-n-flag)
- [Research Gate](#71-research-gate)
- [Verifier Milestone Scope Filtering](#72-verifier-milestone-scope-filtering)
- [Read-Before-Edit Guard Hook](#73-read-before-edit-guard-hook)
- [Context Reduction](#74-context-reduction)
- [Discuss-Phase `--power` Flag](#75-discuss-phase---power-flag)
- [Debug `--diagnose` Flag](#76-debug---diagnose-flag)
- [Phase Dependency Analysis](#77-phase-dependency-analysis)
- [Anti-Pattern Severity Levels](#78-anti-pattern-severity-levels)
- [Methodology Artifact Type](#79-methodology-artifact-type)
- [Planner Reachability Check](#80-planner-reachability-check)
- [Playwright-MCP UI Verification](#81-playwright-mcp-ui-verification)
- [Pause-Work Expansion](#82-pause-work-expansion)
- [Response Language Config](#83-response-language-config)
- [Manual Update Procedure](#84-manual-update-procedure)
- [New Runtime Support (Trae, Cline, Augment Code)](#85-new-runtime-support-trae-cline-augment-code)
- [Autonomous `--interactive` Flag](#86-autonomous---interactive-flag)
- [Commit-Docs Guard Hook](#87-commit-docs-guard-hook)
- [Community Hooks Opt-In](#88-community-hooks-opt-in)
- [v1.34.0 Features](#v1340-features)
- [Global Learnings Store](#89-global-learnings-store)
- [Queryable Codebase Intelligence](#90-queryable-codebase-intelligence)
@@ -116,11 +137,13 @@
- [SDK Workstream Support](#113-sdk-workstream-support)
- [Context-Window-Aware Prompt Thinning](#114-context-window-aware-prompt-thinning)
- [Configurable CLAUDE.md Path](#115-configurable-claudemd-path)
- [TDD Pipeline Mode](#116-tdd-pipeline-mode)
- [v1.37.0 Features](#v1370-features)
- [Spike Command](#117-spike-command)
- [Sketch Command](#118-sketch-command)
- [Agent Size-Budget Enforcement](#119-agent-size-budget-enforcement)
- [Shared Boilerplate Extraction](#120-shared-boilerplate-extraction)
- [Knowledge Graph Integration](#121-knowledge-graph-integration)
- [v1.32 Features](#v132-features)
- [STATE.md Consistency Gates](#69-statemd-consistency-gates)
- [Autonomous `--to N` Flag](#70-autonomous---to-n-flag)
@@ -2371,6 +2394,20 @@ Test suite that scans all agent, workflow, and command files for embedded inject
**Produces:** `{phase}-LEARNINGS.md` with YAML frontmatter (phase, project, counts per category, missing_artifacts)
**Optional integration — `capture_thought`:** `capture_thought` is a **convention, not a bundled tool**. GSD does not ship one and does not require one. The workflow checks whether any MCP server in the current session exposes a tool named `capture_thought` and, if so, calls it once per extracted learning with the signature below. If no such tool is present, the step is skipped silently and `LEARNINGS.md` remains the primary output.
Expected tool signature:
```javascript
capture_thought({
category: "decision" | "lesson" | "pattern" | "surprise",
phase: <phase_number>,
content: <learning_text>,
source: <artifact_name>
})
```
Users who run a memory / knowledge-base MCP server (for example, ExoCortex-style servers, `claude-mem`, or `mem0`-style servers) can implement this tool name to have learnings routed into their knowledge base automatically with `project`, `phase`, and `source` metadata. Everyone else can use `/gsd-extract-learnings` without any extra setup — the `LEARNINGS.md` artifact is the feature.
---
### 113. SDK Workstream Support
@@ -2507,3 +2544,19 @@ Test suite that scans all agent, workflow, and command files for embedded inject
- REQ-BOILER-03: Agents that previously inlined these blocks MUST now reference them via `@` required_reading
**Reference files:** `references/mandatory-initial-read.md`, `references/project-skills-discovery.md`
---
### 121. Knowledge Graph Integration
**Purpose:** Build, query, and inspect a lightweight knowledge graph of the project in `.planning/graphs/`. Opt-in per project. Exposed as the `/gsd-graphify` user-facing command and the `gsd-tools.cjs graphify …` programmatic verb family. Complements `/gsd-intel` (snapshot-oriented) with a graph-oriented view of nodes and edges across commands, agents, workflows, and phases.
**Requirements:**
- REQ-GRAPH-01: Opt-in via `graphify.enabled: true` in `.planning/config.json`. When disabled, `/gsd-graphify` prints an activation hint and stops without writing.
- REQ-GRAPH-02: Slash-command `/gsd-graphify` exposes subcommands `build`, `query <term>`, `status`, `diff`. The programmatic CLI `node gsd-tools.cjs graphify …` additionally exposes `snapshot`, which is also invoked automatically as the final step of `graphify build`.
- REQ-GRAPH-03: Build runs within the configurable `graphify.build_timeout` (seconds); exceeding the timeout aborts cleanly without leaving a partial graph.
- REQ-GRAPH-04: `graphify.cjs` falls back to `graph.links` when `graph.edges` is absent so older graph artifacts keep rendering.
- REQ-GRAPH-05: CJS-only surface; `gsd-sdk query` does not yet register graphify handlers.
**Configuration:** `graphify.enabled`, `graphify.build_timeout`
**Reference files:** `commands/gsd/graphify.md`, `bin/lib/graphify.cjs`

View File

@@ -0,0 +1,301 @@
{
"generated": "2026-04-20",
"families": {
"agents": [
"gsd-advisor-researcher",
"gsd-ai-researcher",
"gsd-assumptions-analyzer",
"gsd-code-fixer",
"gsd-code-reviewer",
"gsd-codebase-mapper",
"gsd-debug-session-manager",
"gsd-debugger",
"gsd-doc-classifier",
"gsd-doc-synthesizer",
"gsd-doc-verifier",
"gsd-doc-writer",
"gsd-domain-researcher",
"gsd-eval-auditor",
"gsd-eval-planner",
"gsd-executor",
"gsd-framework-selector",
"gsd-integration-checker",
"gsd-intel-updater",
"gsd-nyquist-auditor",
"gsd-pattern-mapper",
"gsd-phase-researcher",
"gsd-plan-checker",
"gsd-planner",
"gsd-project-researcher",
"gsd-research-synthesizer",
"gsd-roadmapper",
"gsd-security-auditor",
"gsd-ui-auditor",
"gsd-ui-checker",
"gsd-ui-researcher",
"gsd-user-profiler",
"gsd-verifier"
],
"commands": [
"/gsd-add-backlog",
"/gsd-add-phase",
"/gsd-add-tests",
"/gsd-add-todo",
"/gsd-ai-integration-phase",
"/gsd-analyze-dependencies",
"/gsd-audit-fix",
"/gsd-audit-milestone",
"/gsd-audit-uat",
"/gsd-autonomous",
"/gsd-check-todos",
"/gsd-cleanup",
"/gsd-code-review",
"/gsd-code-review-fix",
"/gsd-complete-milestone",
"/gsd-debug",
"/gsd-discuss-phase",
"/gsd-do",
"/gsd-docs-update",
"/gsd-eval-review",
"/gsd-execute-phase",
"/gsd-explore",
"/gsd-extract_learnings",
"/gsd-fast",
"/gsd-forensics",
"/gsd-from-gsd2",
"/gsd-graphify",
"/gsd-health",
"/gsd-help",
"/gsd-import",
"/gsd-inbox",
"/gsd-ingest-docs",
"/gsd-insert-phase",
"/gsd-intel",
"/gsd-join-discord",
"/gsd-list-phase-assumptions",
"/gsd-list-workspaces",
"/gsd-manager",
"/gsd-map-codebase",
"/gsd-milestone-summary",
"/gsd-new-milestone",
"/gsd-new-project",
"/gsd-new-workspace",
"/gsd-next",
"/gsd-note",
"/gsd-pause-work",
"/gsd-plan-milestone-gaps",
"/gsd-plan-phase",
"/gsd-plan-review-convergence",
"/gsd-plant-seed",
"/gsd-pr-branch",
"/gsd-profile-user",
"/gsd-progress",
"/gsd-quick",
"/gsd-reapply-patches",
"/gsd-remove-phase",
"/gsd-remove-workspace",
"/gsd-research-phase",
"/gsd-resume-work",
"/gsd-review",
"/gsd-review-backlog",
"/gsd-scan",
"/gsd-secure-phase",
"/gsd-session-report",
"/gsd-set-profile",
"/gsd-settings",
"/gsd-ship",
"/gsd-sketch",
"/gsd-sketch-wrap-up",
"/gsd-spec-phase",
"/gsd-spike",
"/gsd-spike-wrap-up",
"/gsd-stats",
"/gsd-thread",
"/gsd-ui-phase",
"/gsd-ui-review",
"/gsd-ultraplan-phase",
"/gsd-sync-skills",
"/gsd-undo",
"/gsd-update",
"/gsd-validate-phase",
"/gsd-verify-work",
"/gsd-workstreams"
],
"workflows": [
"add-phase.md",
"add-tests.md",
"add-todo.md",
"ai-integration-phase.md",
"analyze-dependencies.md",
"audit-fix.md",
"audit-milestone.md",
"audit-uat.md",
"autonomous.md",
"check-todos.md",
"cleanup.md",
"code-review-fix.md",
"code-review.md",
"complete-milestone.md",
"diagnose-issues.md",
"discovery-phase.md",
"discuss-phase-assumptions.md",
"discuss-phase-power.md",
"discuss-phase.md",
"do.md",
"docs-update.md",
"eval-review.md",
"execute-phase.md",
"execute-plan.md",
"explore.md",
"extract_learnings.md",
"fast.md",
"forensics.md",
"graduation.md",
"health.md",
"help.md",
"import.md",
"inbox.md",
"ingest-docs.md",
"insert-phase.md",
"list-phase-assumptions.md",
"list-workspaces.md",
"manager.md",
"map-codebase.md",
"milestone-summary.md",
"new-milestone.md",
"new-project.md",
"new-workspace.md",
"next.md",
"node-repair.md",
"note.md",
"pause-work.md",
"plan-milestone-gaps.md",
"plan-phase.md",
"plan-review-convergence.md",
"plant-seed.md",
"pr-branch.md",
"profile-user.md",
"progress.md",
"quick.md",
"remove-phase.md",
"remove-workspace.md",
"research-phase.md",
"resume-project.md",
"review.md",
"scan.md",
"secure-phase.md",
"session-report.md",
"settings.md",
"ship.md",
"sketch-wrap-up.md",
"sketch.md",
"spec-phase.md",
"spike-wrap-up.md",
"spike.md",
"stats.md",
"sync-skills.md",
"transition.md",
"ui-phase.md",
"ui-review.md",
"ultraplan-phase.md",
"undo.md",
"update.md",
"validate-phase.md",
"verify-phase.md",
"verify-work.md"
],
"references": [
"agent-contracts.md",
"ai-evals.md",
"ai-frameworks.md",
"artifact-types.md",
"autonomous-smart-discuss.md",
"checkpoints.md",
"common-bug-patterns.md",
"context-budget.md",
"continuation-format.md",
"debugger-philosophy.md",
"decimal-phase-calculation.md",
"doc-conflict-engine.md",
"domain-probes.md",
"executor-examples.md",
"gate-prompts.md",
"gates.md",
"git-integration.md",
"git-planning-commit.md",
"ios-scaffold.md",
"mandatory-initial-read.md",
"model-profile-resolution.md",
"model-profiles.md",
"phase-argument-parsing.md",
"planner-antipatterns.md",
"planner-chunked.md",
"planner-gap-closure.md",
"planner-reviews.md",
"planner-revision.md",
"planner-source-audit.md",
"planning-config.md",
"project-skills-discovery.md",
"questioning.md",
"revision-loop.md",
"sketch-interactivity.md",
"sketch-theme-system.md",
"sketch-tooling.md",
"sketch-variant-patterns.md",
"tdd.md",
"thinking-models-debug.md",
"thinking-models-execution.md",
"thinking-models-planning.md",
"thinking-models-research.md",
"thinking-models-verification.md",
"thinking-partner.md",
"ui-brand.md",
"universal-anti-patterns.md",
"user-profiling.md",
"verification-overrides.md",
"verification-patterns.md",
"workstream-flag.md"
],
"cli_modules": [
"artifacts.cjs",
"audit.cjs",
"commands.cjs",
"config-schema.cjs",
"config.cjs",
"core.cjs",
"docs.cjs",
"frontmatter.cjs",
"graphify.cjs",
"gsd2-import.cjs",
"init.cjs",
"intel.cjs",
"learnings.cjs",
"milestone.cjs",
"model-profiles.cjs",
"phase.cjs",
"profile-output.cjs",
"profile-pipeline.cjs",
"roadmap.cjs",
"schema-detect.cjs",
"security.cjs",
"state.cjs",
"template.cjs",
"uat.cjs",
"verify.cjs",
"workstream.cjs"
],
"hooks": [
"gsd-check-update-worker.js",
"gsd-check-update.js",
"gsd-context-monitor.js",
"gsd-phase-boundary.sh",
"gsd-prompt-guard.js",
"gsd-read-guard.js",
"gsd-read-injection-scanner.js",
"gsd-session-state.sh",
"gsd-statusline.js",
"gsd-validate-commit.sh",
"gsd-workflow-guard.js"
]
}
}

418
docs/INVENTORY.md Normal file
View File

@@ -0,0 +1,418 @@
# GSD Shipped Surface Inventory
> Authoritative roster of every shipped GSD surface: commands, agents, workflows, references, CLI modules, and hooks. Where the broad docs (AGENTS.md, COMMANDS.md, ARCHITECTURE.md, CLI-TOOLS.md) diverge from the filesystem, treat this file and the repository tree itself as the source of truth.
## How To Use This File
- Counts here are derived from the filesystem at the v1.36.0 pin and may drift between releases. For live counts, run `ls commands/gsd/*.md | wc -l`, `ls agents/gsd-*.md | wc -l`, etc. against the checkout.
- This file enumerates every shipped surface across all six families (agents, commands, workflows, references, CLI modules, hooks). Broad docs may render narrative or curated subsets; when they disagree with the filesystem, this file and the directory listings are authoritative.
- New surfaces added after v1.36.0 should land here first, then propagate to the broad docs. The drift-control tests in `tests/inventory-counts.test.cjs`, `tests/commands-doc-parity.test.cjs`, `tests/agents-doc-parity.test.cjs`, `tests/cli-modules-doc-parity.test.cjs`, `tests/hooks-doc-parity.test.cjs`, `tests/architecture-counts.test.cjs`, and `tests/command-count-sync.test.cjs` anchor the counts and roster contents against the filesystem.
---
## Agents (33 shipped)
Full roster at `agents/gsd-*.md`. The "Primary doc" column flags whether [`docs/AGENTS.md`](AGENTS.md) carries a full role card (*primary*), a short stub in the "Advanced and Specialized Agents" section (*advanced stub*), or no coverage (*inventory only*).
| Agent | Role (one line) | Spawned by | Primary doc |
|-------|-----------------|------------|-------------|
| gsd-project-researcher | Researches domain ecosystem before roadmap creation (stack, features, architecture, pitfalls). | `/gsd-new-project`, `/gsd-new-milestone` | primary |
| gsd-phase-researcher | Researches implementation approach for a specific phase before planning. | `/gsd-plan-phase` | primary |
| gsd-ui-researcher | Produces UI design contracts for frontend phases. | `/gsd-ui-phase` | primary |
| gsd-assumptions-analyzer | Produces evidence-backed assumptions for discuss-phase (assumptions mode). | `discuss-phase-assumptions` workflow | primary |
| gsd-advisor-researcher | Researches a single gray-area decision during discuss-phase advisor mode. | `discuss-phase` workflow (advisor mode) | primary |
| gsd-research-synthesizer | Combines parallel researcher outputs into a unified SUMMARY.md. | `/gsd-new-project` | primary |
| gsd-planner | Creates executable phase plans with task breakdown and goal-backward verification. | `/gsd-plan-phase`, `/gsd-quick` | primary |
| gsd-roadmapper | Creates project roadmaps with phase breakdown and requirement mapping. | `/gsd-new-project` | primary |
| gsd-executor | Executes GSD plans with atomic commits and deviation handling. | `/gsd-execute-phase`, `/gsd-quick` | primary |
| gsd-plan-checker | Verifies plans will achieve phase goals (8 verification dimensions). | `/gsd-plan-phase` (verification loop) | primary |
| gsd-integration-checker | Verifies cross-phase integration and end-to-end flows. | `/gsd-audit-milestone` | primary |
| gsd-ui-checker | Validates UI-SPEC.md design contracts against quality dimensions. | `/gsd-ui-phase` (validation loop) | primary |
| gsd-verifier | Verifies phase goal achievement through goal-backward analysis. | `/gsd-execute-phase` | primary |
| gsd-nyquist-auditor | Fills Nyquist validation gaps by generating tests. | `/gsd-validate-phase` | primary |
| gsd-ui-auditor | Retroactive 6-pillar visual audit of implemented frontend code. | `/gsd-ui-review` | primary |
| gsd-codebase-mapper | Explores codebase and writes structured analysis documents. | `/gsd-map-codebase` | primary |
| gsd-debugger | Investigates bugs using scientific method with persistent state. | `/gsd-debug`, `/gsd-verify-work` | primary |
| gsd-user-profiler | Scores developer behavior across 8 dimensions. | `/gsd-profile-user` | primary |
| gsd-doc-writer | Writes and updates project documentation. | `/gsd-docs-update` | primary |
| gsd-doc-verifier | Verifies factual claims in generated documentation. | `/gsd-docs-update` | primary |
| gsd-security-auditor | Verifies threat mitigations from PLAN.md threat model. | `/gsd-secure-phase` | primary |
| gsd-pattern-mapper | Maps new files to closest existing analogs; writes PATTERNS.md for the planner. | `/gsd-plan-phase` (between research and planning) | advanced stub |
| gsd-debug-session-manager | Runs the full `/gsd-debug` checkpoint-and-continuation loop in isolated context so main stays lean. | `/gsd-debug` | advanced stub |
| gsd-code-reviewer | Reviews source files for bugs, security issues, and code-quality problems; produces REVIEW.md. | `/gsd-code-review` | advanced stub |
| gsd-code-fixer | Applies fixes to REVIEW.md findings with atomic per-fix commits; produces REVIEW-FIX.md. | `/gsd-code-review-fix` | advanced stub |
| gsd-ai-researcher | Researches a chosen AI framework's official docs into implementation-ready guidance (AI-SPEC.md §3§4b). | `/gsd-ai-integration-phase` | advanced stub |
| gsd-domain-researcher | Surfaces domain-expert evaluation criteria and failure modes for an AI system (AI-SPEC.md §1b). | `/gsd-ai-integration-phase` | advanced stub |
| gsd-eval-planner | Designs structured evaluation strategy for an AI phase (AI-SPEC.md §5§7). | `/gsd-ai-integration-phase` | advanced stub |
| gsd-eval-auditor | Retroactive audit of an AI phase's evaluation coverage; produces EVAL-REVIEW.md (COVERED/PARTIAL/MISSING). | `/gsd-eval-review` | advanced stub |
| gsd-framework-selector | ≤6-question interactive decision matrix that scores and recommends an AI/LLM framework. | `/gsd-ai-integration-phase`, `/gsd-select-framework` | advanced stub |
| gsd-intel-updater | Writes structured intel files (`.planning/intel/*.json`) used as a queryable codebase knowledge base. | `/gsd-intel` | advanced stub |
| gsd-doc-classifier | Classifies a single planning document as ADR, PRD, SPEC, DOC, or UNKNOWN; spawned in parallel to process the doc corpus. | `/gsd-ingest-docs` | advanced stub |
| gsd-doc-synthesizer | Synthesizes classified planning docs into a single consolidated context with precedence rules, cycle detection, and three-bucket conflicts report. | `/gsd-ingest-docs` | advanced stub |
**Coverage note.** `docs/AGENTS.md` gives full role cards for 21 primary agents plus concise stubs for the 12 advanced agents. The Agent Tool Permissions Summary in that file covers only the primary 21 agents; the advanced agents' tool lists are captured in their per-agent frontmatter in `agents/gsd-*.md`.
---
## Commands (83 shipped)
Full roster at `commands/gsd/*.md`. The groupings below mirror `docs/COMMANDS.md` section order; each row carries the command name, a one-line role derived from the command's frontmatter `description:`, and a link to the source file. `tests/command-count-sync.test.cjs` locks the count against the filesystem.
### Core Workflow
| Command | Role | Source |
|---------|------|--------|
| `/gsd-new-project` | Initialize a new project with deep context gathering and PROJECT.md. | [commands/gsd/new-project.md](../commands/gsd/new-project.md) |
| `/gsd-new-workspace` | Create an isolated workspace with repo copies and independent `.planning/`. | [commands/gsd/new-workspace.md](../commands/gsd/new-workspace.md) |
| `/gsd-list-workspaces` | List active GSD workspaces and their status. | [commands/gsd/list-workspaces.md](../commands/gsd/list-workspaces.md) |
| `/gsd-remove-workspace` | Remove a GSD workspace and clean up worktrees. | [commands/gsd/remove-workspace.md](../commands/gsd/remove-workspace.md) |
| `/gsd-discuss-phase` | Gather phase context through adaptive questioning before planning. | [commands/gsd/discuss-phase.md](../commands/gsd/discuss-phase.md) |
| `/gsd-spec-phase` | Socratic spec refinement producing a SPEC.md with falsifiable requirements. | [commands/gsd/spec-phase.md](../commands/gsd/spec-phase.md) |
| `/gsd-ui-phase` | Generate UI design contract (UI-SPEC.md) for frontend phases. | [commands/gsd/ui-phase.md](../commands/gsd/ui-phase.md) |
| `/gsd-ai-integration-phase` | Generate AI design contract (AI-SPEC.md) via framework selection, research, and eval planning. | [commands/gsd/ai-integration-phase.md](../commands/gsd/ai-integration-phase.md) |
| `/gsd-plan-phase` | Create detailed phase plan (PLAN.md) with verification loop. | [commands/gsd/plan-phase.md](../commands/gsd/plan-phase.md) |
| `/gsd-plan-review-convergence` | Cross-AI plan convergence loop — replan with review feedback until no HIGH concerns remain (max 3 cycles). | [commands/gsd/plan-review-convergence.md](../commands/gsd/plan-review-convergence.md) |
| `/gsd-ultraplan-phase` | [BETA] Offload plan phase to Claude Code's ultraplan cloud — drafts remotely, review in browser, import back via `/gsd-import`. Claude Code only. | [commands/gsd/ultraplan-phase.md](../commands/gsd/ultraplan-phase.md) |
| `/gsd-spike` | Rapidly spike an idea with throwaway experiments to validate feasibility before planning. | [commands/gsd/spike.md](../commands/gsd/spike.md) |
| `/gsd-sketch` | Rapidly sketch UI/design ideas using throwaway HTML mockups with multi-variant exploration. | [commands/gsd/sketch.md](../commands/gsd/sketch.md) |
| `/gsd-research-phase` | Research how to implement a phase (standalone). | [commands/gsd/research-phase.md](../commands/gsd/research-phase.md) |
| `/gsd-execute-phase` | Execute all plans in a phase with wave-based parallelization. | [commands/gsd/execute-phase.md](../commands/gsd/execute-phase.md) |
| `/gsd-verify-work` | Validate built features through conversational UAT with auto-diagnosis. | [commands/gsd/verify-work.md](../commands/gsd/verify-work.md) |
| `/gsd-ship` | Create PR, run review, and prepare for merge after verification. | [commands/gsd/ship.md](../commands/gsd/ship.md) |
| `/gsd-next` | Automatically advance to the next logical step in the GSD workflow. | [commands/gsd/next.md](../commands/gsd/next.md) |
| `/gsd-fast` | Execute a trivial task inline — no subagents, no planning overhead. | [commands/gsd/fast.md](../commands/gsd/fast.md) |
| `/gsd-quick` | Execute a quick task with GSD guarantees (atomic commits, state tracking) but skip optional agents. | [commands/gsd/quick.md](../commands/gsd/quick.md) |
| `/gsd-ui-review` | Retroactive 6-pillar visual audit of implemented frontend code. | [commands/gsd/ui-review.md](../commands/gsd/ui-review.md) |
| `/gsd-code-review` | Review source files changed during a phase for bugs, security, and code-quality problems. | [commands/gsd/code-review.md](../commands/gsd/code-review.md) |
| `/gsd-code-review-fix` | Auto-fix issues found by `/gsd-code-review`, committing each fix atomically. | [commands/gsd/code-review-fix.md](../commands/gsd/code-review-fix.md) |
| `/gsd-eval-review` | Retroactively audit an executed AI phase's evaluation coverage; produces EVAL-REVIEW.md. | [commands/gsd/eval-review.md](../commands/gsd/eval-review.md) |
### Phase & Milestone Management
| Command | Role | Source |
|---------|------|--------|
| `/gsd-add-phase` | Add phase to end of current milestone in roadmap. | [commands/gsd/add-phase.md](../commands/gsd/add-phase.md) |
| `/gsd-insert-phase` | Insert urgent work as decimal phase (e.g., 72.1) between existing phases. | [commands/gsd/insert-phase.md](../commands/gsd/insert-phase.md) |
| `/gsd-remove-phase` | Remove a future phase from roadmap and renumber subsequent phases. | [commands/gsd/remove-phase.md](../commands/gsd/remove-phase.md) |
| `/gsd-add-tests` | Generate tests for a completed phase based on UAT criteria and implementation. | [commands/gsd/add-tests.md](../commands/gsd/add-tests.md) |
| `/gsd-list-phase-assumptions` | Surface Claude's assumptions about a phase approach before planning. | [commands/gsd/list-phase-assumptions.md](../commands/gsd/list-phase-assumptions.md) |
| `/gsd-analyze-dependencies` | Analyze phase dependencies and suggest `Depends on` entries for ROADMAP.md. | [commands/gsd/analyze-dependencies.md](../commands/gsd/analyze-dependencies.md) |
| `/gsd-validate-phase` | Retroactively audit and fill Nyquist validation gaps for a completed phase. | [commands/gsd/validate-phase.md](../commands/gsd/validate-phase.md) |
| `/gsd-secure-phase` | Retroactively verify threat mitigations for a completed phase. | [commands/gsd/secure-phase.md](../commands/gsd/secure-phase.md) |
| `/gsd-audit-milestone` | Audit milestone completion against original intent before archiving. | [commands/gsd/audit-milestone.md](../commands/gsd/audit-milestone.md) |
| `/gsd-audit-uat` | Cross-phase audit of all outstanding UAT and verification items. | [commands/gsd/audit-uat.md](../commands/gsd/audit-uat.md) |
| `/gsd-audit-fix` | Autonomous audit-to-fix pipeline — find issues, classify, fix, test, commit. | [commands/gsd/audit-fix.md](../commands/gsd/audit-fix.md) |
| `/gsd-plan-milestone-gaps` | Create phases to close all gaps identified by milestone audit. | [commands/gsd/plan-milestone-gaps.md](../commands/gsd/plan-milestone-gaps.md) |
| `/gsd-complete-milestone` | Archive completed milestone and prepare for next version. | [commands/gsd/complete-milestone.md](../commands/gsd/complete-milestone.md) |
| `/gsd-new-milestone` | Start a new milestone cycle — update PROJECT.md and route to requirements. | [commands/gsd/new-milestone.md](../commands/gsd/new-milestone.md) |
| `/gsd-milestone-summary` | Generate a comprehensive project summary from milestone artifacts. | [commands/gsd/milestone-summary.md](../commands/gsd/milestone-summary.md) |
| `/gsd-cleanup` | Archive accumulated phase directories from completed milestones. | [commands/gsd/cleanup.md](../commands/gsd/cleanup.md) |
| `/gsd-manager` | Interactive command center for managing multiple phases from one terminal. | [commands/gsd/manager.md](../commands/gsd/manager.md) |
| `/gsd-workstreams` | Manage parallel workstreams — list, create, switch, status, progress, complete, resume. | [commands/gsd/workstreams.md](../commands/gsd/workstreams.md) |
| `/gsd-autonomous` | Run all remaining phases autonomously — discuss → plan → execute per phase. | [commands/gsd/autonomous.md](../commands/gsd/autonomous.md) |
| `/gsd-undo` | Safe git revert — roll back phase or plan commits using the phase manifest. | [commands/gsd/undo.md](../commands/gsd/undo.md) |
### Session & Navigation
| Command | Role | Source |
|---------|------|--------|
| `/gsd-progress` | Check project progress, show context, and route to next action. | [commands/gsd/progress.md](../commands/gsd/progress.md) |
| `/gsd-stats` | Display project statistics — phases, plans, requirements, git metrics, timeline. | [commands/gsd/stats.md](../commands/gsd/stats.md) |
| `/gsd-session-report` | Generate a session report with token usage estimates, work summary, outcomes. | [commands/gsd/session-report.md](../commands/gsd/session-report.md) |
| `/gsd-pause-work` | Create context handoff when pausing work mid-phase. | [commands/gsd/pause-work.md](../commands/gsd/pause-work.md) |
| `/gsd-resume-work` | Resume work from previous session with full context restoration. | [commands/gsd/resume-work.md](../commands/gsd/resume-work.md) |
| `/gsd-explore` | Socratic ideation and idea routing — think through ideas before committing. | [commands/gsd/explore.md](../commands/gsd/explore.md) |
| `/gsd-do` | Route freeform text to the right GSD command automatically. | [commands/gsd/do.md](../commands/gsd/do.md) |
| `/gsd-note` | Zero-friction idea capture — append, list, or promote notes to todos. | [commands/gsd/note.md](../commands/gsd/note.md) |
| `/gsd-add-todo` | Capture idea or task as todo from current conversation context. | [commands/gsd/add-todo.md](../commands/gsd/add-todo.md) |
| `/gsd-check-todos` | List pending todos and select one to work on. | [commands/gsd/check-todos.md](../commands/gsd/check-todos.md) |
| `/gsd-add-backlog` | Add an idea to the backlog parking lot (999.x numbering). | [commands/gsd/add-backlog.md](../commands/gsd/add-backlog.md) |
| `/gsd-review-backlog` | Review and promote backlog items to active milestone. | [commands/gsd/review-backlog.md](../commands/gsd/review-backlog.md) |
| `/gsd-plant-seed` | Capture a forward-looking idea with trigger conditions. | [commands/gsd/plant-seed.md](../commands/gsd/plant-seed.md) |
| `/gsd-thread` | Manage persistent context threads for cross-session work. | [commands/gsd/thread.md](../commands/gsd/thread.md) |
### Codebase Intelligence
| Command | Role | Source |
|---------|------|--------|
| `/gsd-map-codebase` | Analyze codebase with parallel mapper agents; produces `.planning/codebase/` documents. | [commands/gsd/map-codebase.md](../commands/gsd/map-codebase.md) |
| `/gsd-scan` | Rapid codebase assessment — lightweight alternative to `/gsd-map-codebase`. | [commands/gsd/scan.md](../commands/gsd/scan.md) |
| `/gsd-intel` | Query, inspect, or refresh codebase intelligence files in `.planning/intel/`. | [commands/gsd/intel.md](../commands/gsd/intel.md) |
| `/gsd-graphify` | Build, query, and inspect the project knowledge graph in `.planning/graphs/`. | [commands/gsd/graphify.md](../commands/gsd/graphify.md) |
| `/gsd-extract-learnings` | Extract decisions, lessons, patterns, and surprises from completed phase artifacts. | [commands/gsd/extract_learnings.md](../commands/gsd/extract_learnings.md) |
### Review, Debug & Recovery
| Command | Role | Source |
|---------|------|--------|
| `/gsd-review` | Request cross-AI peer review of phase plans from external AI CLIs. | [commands/gsd/review.md](../commands/gsd/review.md) |
| `/gsd-debug` | Systematic debugging with persistent state across context resets. | [commands/gsd/debug.md](../commands/gsd/debug.md) |
| `/gsd-forensics` | Post-mortem investigation for failed GSD workflows — analyzes git, artifacts, state. | [commands/gsd/forensics.md](../commands/gsd/forensics.md) |
| `/gsd-health` | Diagnose planning directory health and optionally repair issues. | [commands/gsd/health.md](../commands/gsd/health.md) |
| `/gsd-import` | Ingest external plans with conflict detection against project decisions. | [commands/gsd/import.md](../commands/gsd/import.md) |
| `/gsd-from-gsd2` | Import a GSD-2 (`.gsd/`) project back to GSD v1 (`.planning/`) format. | [commands/gsd/from-gsd2.md](../commands/gsd/from-gsd2.md) |
| `/gsd-inbox` | Triage and review all open GitHub issues and PRs against project templates. | [commands/gsd/inbox.md](../commands/gsd/inbox.md) |
### Docs, Profile & Utilities
| Command | Role | Source |
|---------|------|--------|
| `/gsd-docs-update` | Generate or update project documentation verified against the codebase. | [commands/gsd/docs-update.md](../commands/gsd/docs-update.md) |
| `/gsd-ingest-docs` | Scan a repo for mixed ADRs/PRDs/SPECs/DOCs and bootstrap or merge the full `.planning/` setup with classification, synthesis, and conflicts report. | [commands/gsd/ingest-docs.md](../commands/gsd/ingest-docs.md) |
| `/gsd-spike-wrap-up` | Package spike findings into a persistent project skill for future build conversations. | [commands/gsd/spike-wrap-up.md](../commands/gsd/spike-wrap-up.md) |
| `/gsd-sketch-wrap-up` | Package sketch design findings into a persistent project skill for future build conversations. | [commands/gsd/sketch-wrap-up.md](../commands/gsd/sketch-wrap-up.md) |
| `/gsd-profile-user` | Generate developer behavioral profile and Claude-discoverable artifacts. | [commands/gsd/profile-user.md](../commands/gsd/profile-user.md) |
| `/gsd-settings` | Configure GSD workflow toggles and model profile. | [commands/gsd/settings.md](../commands/gsd/settings.md) |
| `/gsd-set-profile` | Switch model profile for GSD agents (quality/balanced/budget/inherit). | [commands/gsd/set-profile.md](../commands/gsd/set-profile.md) |
| `/gsd-pr-branch` | Create a clean PR branch by filtering out `.planning/` commits. | [commands/gsd/pr-branch.md](../commands/gsd/pr-branch.md) |
| `/gsd-sync-skills` | Sync managed GSD skill directories across runtime roots for multi-runtime users. | [commands/gsd/sync-skills.md](../commands/gsd/sync-skills.md) |
| `/gsd-update` | Update GSD to latest version with changelog display. | [commands/gsd/update.md](../commands/gsd/update.md) |
| `/gsd-reapply-patches` | Reapply local modifications after a GSD update. | [commands/gsd/reapply-patches.md](../commands/gsd/reapply-patches.md) |
| `/gsd-help` | Show available GSD commands and usage guide. | [commands/gsd/help.md](../commands/gsd/help.md) |
| `/gsd-join-discord` | Join the GSD Discord community. | [commands/gsd/join-discord.md](../commands/gsd/join-discord.md) |
---
## Workflows (81 shipped)
Full roster at `get-shit-done/workflows/*.md`. Workflows are thin orchestrators that commands reference internally; most are not read directly by end users. Rows below map each workflow file to its role (derived from the `<purpose>` block) and, where applicable, to the command that invokes it.
| Workflow | Role | Invoked by |
|----------|------|------------|
| `add-phase.md` | Add a new integer phase to the end of the current milestone in the roadmap. | `/gsd-add-phase` |
| `add-tests.md` | Generate unit and E2E tests for a completed phase based on its artifacts. | `/gsd-add-tests` |
| `add-todo.md` | Capture an idea or task that surfaces during a session as a structured todo. | `/gsd-add-todo`, `/gsd-add-backlog` |
| `ai-integration-phase.md` | Orchestrate framework selection → AI research → domain research → eval planning into AI-SPEC.md. | `/gsd-ai-integration-phase` |
| `analyze-dependencies.md` | Analyze ROADMAP.md phases for file overlap and semantic dependencies; suggest `Depends on` edges. | `/gsd-analyze-dependencies` |
| `audit-fix.md` | Autonomous audit-to-fix pipeline — run audit, parse, classify, fix, test, commit. | `/gsd-audit-fix` |
| `audit-milestone.md` | Verify milestone met its definition of done by aggregating phase verifications. | `/gsd-audit-milestone` |
| `audit-uat.md` | Cross-phase audit of UAT and verification files; produces prioritized outstanding-items list. | `/gsd-audit-uat` |
| `autonomous.md` | Drive milestone phases autonomously — all remaining, a range, or a single phase. | `/gsd-autonomous` |
| `check-todos.md` | List pending todos, allow selection, load context, and route to the appropriate action. | `/gsd-check-todos` |
| `cleanup.md` | Archive accumulated phase directories from completed milestones. | `/gsd-cleanup` |
| `code-review-fix.md` | Auto-fix issues from REVIEW.md via gsd-code-fixer with per-fix atomic commits. | `/gsd-code-review-fix` |
| `code-review.md` | Review phase source changes via gsd-code-reviewer; produces REVIEW.md. | `/gsd-code-review` |
| `complete-milestone.md` | Mark a shipped version as complete — MILESTONES.md entry, PROJECT.md evolution, tag. | `/gsd-complete-milestone` |
| `diagnose-issues.md` | Orchestrate parallel debug agents to investigate UAT gaps and find root causes. | `/gsd-verify-work` (auto-diagnosis) |
| `discovery-phase.md` | Execute discovery at the appropriate depth level. | `/gsd-new-project` (discovery path) |
| `discuss-phase-assumptions.md` | Assumptions-mode discuss — extract implementation decisions via codebase-first analysis. | `/gsd-discuss-phase` (when `discuss_mode=assumptions`) |
| `discuss-phase-power.md` | Power-user discuss — pre-generate all questions into a JSON state file + HTML UI. | `/gsd-discuss-phase --power` |
| `discuss-phase.md` | Extract implementation decisions through iterative gray-area discussion. | `/gsd-discuss-phase` |
| `do.md` | Route freeform text from the user to the best matching GSD command. | `/gsd-do` |
| `docs-update.md` | Generate, update, and verify canonical and hand-written project documentation. | `/gsd-docs-update` |
| `eval-review.md` | Retroactive audit of an implemented AI phase's evaluation coverage. | `/gsd-eval-review` |
| `execute-phase.md` | Execute all plans in a phase using wave-based parallel execution. | `/gsd-execute-phase` |
| `execute-plan.md` | Execute a phase prompt (PLAN.md) and create the outcome summary (SUMMARY.md). | `execute-phase.md` (per-plan subagent) |
| `explore.md` | Socratic ideation — guide the developer through probing questions. | `/gsd-explore` |
| `extract_learnings.md` | Extract decisions, lessons, patterns, and surprises from completed phase artifacts. | `/gsd-extract-learnings` |
| `fast.md` | Execute a trivial task inline without subagent overhead. | `/gsd-fast` |
| `forensics.md` | Forensics investigation of failed workflows — git, artifacts, and state analysis. | `/gsd-forensics` |
| `graduation.md` | Cluster recurring LEARNINGS.md items across phases and surface HITL promotion candidates. | `transition.md` (graduation_scan step) |
| `health.md` | Validate `.planning/` directory integrity and report actionable issues. | `/gsd-health` |
| `help.md` | Display the complete GSD command reference. | `/gsd-help` |
| `import.md` | Ingest external plans with conflict detection against existing project decisions. | `/gsd-import` |
| `inbox.md` | Triage open GitHub issues and PRs against project contribution templates. | `/gsd-inbox` |
| `ingest-docs.md` | Scan a repo for mixed planning docs; classify, synthesize, and bootstrap or merge into `.planning/` with a conflicts report. | `/gsd-ingest-docs` |
| `insert-phase.md` | Insert a decimal phase for urgent work discovered mid-milestone. | `/gsd-insert-phase` |
| `list-phase-assumptions.md` | Surface Claude's assumptions about a phase before planning. | `/gsd-list-phase-assumptions` |
| `list-workspaces.md` | List all GSD workspaces found in `~/gsd-workspaces/` with their status. | `/gsd-list-workspaces` |
| `manager.md` | Interactive milestone command center — dashboard, inline discuss, background plan/execute. | `/gsd-manager` |
| `map-codebase.md` | Orchestrate parallel codebase mapper agents to produce `.planning/codebase/` docs. | `/gsd-map-codebase` |
| `milestone-summary.md` | Milestone summary synthesis — onboarding and review artifact from milestone artifacts. | `/gsd-milestone-summary` |
| `new-milestone.md` | Start a new milestone cycle — load project context, gather goals, update PROJECT.md/STATE.md. | `/gsd-new-milestone` |
| `new-project.md` | Unified new-project flow — questioning, research (optional), requirements, roadmap. | `/gsd-new-project` |
| `new-workspace.md` | Create an isolated workspace with repo worktrees/clones and an independent `.planning/`. | `/gsd-new-workspace` |
| `next.md` | Detect current project state and automatically advance to the next logical step. | `/gsd-next` |
| `node-repair.md` | Autonomous repair operator for failed task verification; invoked by `execute-plan`. | `execute-plan.md` (recovery) |
| `note.md` | Zero-friction idea capture — one Write call, one confirmation line. | `/gsd-note` |
| `pause-work.md` | Create structured `.planning/HANDOFF.json` and `.continue-here.md` handoff files. | `/gsd-pause-work` |
| `plan-milestone-gaps.md` | Create all phases necessary to close gaps identified by `/gsd-audit-milestone`. | `/gsd-plan-milestone-gaps` |
| `plan-phase.md` | Create executable PLAN.md files with integrated research and verification loop. | `/gsd-plan-phase`, `/gsd-quick` |
| `plan-review-convergence.md` | Cross-AI plan convergence loop — replan with review feedback until no HIGH concerns remain. | `/gsd-plan-review-convergence` |
| `plant-seed.md` | Capture a forward-looking idea as a structured seed file with trigger conditions. | `/gsd-plant-seed` |
| `pr-branch.md` | Create a clean branch for pull requests by filtering `.planning/` commits. | `/gsd-pr-branch` |
| `profile-user.md` | Orchestrate the full developer profiling flow — consent, session scan, profile generation. | `/gsd-profile-user` |
| `progress.md` | Progress rendering — project context, position, and next-action routing. | `/gsd-progress` |
| `quick.md` | Quick-task execution with GSD guarantees (atomic commits, state tracking). | `/gsd-quick` |
| `remove-phase.md` | Remove a future phase from the roadmap and renumber subsequent phases. | `/gsd-remove-phase` |
| `remove-workspace.md` | Remove a GSD workspace and clean up worktrees. | `/gsd-remove-workspace` |
| `research-phase.md` | Standalone phase research workflow (usually invoked via `plan-phase`). | `/gsd-research-phase` |
| `resume-project.md` | Resume work — restore full context from STATE.md, HANDOFF.json, and artifacts. | `/gsd-resume-work` |
| `review.md` | Cross-AI plan review via external CLIs; produces REVIEWS.md. | `/gsd-review` |
| `scan.md` | Rapid single-focus codebase scan — lightweight alternative to map-codebase. | `/gsd-scan` |
| `secure-phase.md` | Retroactive threat-mitigation audit for a completed phase. | `/gsd-secure-phase` |
| `session-report.md` | Session report — token usage, work summary, outcomes. | `/gsd-session-report` |
| `settings.md` | Configure GSD workflow toggles and model profile. | `/gsd-settings`, `/gsd-set-profile` |
| `ship.md` | Create PR, run review, and prepare for merge after verification. | `/gsd-ship` |
| `sketch.md` | Explore design directions through throwaway HTML mockups with 2-3 variants per sketch. | `/gsd-sketch` |
| `sketch-wrap-up.md` | Curate sketch findings and package them as a persistent `sketch-findings-[project]` skill. | `/gsd-sketch-wrap-up` |
| `spec-phase.md` | Socratic spec refinement with ambiguity scoring; produces SPEC.md. | `/gsd-spec-phase` |
| `spike.md` | Rapid feasibility validation through focused, throwaway experiments. | `/gsd-spike` |
| `spike-wrap-up.md` | Curate spike findings and package them as a persistent `spike-findings-[project]` skill. | `/gsd-spike-wrap-up` |
| `stats.md` | Project statistics rendering — phases, plans, requirements, git metrics. | `/gsd-stats` |
| `sync-skills.md` | Cross-runtime GSD skill sync — diff and apply `gsd-*` skill directories across runtime roots. | `/gsd-sync-skills` |
| `transition.md` | Phase-boundary transition workflow — workstream checks, state advancement. | `execute-phase.md`, `/gsd-next` |
| `ui-phase.md` | Generate UI-SPEC.md design contract via gsd-ui-researcher. | `/gsd-ui-phase` |
| `ui-review.md` | Retroactive 6-pillar visual audit via gsd-ui-auditor. | `/gsd-ui-review` |
| `ultraplan-phase.md` | [BETA] Offload planning to Claude Code's ultraplan cloud; drafts remotely and imports back via `/gsd-import`. | `/gsd-ultraplan-phase` |
| `undo.md` | Safe git revert — phase or plan commits using the phase manifest. | `/gsd-undo` |
| `update.md` | Update GSD to latest version with changelog display. | `/gsd-update` |
| `validate-phase.md` | Retroactively audit and fill Nyquist validation gaps for a completed phase. | `/gsd-validate-phase` |
| `verify-phase.md` | Verify phase goal achievement through goal-backward analysis. | `execute-phase.md` (post-execution) |
| `verify-work.md` | Conversational UAT with auto-diagnosis — produces UAT.md and fix plans. | `/gsd-verify-work` |
> **Note:** Some workflows have no direct user-facing command (e.g. `execute-plan.md`, `verify-phase.md`, `transition.md`, `node-repair.md`, `diagnose-issues.md`) — they are invoked internally by orchestrator workflows. `discovery-phase.md` is an alternate entry for `/gsd-new-project`.
---
## References (50 shipped)
Full roster at `get-shit-done/references/*.md`. References are shared knowledge documents that workflows and agents `@-reference`. The groupings below match [`docs/ARCHITECTURE.md`](ARCHITECTURE.md#references-get-shit-donereferencesmd) — core, workflow, thinking-model clusters, and the modular planner decomposition.
### Core References
| Reference | Role |
|-----------|------|
| `checkpoints.md` | Checkpoint type definitions and interaction patterns. |
| `gates.md` | 4 canonical gate types (Confirm, Quality, Safety, Transition) wired into plan-checker and verifier. |
| `model-profiles.md` | Per-agent model tier assignments. |
| `model-profile-resolution.md` | Model resolution algorithm documentation. |
| `verification-patterns.md` | How to verify different artifact types. |
| `verification-overrides.md` | Per-artifact verification override rules. |
| `planning-config.md` | Full config schema and behavior. |
| `git-integration.md` | Git commit, branching, and history patterns. |
| `git-planning-commit.md` | Planning directory commit conventions. |
| `questioning.md` | Dream-extraction philosophy for project initialization. |
| `tdd.md` | Test-driven development integration patterns. |
| `ui-brand.md` | Visual output formatting patterns. |
| `common-bug-patterns.md` | Common bug patterns for code review and verification. |
| `debugger-philosophy.md` | Evergreen debugging disciplines loaded by `gsd-debugger`. |
| `mandatory-initial-read.md` | Shared required-reading boilerplate injected into agent prompts. |
| `project-skills-discovery.md` | Shared project-skills-discovery boilerplate injected into agent prompts. |
### Workflow References
| Reference | Role |
|-----------|------|
| `agent-contracts.md` | Formal interface between orchestrators and agents. |
| `context-budget.md` | Context window budget allocation rules. |
| `continuation-format.md` | Session continuation/resume format. |
| `domain-probes.md` | Domain-specific probing questions for discuss-phase. |
| `gate-prompts.md` | Gate/checkpoint prompt templates. |
| `revision-loop.md` | Plan revision iteration patterns. |
| `universal-anti-patterns.md` | Universal anti-patterns to detect and avoid. |
| `artifact-types.md` | Planning artifact type definitions. |
| `phase-argument-parsing.md` | Phase argument parsing conventions. |
| `decimal-phase-calculation.md` | Decimal sub-phase numbering rules. |
| `workstream-flag.md` | Workstream active-pointer conventions (`--ws`). |
| `user-profiling.md` | User behavioral profiling detection heuristics. |
| `thinking-partner.md` | Conditional thinking-partner activation at decision points. |
| `autonomous-smart-discuss.md` | Smart-discuss logic for autonomous mode. |
| `ios-scaffold.md` | iOS application scaffolding patterns. |
| `ai-evals.md` | AI evaluation design reference for `/gsd-ai-integration-phase`. |
| `ai-frameworks.md` | AI framework decision-matrix reference for `gsd-framework-selector`. |
| `executor-examples.md` | Worked examples for the gsd-executor agent. |
| `doc-conflict-engine.md` | Shared conflict-detection contract for ingest/import workflows. |
### Sketch References
References consumed by the `/gsd-sketch` workflow and its wrap-up companion.
| Reference | Role |
|-----------|------|
| `sketch-interactivity.md` | Rules for making HTML sketches feel interactive and alive. |
| `sketch-theme-system.md` | Shared CSS theme variable system for cross-sketch consistency. |
| `sketch-tooling.md` | Floating toolbar utilities included in every sketch. |
| `sketch-variant-patterns.md` | Multi-variant HTML patterns (tabs, side-by-side, overlays). |
### Thinking-Model References
References for integrating thinking-class models (o3, o4-mini, Gemini 2.5 Pro) into GSD workflows.
| Reference | Role |
|-----------|------|
| `thinking-models-debug.md` | Thinking-model patterns for debug workflows. |
| `thinking-models-execution.md` | Thinking-model patterns for execution agents. |
| `thinking-models-planning.md` | Thinking-model patterns for planning agents. |
| `thinking-models-research.md` | Thinking-model patterns for research agents. |
| `thinking-models-verification.md` | Thinking-model patterns for verification agents. |
### Modular Planner Decomposition
The `gsd-planner` agent is decomposed into a core agent plus reference modules to fit runtime character limits.
| Reference | Role |
|-----------|------|
| `planner-antipatterns.md` | Planner anti-patterns and specificity examples. |
| `planner-chunked.md` | Chunked mode return formats (`## OUTLINE COMPLETE`, `## PLAN COMPLETE`) for Windows stdio hang mitigation. |
| `planner-gap-closure.md` | Gap-closure mode behavior (reads VERIFICATION.md, targeted replanning). |
| `planner-reviews.md` | Cross-AI review integration (reads REVIEWS.md from `/gsd-review`). |
| `planner-revision.md` | Plan revision patterns for iterative refinement. |
| `planner-source-audit.md` | Planner source-audit and authority-limit rules. |
> **Subdirectory:** `get-shit-done/references/few-shot-examples/` contains additional few-shot examples (`plan-checker.md`, `verifier.md`) that are referenced from specific agents. These are not counted in the 50 top-level references.
---
## CLI Modules (26 shipped)
Full listing: `get-shit-done/bin/lib/*.cjs`.
| Module | Responsibility |
|--------|----------------|
| `artifacts.cjs` | Canonical artifact registry — known `.planning/` root file names; used by `gsd-health` W019 lint |
| `audit.cjs` | Audit dispatch, audit open sessions, audit storage helpers |
| `commands.cjs` | Misc CLI commands (slug, timestamp, todos, scaffolding, stats) |
| `config-schema.cjs` | Single source of truth for `VALID_CONFIG_KEYS` and dynamic key patterns; imported by both the validator and the config-schema-docs parity test |
| `config.cjs` | `config.json` read/write, section initialization; imports validator from `config-schema.cjs` |
| `core.cjs` | Error handling, output formatting, shared utilities, runtime fallbacks |
| `docs.cjs` | Docs-update workflow init, Markdown scanning, monorepo detection |
| `frontmatter.cjs` | YAML frontmatter CRUD operations |
| `graphify.cjs` | Knowledge-graph build/query/status/diff for `/gsd-graphify` |
| `gsd2-import.cjs` | External-plan ingest for `/gsd-from-gsd2` |
| `init.cjs` | Compound context loading for each workflow type |
| `intel.cjs` | Codebase intel store backing `/gsd-intel` and `gsd-intel-updater` |
| `learnings.cjs` | Cross-phase learnings extraction for `/gsd-extract-learnings` |
| `milestone.cjs` | Milestone archival, requirements marking |
| `model-profiles.cjs` | Model profile resolution table (authoritative profile data) |
| `phase.cjs` | Phase directory operations, decimal numbering, plan indexing |
| `profile-output.cjs` | Profile rendering, USER-PROFILE.md and dev-preferences.md generation |
| `profile-pipeline.cjs` | User behavioral profiling data pipeline, session file scanning |
| `roadmap.cjs` | ROADMAP.md parsing, phase extraction, plan progress |
| `schema-detect.cjs` | Schema-drift detection for ORM patterns (Prisma, Drizzle, etc.) |
| `security.cjs` | Path traversal prevention, prompt injection detection, safe JSON/shell helpers |
| `state.cjs` | STATE.md parsing, updating, progression, metrics |
| `template.cjs` | Template selection and filling with variable substitution |
| `uat.cjs` | UAT file parsing, verification debt tracking, audit-uat support |
| `verify.cjs` | Plan structure, phase completeness, reference, commit validation |
| `workstream.cjs` | Workstream CRUD, migration, session-scoped active pointer |
[`docs/CLI-TOOLS.md`](CLI-TOOLS.md) may describe a subset of these modules; when it disagrees with the filesystem, this table and the directory listing are authoritative.
---
## Hooks (11 shipped)
Full listing: `hooks/`.
| Hook | Event | Purpose |
|------|-------|---------|
| `gsd-statusline.js` | `statusLine` | Displays model, task, directory, context usage |
| `gsd-context-monitor.js` | `PostToolUse` / `AfterTool` | Injects agent-facing context warnings at 35%/25% remaining |
| `gsd-check-update.js` | `SessionStart` | Background check for new GSD versions |
| `gsd-check-update-worker.js` | (worker) | Background worker helper for check-update |
| `gsd-prompt-guard.js` | `PreToolUse` | Scans `.planning/` writes for prompt-injection patterns (advisory) |
| `gsd-workflow-guard.js` | `PreToolUse` | Detects file edits outside GSD workflow context (advisory, opt-in) |
| `gsd-read-guard.js` | `PreToolUse` | Advisory guard preventing Edit/Write on unread files |
| `gsd-read-injection-scanner.js` | `PostToolUse` | Scans tool Read results for prompt-injection patterns (v1.36+, PR #2201) |
| `gsd-session-state.sh` | `PostToolUse` | Session-state tracking for shell-based runtimes |
| `gsd-validate-commit.sh` | `PostToolUse` | Commit validation for conventional-commit enforcement |
| `gsd-phase-boundary.sh` | `PostToolUse` | Phase-boundary detection for workflow transitions |
---
## Maintenance
- When a new command, agent, workflow, reference, CLI module, or hook ships, update the corresponding section here before the release is cut.
- The drift-guard tests under `tests/` (see "How To Use This File" above) assert that every shipped file is enumerated in this inventory. A new file without a matching row here will fail CI.
- When the filesystem diverges from `docs/ARCHITECTURE.md` counts or from curated-subset docs (e.g. `docs/AGENTS.md`'s primary roster), this file is the source of truth.

View File

@@ -9,21 +9,21 @@ Language versions: [English](README.md) · [Português (pt-BR)](pt-BR/README.md)
| Document | Audience | Description |
|----------|----------|-------------|
| [Architecture](ARCHITECTURE.md) | Contributors, advanced users | System architecture, agent model, data flow, and internal design |
| [Feature Reference](FEATURES.md) | All users | Complete feature and function documentation with requirements |
| [Command Reference](COMMANDS.md) | All users | Every command with syntax, flags, options, and examples |
| [Feature Reference](FEATURES.md) | All users | Feature narratives and requirements for released features (see [CHANGELOG](../CHANGELOG.md) for latest additions) |
| [Command Reference](COMMANDS.md) | All users | Stable commands with syntax, flags, options, and examples |
| [Configuration Reference](CONFIGURATION.md) | All users | Full config schema, workflow toggles, model profiles, git branching |
| [CLI Tools Reference](CLI-TOOLS.md) | Contributors, agent authors | `gsd-tools.cjs` programmatic API for workflows and agents |
| [Agent Reference](AGENTS.md) | Contributors, advanced users | All 18 specialized agents — roles, tools, spawn patterns |
| [Agent Reference](AGENTS.md) | Contributors, advanced users | Role cards for primary agents — roles, tools, spawn patterns (the `agents/` filesystem is authoritative) |
| [User Guide](USER-GUIDE.md) | All users | Workflow walkthroughs, troubleshooting, and recovery |
| [Context Monitor](context-monitor.md) | All users | Context window monitoring hook architecture |
| [Discuss Mode](workflow-discuss-mode.md) | All users | Assumptions vs interview mode for discuss-phase |
## Quick Links
- **What's new in v1.32:** STATE.md consistency gates, `--to N` autonomous flag, research gate, verifier scope filtering, read-before-edit guard, 4 new runtimes (Trae, Kilo, Augment, Cline), context reduction, response language config — see [CHANGELOG](../CHANGELOG.md)
- **What's new:** see [CHANGELOG](../CHANGELOG.md) for current release notes, and upstream [README](../README.md) for release highlights
- **Getting started:** [README](../README.md) → install → `/gsd-new-project`
- **Full workflow walkthrough:** [User Guide](USER-GUIDE.md)
- **All commands at a glance:** [Command Reference](COMMANDS.md)
- **Configuring GSD:** [Configuration Reference](CONFIGURATION.md)
- **How the system works internally:** [Architecture](ARCHITECTURE.md)
- **Contributing or extending:** [CLI Tools Reference](CLI-TOOLS.md) + [Agent Reference](AGENTS.md)
- **Contributing or extending:** [CLI Tools Reference](CLI-TOOLS.md) + [Agent Reference](AGENTS.md)

View File

@@ -12,8 +12,7 @@ A detailed reference for workflows, troubleshooting, and configuration. For quic
- [Backlog & Threads](#backlog--threads)
- [Workstreams](#workstreams)
- [Security](#security)
- [Command Reference](#command-reference)
- [Configuration Reference](#configuration-reference)
- [Command And Configuration Reference](#command-and-configuration-reference)
- [Usage Examples](#usage-examples)
- [Troubleshooting](#troubleshooting)
- [Recovery Quick Reference](#recovery-quick-reference)
@@ -166,12 +165,14 @@ By default, `/gsd-discuss-phase` asks open-ended questions about your implementa
**Enable:** Set `workflow.discuss_mode` to `'assumptions'` via `/gsd-settings`.
**How it works:**
1. Reads PROJECT.md, codebase mapping, and existing conventions
2. Generates a structured list of assumptions (tech choices, patterns, file locations)
3. Presents assumptions for you to confirm, correct, or expand
4. Writes CONTEXT.md from confirmed assumptions
**When to use:**
- Experienced developers who already know their codebase well
- Rapid iteration where open-ended questions slow you down
- Projects where patterns are well-established and predictable
@@ -190,16 +191,19 @@ AI-generated frontends are visually inconsistent not because Claude Code is bad
### Commands
| Command | Description |
|---------|-------------|
| `/gsd-ui-phase [N]` | Generate UI-SPEC.md design contract for a frontend phase |
| `/gsd-ui-review [N]` | Retroactive 6-pillar visual audit of implemented UI |
| Command | Description |
| -------------------- | -------------------------------------------------------- |
| `/gsd-ui-phase [N]` | Generate UI-SPEC.md design contract for a frontend phase |
| `/gsd-ui-review [N]` | Retroactive 6-pillar visual audit of implemented UI |
### Workflow: `/gsd-ui-phase`
**When to run:** After `/gsd-discuss-phase`, before `/gsd-plan-phase` — for phases with frontend/UI work.
**Flow:**
1. Reads CONTEXT.md, RESEARCH.md, REQUIREMENTS.md for existing decisions
2. Detects design system state (shadcn components.json, Tailwind config, existing tokens)
3. shadcn initialization gate — offers to initialize if React/Next.js/Vite project has none
@@ -217,6 +221,7 @@ AI-generated frontends are visually inconsistent not because Claude Code is bad
**Standalone:** Works on any project, not just GSD-managed ones. If no UI-SPEC.md exists, audits against abstract 6-pillar standards.
**6 Pillars (scored 1-4 each):**
1. Copywriting — CTA labels, empty states, error states
2. Visuals — focal points, visual hierarchy, icon accessibility
3. Color — accent usage discipline, 60/30/10 compliance
@@ -228,10 +233,12 @@ AI-generated frontends are visually inconsistent not because Claude Code is bad
### Configuration
| Setting | Default | Description |
|---------|---------|-------------|
| `workflow.ui_phase` | `true` | Generate UI design contracts for frontend phases |
| `workflow.ui_safety_gate` | `true` | plan-phase prompts to run /gsd-ui-phase for frontend phases |
| Setting | Default | Description |
| ------------------------- | ------- | ----------------------------------------------------------- |
| `workflow.ui_phase` | `true` | Generate UI design contracts for frontend phases |
| `workflow.ui_safety_gate` | `true` | plan-phase prompts to run /gsd-ui-phase for frontend phases |
Both follow the absent=enabled pattern. Disable via `/gsd-settings`.
@@ -249,6 +256,7 @@ The preset string becomes a first-class GSD planning artifact, reproducible acro
### Registry Safety Gate
Third-party shadcn registries can inject arbitrary code. The safety gate requires:
- `npx shadcn view {component}` — inspect before installing
- `npx shadcn diff {component}` — compare against official
@@ -366,12 +374,14 @@ Workstreams let you work on multiple milestone areas concurrently without state
### Commands
| Command | Purpose |
|---------|---------|
| `/gsd-workstreams create <name>` | Create a new workstream with isolated planning state |
| `/gsd-workstreams switch <name>` | Switch active context to a different workstream |
| `/gsd-workstreams list` | Show all workstreams and which is active |
| `/gsd-workstreams complete <name>` | Mark a workstream as done and archive its state |
| Command | Purpose |
| ---------------------------------- | ---------------------------------------------------- |
| `/gsd-workstreams create <name>` | Create a new workstream with isolated planning state |
| `/gsd-workstreams switch <name>` | Switch active context to a different workstream |
| `/gsd-workstreams list` | Show all workstreams and which is active |
| `/gsd-workstreams complete <name>` | Mark a workstream as done and archive its state |
### How It Works
@@ -394,6 +404,7 @@ All user-supplied file paths (`--text-file`, `--prd`) are validated to resolve w
The `security.cjs` module scans for known injection patterns (role overrides, instruction bypasses, system tag injections) in user-supplied text before it enters planning artifacts.
**Runtime Hooks:**
- `gsd-prompt-guard.js` — Scans Write/Edit calls to `.planning/` for injection patterns (always active, advisory-only)
- `gsd-workflow-guard.js` — Warns on file edits outside GSD workflow context (opt-in via `hooks.workflow_guard`)
@@ -522,222 +533,16 @@ For a focused assessment without full `/gsd-map-codebase` overhead:
---
## Command Reference
## Command And Configuration Reference
### Core Workflow
- **Command Reference:** see [`docs/COMMANDS.md`](COMMANDS.md) for every stable command's flags, subcommands, and examples. The authoritative shipped-command roster lives in [`docs/INVENTORY.md`](INVENTORY.md#commands-75-shipped).
- **Configuration Reference:** see [`docs/CONFIGURATION.md`](CONFIGURATION.md) for the full `config.json` schema, every setting's default and provenance, the per-agent model-profile table (including the `inherit` option for non-Claude runtimes), git branching strategies, and security settings.
- **Discuss Mode:** see [`docs/workflow-discuss-mode.md`](workflow-discuss-mode.md) for interview vs assumptions mode.
| Command | Purpose | When to Use |
|---------|---------|-------------|
| `/gsd-new-project` | Full project init: questions, research, requirements, roadmap | Start of a new project |
| `/gsd-new-project --auto @idea.md` | Automated init from document | Have a PRD or idea doc ready |
| `/gsd-discuss-phase [N]` | Capture implementation decisions | Before planning, to shape how it gets built |
| `/gsd-ui-phase [N]` | Generate UI design contract | After discuss-phase, before plan-phase (frontend phases) |
| `/gsd-plan-phase [N]` | Research + plan + verify | Before executing a phase |
| `/gsd-execute-phase <N>` | Execute all plans in parallel waves | After planning is complete |
| `/gsd-verify-work [N]` | Manual UAT with auto-diagnosis | After execution completes |
| `/gsd-ship [N]` | Create PR from verified work | After verification passes |
| `/gsd-fast <text>` | Inline trivial tasks — skips planning entirely | Typo fixes, config changes, small refactors |
| `/gsd-next` | Auto-detect state and run next step | Anytime — "what should I do next?" |
| `/gsd-ui-review [N]` | Retroactive 6-pillar visual audit | After execution or verify-work (frontend projects) |
| `/gsd-audit-milestone` | Verify milestone met its definition of done | Before completing milestone |
| `/gsd-complete-milestone` | Archive milestone, tag release | All phases verified |
| `/gsd-new-milestone [name]` | Start next version cycle | After completing a milestone |
This guide intentionally does not re-document commands or config settings: maintaining two copies previously produced drift (`workflow.discuss_mode`'s default, `claude_md_path`'s default, the model-profile table's agent coverage). The single-source-of-truth rule is enforced mechanically by the drift-guard tests anchored on `docs/INVENTORY.md`.
### Navigation
| Command | Purpose | When to Use |
|---------|---------|-------------|
| `/gsd-progress` | Show status and next steps | Anytime -- "where am I?" |
| `/gsd-resume-work` | Restore full context from last session | Starting a new session |
| `/gsd-pause-work` | Save structured handoff (HANDOFF.json + continue-here.md) | Stopping mid-phase |
| `/gsd-session-report` | Generate session summary with work and outcomes | End of session, stakeholder sharing |
| `/gsd-help` | Show all commands | Quick reference |
| `/gsd-update` | Update GSD with changelog preview | Check for new versions |
| `/gsd-join-discord` | Open Discord community invite | Questions or community |
### Phase Management
| Command | Purpose | When to Use |
|---------|---------|-------------|
| `/gsd-add-phase` | Append new phase to roadmap | Scope grows after initial planning |
| `/gsd-insert-phase [N]` | Insert urgent work (decimal numbering) | Urgent fix mid-milestone |
| `/gsd-remove-phase [N]` | Remove future phase and renumber | Descoping a feature |
| `/gsd-list-phase-assumptions [N]` | Preview Claude's intended approach | Before planning, to validate direction |
| `/gsd-analyze-dependencies` | Detect phase dependencies for ROADMAP.md | Before `/gsd-manager` when phases have empty `Depends on` |
| `/gsd-plan-milestone-gaps` | Create phases for audit gaps | After audit finds missing items |
| `/gsd-research-phase [N]` | Deep ecosystem research only | Complex or unfamiliar domain |
### Brownfield & Utilities
| Command | Purpose | When to Use |
|---------|---------|-------------|
| `/gsd-map-codebase` | Analyze existing codebase (4 parallel agents) | Before `/gsd-new-project` on existing code |
| `/gsd-scan [--focus area]` | Rapid single-focus codebase scan (1 agent) | Quick assessment of a specific area |
| `/gsd-intel [query\|status\|diff\|refresh]` | Query codebase intelligence index | Look up APIs, deps, or architecture decisions |
| `/gsd-explore [topic]` | Socratic ideation — think through an idea before committing | Exploring unfamiliar solution space |
| `/gsd-quick` | Ad-hoc task with GSD guarantees | Bug fixes, small features, config changes |
| `/gsd-autonomous` | Run remaining phases autonomously (`--from N`, `--to N`) | Hands-free multi-phase execution |
| `/gsd-undo --last N\|--phase NN\|--plan NN-MM` | Safe git revert using phase manifest | Roll back a bad execution |
| `/gsd-import --from <file>` | Ingest external plan with conflict detection | Import plans from teammates or other tools |
| `/gsd-debug [desc]` | Systematic debugging with persistent state (`--diagnose` for no-fix mode) | When something breaks |
| `/gsd-forensics` | Diagnostic report for workflow failures | When state, artifacts, or git history seem corrupted |
| `/gsd-add-todo [desc]` | Capture an idea for later | Think of something during a session |
| `/gsd-check-todos` | List pending todos | Review captured ideas |
| `/gsd-settings` | Configure workflow toggles and model profile | Change model, toggle agents |
| `/gsd-set-profile <profile>` | Quick profile switch | Change cost/quality tradeoff |
| `/gsd-reapply-patches` | Restore local modifications after update | After `/gsd-update` if you had local edits |
### Code Quality & Review
| Command | Purpose | When to Use |
|---------|---------|-------------|
| `/gsd-review --phase N` | Cross-AI peer review from external CLIs | Before executing, to validate plans |
| `/gsd-code-review <N>` | Review source files changed in a phase for bugs and security issues | After execution, before verification |
| `/gsd-code-review-fix <N>` | Auto-fix issues found by `/gsd-code-review` | After code review produces REVIEW.md |
| `/gsd-audit-fix` | Autonomous audit-to-fix pipeline with classification and atomic commits | After UAT surfaces fixable issues |
| `/gsd-pr-branch` | Clean PR branch filtering `.planning/` commits | Before creating PR with planning-free diff |
| `/gsd-audit-uat` | Audit verification debt across all phases | Before milestone completion |
### Backlog & Threads
| Command | Purpose | When to Use |
|---------|---------|-------------|
| `/gsd-add-backlog <desc>` | Add idea to backlog parking lot (999.x) | Ideas not ready for active planning |
| `/gsd-review-backlog` | Promote/keep/remove backlog items | Before new milestone, to prioritize |
| `/gsd-plant-seed <idea>` | Forward-looking idea with trigger conditions | Ideas that should surface at a future milestone |
| `/gsd-thread [name]` | Persistent context threads | Cross-session work outside the phase structure |
---
## Configuration Reference
GSD stores project settings in `.planning/config.json`. Configure during `/gsd-new-project` or update later with `/gsd-settings`.
### Full config.json Schema
```json
{
"mode": "interactive",
"granularity": "standard",
"model_profile": "balanced",
"planning": {
"commit_docs": true,
"search_gitignored": false
},
"workflow": {
"research": true,
"plan_check": true,
"verifier": true,
"nyquist_validation": true,
"ui_phase": true,
"ui_safety_gate": true,
"research_before_questions": false,
"discuss_mode": "standard",
"skip_discuss": false
},
"resolve_model_ids": "anthropic",
"hooks": {
"context_warnings": true,
"workflow_guard": false
},
"git": {
"branching_strategy": "none",
"phase_branch_template": "gsd/phase-{phase}-{slug}",
"milestone_branch_template": "gsd/{milestone}-{slug}",
"quick_branch_template": null
}
}
```
### Core Settings
| Setting | Options | Default | What it Controls |
|---------|---------|---------|------------------|
| `mode` | `interactive`, `yolo` | `interactive` | `yolo` auto-approves decisions; `interactive` confirms at each step |
| `granularity` | `coarse`, `standard`, `fine` | `standard` | Phase granularity: how finely scope is sliced (3-5, 5-8, or 8-12 phases) |
| `model_profile` | `quality`, `balanced`, `budget`, `inherit` | `balanced` | Model tier for each agent (see table below) |
### Planning Settings
| Setting | Options | Default | What it Controls |
|---------|---------|---------|------------------|
| `planning.commit_docs` | `true`, `false` | `true` | Whether `.planning/` files are committed to git |
| `planning.search_gitignored` | `true`, `false` | `false` | Add `--no-ignore` to broad searches to include `.planning/` |
> **Note:** If `.planning/` is in `.gitignore`, `commit_docs` is automatically `false` regardless of the config value.
### Workflow Toggles
| Setting | Options | Default | What it Controls |
|---------|---------|---------|------------------|
| `workflow.research` | `true`, `false` | `true` | Domain investigation before planning |
| `workflow.plan_check` | `true`, `false` | `true` | Plan verification loop (up to 3 iterations) |
| `workflow.verifier` | `true`, `false` | `true` | Post-execution verification against phase goals |
| `workflow.nyquist_validation` | `true`, `false` | `true` | Validation architecture research during plan-phase; 8th plan-check dimension |
| `workflow.ui_phase` | `true`, `false` | `true` | Generate UI design contracts for frontend phases |
| `workflow.ui_safety_gate` | `true`, `false` | `true` | plan-phase prompts to run /gsd-ui-phase for frontend phases |
| `workflow.research_before_questions` | `true`, `false` | `false` | Run research before discussion questions instead of after |
| `workflow.discuss_mode` | `standard`, `assumptions` | `standard` | Discussion style: open-ended questions vs. codebase-driven assumptions |
| `workflow.skip_discuss` | `true`, `false` | `false` | Skip discuss-phase entirely in autonomous mode; writes minimal CONTEXT.md from ROADMAP phase goal |
| `response_language` | language code | (none) | Agent response language for cross-phase consistency (e.g., `"pt"`, `"ko"`, `"ja"`) |
### Hook Settings
| Setting | Options | Default | What it Controls |
|---------|---------|---------|------------------|
| `hooks.context_warnings` | `true`, `false` | `true` | Context window usage warnings |
| `hooks.workflow_guard` | `true`, `false` | `false` | Warn on file edits outside GSD workflow context |
Disable workflow toggles to speed up phases in familiar domains or when conserving tokens.
### Git Branching
| Setting | Options | Default | What it Controls |
|---------|---------|---------|------------------|
| `git.branching_strategy` | `none`, `phase`, `milestone` | `none` | When and how branches are created |
| `git.phase_branch_template` | Template string | `gsd/phase-{phase}-{slug}` | Branch name for phase strategy |
| `git.milestone_branch_template` | Template string | `gsd/{milestone}-{slug}` | Branch name for milestone strategy |
| `git.quick_branch_template` | Template string or `null` | `null` | Optional branch name for `/gsd-quick` tasks |
**Branching strategies explained:**
| Strategy | Creates Branch | Scope | Best For |
|----------|---------------|-------|----------|
| `none` | Never | N/A | Solo development, simple projects |
| `phase` | At each `execute-phase` | One phase per branch | Code review per phase, granular rollback |
| `milestone` | At first `execute-phase` | All phases share one branch | Release branches, PR per version |
**Template variables:** `{phase}` = zero-padded number (e.g., "03"), `{slug}` = lowercase hyphenated name, `{milestone}` = version (e.g., "v1.0"), `{num}` / `{quick}` = quick task ID (e.g., "260317-abc").
Example quick-task branching:
```json
"git": {
"quick_branch_template": "gsd/quick-{num}-{slug}"
}
```
### Model Profiles (Per-Agent Breakdown)
| Agent | `quality` | `balanced` | `budget` | `inherit` |
|-------|-----------|------------|----------|-----------|
| gsd-planner | Opus | Opus | Sonnet | Inherit |
| gsd-roadmapper | Opus | Sonnet | Sonnet | Inherit |
| gsd-executor | Opus | Sonnet | Sonnet | Inherit |
| gsd-phase-researcher | Opus | Sonnet | Haiku | Inherit |
| gsd-project-researcher | Opus | Sonnet | Haiku | Inherit |
| gsd-research-synthesizer | Sonnet | Sonnet | Haiku | Inherit |
| gsd-debugger | Opus | Sonnet | Sonnet | Inherit |
| gsd-codebase-mapper | Sonnet | Haiku | Haiku | Inherit |
| gsd-verifier | Sonnet | Sonnet | Haiku | Inherit |
| gsd-plan-checker | Sonnet | Sonnet | Haiku | Inherit |
| gsd-integration-checker | Sonnet | Sonnet | Haiku | Inherit |
**Profile philosophy:**
- **quality** -- Opus for all decision-making agents, Sonnet for read-only verification. Use when quota is available and the work is critical.
- **balanced** -- Opus only for planning (where architecture decisions happen), Sonnet for everything else. The default for good reason.
- **budget** -- Sonnet for anything that writes code, Haiku for research and verification. Use for high-volume work or less critical phases.
- **inherit** -- All agents use the current session model. Best when switching models dynamically (e.g. OpenCode or Kilo `/model`), or when using Claude Code with non-Anthropic providers (OpenRouter, local models) to avoid unexpected API costs. For non-Claude runtimes (Codex, OpenCode, Gemini CLI, Kilo), the installer sets `resolve_model_ids: "omit"` automatically -- see [Non-Claude Runtimes](#using-non-claude-runtimes-codex-opencode-gemini-cli-kilo).
<!-- The Command Reference table previously here duplicated docs/COMMANDS.md; removed to stop drift. -->
<!-- The Configuration Reference subsection (core settings, planning, workflow toggles, hooks, git branching, model profiles) previously here duplicated docs/CONFIGURATION.md; removed to stop drift. The `resolve_model_ids` ghost key that appeared only in this file's abbreviated schema is retired with the duplicate. -->
---
@@ -805,11 +610,13 @@ claude --dangerously-skip-permissions
### Speed vs Quality Presets
| Scenario | Mode | Granularity | Profile | Research | Plan Check | Verifier |
|----------|------|-------|---------|----------|------------|----------|
| Prototyping | `yolo` | `coarse` | `budget` | off | off | off |
| Normal dev | `interactive` | `standard` | `balanced` | on | on | on |
| Production | `interactive` | `fine` | `quality` | on | on | on |
| Scenario | Mode | Granularity | Profile | Research | Plan Check | Verifier |
| ----------- | ------------- | ----------- | ---------- | -------- | ---------- | -------- |
| Prototyping | `yolo` | `coarse` | `budget` | off | off | off |
| Normal dev | `interactive` | `standard` | `balanced` | on | on | on |
| Production | `interactive` | `fine` | `quality` | on | on | on |
**Skipping discuss-phase in autonomous mode:** When running in `yolo` mode with well-established preferences already captured in PROJECT.md, set `workflow.skip_discuss: true` via `/gsd-settings`. This bypasses the discuss-phase entirely and writes a minimal CONTEXT.md derived from the ROADMAP phase goal. Useful when your PROJECT.md and conventions are comprehensive enough that discussion adds no new information.
@@ -844,6 +651,7 @@ cd ~/gsd-workspaces/feature-b
```
Each workspace gets:
- Its own `.planning/` directory (fully independent from source repos)
- Git worktrees (default) or clones of specified repos
- A `WORKSPACE.md` manifest tracking member repos
@@ -854,9 +662,9 @@ Each workspace gets:
### Programmatic CLI (`gsd-sdk query` vs `gsd-tools.cjs`)
For automation and copy-paste from docs, prefer **`gsd-sdk query`** with a registered subcommand (see [CLI-TOOLS.md](CLI-TOOLS.md) and [QUERY-HANDLERS.md](../sdk/src/query/QUERY-HANDLERS.md)). The legacy **`node $HOME/.claude/get-shit-done/bin/gsd-tools.cjs`** CLI remains supported for dual-mode operation.
For automation and copy-paste from docs, prefer **`gsd-sdk query`** with a registered subcommand (see [CLI-TOOLS.md — SDK and programmatic access](CLI-TOOLS.md#sdk-and-programmatic-access) and [QUERY-HANDLERS.md](../sdk/src/query/QUERY-HANDLERS.md)). The legacy `node $HOME/.claude/get-shit-done/bin/gsd-tools.cjs` CLI remains supported for dual-mode operation.
**Not yet on `gsd-sdk query` (use CJS):** `state validate`, `state sync`, `audit-open`, `graphify`, `from-gsd2`, and any subcommand not listed in the registry.
**CLI-only (not in the query registry):** **graphify**, **from-gsd2** / **gsd2-import** — call `gsd-tools.cjs` (see [QUERY-HANDLERS.md](../sdk/src/query/QUERY-HANDLERS.md)). **Two different `state` JSON shapes in the legacy CLI:** `state json` (frontmatter rebuild) vs `state load` (`config` + `state_raw` + flags). **`gsd-sdk query` today:** both `state.json` and `state.load` resolve to the frontmatter-rebuild handler — use `node …/gsd-tools.cjs state load` when you need the CJS `state load` shape. See [CLI-TOOLS.md](CLI-TOOLS.md#sdk-and-programmatic-access) and QUERY-HANDLERS.
### STATE.md Out of Sync
@@ -989,6 +797,7 @@ If `npx get-shit-done-cc` fails due to npm outages or network restrictions, see
When a workflow fails in a way that isn't obvious -- plans reference nonexistent files, execution produces unexpected results, or state seems corrupted -- run `/gsd-forensics` to generate a diagnostic report.
**What it checks:**
- Git history anomalies (orphaned commits, unexpected branch state, rebase artifacts)
- Artifact integrity (missing or malformed planning files, broken cross-references)
- State inconsistencies (ROADMAP status vs. actual file presence, config drift)
@@ -1123,22 +932,24 @@ If the installer crashes with `EPERM: operation not permitted, scandir` on Windo
## Recovery Quick Reference
| Problem | Solution |
|---------|----------|
| Lost context / new session | `/gsd-resume-work` or `/gsd-progress` |
| Phase went wrong | `git revert` the phase commits, then re-plan |
| Need to change scope | `/gsd-add-phase`, `/gsd-insert-phase`, or `/gsd-remove-phase` |
| Milestone audit found gaps | `/gsd-plan-milestone-gaps` |
| Something broke | `/gsd-debug "description"` (add `--diagnose` for analysis without fixes) |
| STATE.md out of sync | `state validate` then `state sync` |
| Workflow state seems corrupted | `/gsd-forensics` |
| Quick targeted fix | `/gsd-quick` |
| Plan doesn't match your vision | `/gsd-discuss-phase [N]` then re-plan |
| Costs running high | `/gsd-set-profile budget` and `/gsd-settings` to toggle agents off |
| Update broke local changes | `/gsd-reapply-patches` |
| Want session summary for stakeholder | `/gsd-session-report` |
| Don't know what step is next | `/gsd-next` |
| Parallel execution build errors | Update GSD or set `parallelization.enabled: false` |
| Problem | Solution |
| ------------------------------------ | ------------------------------------------------------------------------ |
| Lost context / new session | `/gsd-resume-work` or `/gsd-progress` |
| Phase went wrong | `git revert` the phase commits, then re-plan |
| Need to change scope | `/gsd-add-phase`, `/gsd-insert-phase`, or `/gsd-remove-phase` |
| Milestone audit found gaps | `/gsd-plan-milestone-gaps` |
| Something broke | `/gsd-debug "description"` (add `--diagnose` for analysis without fixes) |
| STATE.md out of sync | `state validate` then `state sync` |
| Workflow state seems corrupted | `/gsd-forensics` |
| Quick targeted fix | `/gsd-quick` |
| Plan doesn't match your vision | `/gsd-discuss-phase [N]` then re-plan |
| Costs running high | `/gsd-set-profile budget` and `/gsd-settings` to toggle agents off |
| Update broke local changes | `/gsd-reapply-patches` |
| Want session summary for stakeholder | `/gsd-session-report` |
| Don't know what step is next | `/gsd-next` |
| Parallel execution build errors | Update GSD or set `parallelization.enabled: false` |
---
@@ -1182,3 +993,4 @@ For reference, here is what GSD creates in your project:
XX-UI-REVIEW.md # Visual audit scores (from /gsd-ui-review)
ui-reviews/ # Screenshots from /gsd-ui-review (gitignored)
```

View File

@@ -4,7 +4,7 @@ Copy-paste friendly for Discord and GitHub comments.
---
**@gsd-build/sdk** replaces the untyped, monolithic `gsd-tools.cjs` subprocess with a typed, tested, registry-based query system and **`gsd-sdk query`**, giving GSD structured results, classified errors (`GSDQueryError`), and golden-verified parity with the old CLI. That gives the framework one stable contract instead of a fragile, very large CLI that every workflow had to spawn and parse by hand.
**@gsd-build/sdk** replaces the untyped, monolithic `gsd-tools.cjs` subprocess with a typed, tested, registry-based query system and **`gsd-sdk query`**, giving GSD structured results, classified errors (`GSDError` with `ErrorClassification`), and golden-verified parity with the old CLI. That gives the framework one stable contract instead of a fragile, very large CLI that every workflow had to spawn and parse by hand.
**What users can expect**

View File

@@ -10,7 +10,7 @@ Get Shit DoneGSDフレームワークの包括的なドキュメントで
| [機能リファレンス](FEATURES.md) | 全ユーザー | 全機能の詳細ドキュメントと要件 |
| [コマンドリファレンス](COMMANDS.md) | 全ユーザー | 全コマンドの構文、フラグ、オプション、使用例 |
| [設定リファレンス](CONFIGURATION.md) | 全ユーザー | 設定スキーマ、ワークフロートグル、モデルプロファイル、Git ブランチ |
| [CLI ツールリファレンス](CLI-TOOLS.md) | コントリビューター、エージェント作成者 | `gsd-tools.cjs` のプログラマティック APIワークフローおよびエージェント向け |
| [CLI ツールリファレンス](CLI-TOOLS.md) | コントリビューター、エージェント作成者 | CJS `gsd-tools.cjs` **`gsd-sdk query` / SDK** のガイド |
| [エージェントリファレンス](AGENTS.md) | コントリビューター、上級ユーザー | 全18種の専門エージェント — 役割、ツール、スポーンパターン |
| [ユーザーガイド](USER-GUIDE.md) | 全ユーザー | ワークフローのウォークスルー、トラブルシューティング、リカバリー |
| [コンテキストモニター](context-monitor.md) | 全ユーザー | コンテキストウィンドウ監視フックのアーキテクチャ |

View File

@@ -12,7 +12,7 @@ Get Shit Done (GSD) 프레임워크의 종합 문서입니다. GSD는 AI 코딩
| [Feature Reference](FEATURES.md) | 전체 사용자 | 요구사항이 포함된 전체 기능 및 함수 문서 |
| [Command Reference](COMMANDS.md) | 전체 사용자 | 모든 명령어의 구문, 플래그, 옵션 및 예제 |
| [Configuration Reference](CONFIGURATION.md) | 전체 사용자 | 전체 설정 스키마, 워크플로우 토글, 모델 프로필, git 브랜칭 |
| [CLI Tools Reference](CLI-TOOLS.md) | 기여자, 에이전트 작성자 | 워크플로우 및 에이전트를 위한 `gsd-tools.cjs` 프로그래매틱 API |
| [CLI Tools Reference](CLI-TOOLS.md) | 기여자, 에이전트 작성자 | CJS `gsd-tools.cjs` + **`gsd-sdk query`/SDK** 안내 |
| [Agent Reference](AGENTS.md) | 기여자, 고급 사용자 | 18개 전문 에이전트의 역할, 도구, 스폰 패턴 |
| [User Guide](USER-GUIDE.md) | 전체 사용자 | 워크플로우 안내, 문제 해결, 복구 방법 |
| [Context Monitor](context-monitor.md) | 전체 사용자 | 컨텍스트 윈도우 모니터링 훅 아키텍처 |

View File

@@ -1,7 +1,7 @@
# Referência de Ferramentas CLI
Resumo em Português das ferramentas CLI do GSD.
Para API completa (assinaturas, argumentos e comportamento detalhado), consulte [CLI-TOOLS.md em inglês](../CLI-TOOLS.md).
Para API completa (assinaturas, argumentos e comportamento detalhado), consulte [CLI-TOOLS.md em inglês](../CLI-TOOLS.md) — inclui a secção **SDK and programmatic access** (`gsd-sdk query`, `@gsd-build/sdk`).
---

View File

@@ -12,7 +12,7 @@ Documentação abrangente do framework Get Shit Done (GSD) — um sistema de met
| [Referência de configuração](CONFIGURATION.md) | Todos os usuários | Schema completo de configuração, toggles e perfis |
| [Referência de recursos](FEATURES.md) | Todos os usuários | Recursos e requisitos detalhados |
| [Referência de agentes](AGENTS.md) | Contribuidores, usuários avançados | Agentes especializados, papéis e padrões de orquestração |
| [Ferramentas CLI](CLI-TOOLS.md) | Contribuidores, autores de agentes | API programática `gsd-tools.cjs` |
| [Ferramentas CLI](CLI-TOOLS.md) | Contribuidores, autores de agentes | Superfície CJS `gsd-tools.cjs` + guia **`gsd-sdk query`/SDK** |
| [Monitor de contexto](context-monitor.md) | Todos os usuários | Arquitetura de monitoramento da janela de contexto |
| [Discuss Mode](workflow-discuss-mode.md) | Todos os usuários | Modo suposições vs entrevista no `discuss-phase` |
| [Referências](references/) | Todos os usuários | Guias complementares de decisão, verificação e padrões |

View File

@@ -27,10 +27,10 @@ correction. Good for:
```bash
# Enable assumptions mode
gsd-tools config-set workflow.discuss_mode assumptions
node gsd-tools.cjs config-set workflow.discuss_mode assumptions
# Switch back to interview mode
gsd-tools config-set workflow.discuss_mode discuss
node gsd-tools.cjs config-set workflow.discuss_mode discuss
```
The setting is per-project (stored in `.planning/config.json`).

View File

@@ -2,11 +2,11 @@
为紧急插入计算下一个小数阶段编号。
## 使用 gsd-tools
## 使用 gsd-sdk query
```bash
# 获取阶段 6 之后的下一个小数阶段
node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" phase next-decimal 6
gsd-sdk query phase.next-decimal 6
```
输出:
@@ -32,14 +32,13 @@ node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" phase next-decimal 6
## 提取值
```bash
DECIMAL_INFO=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" phase next-decimal "${AFTER_PHASE}")
DECIMAL_PHASE=$(printf '%s\n' "$DECIMAL_INFO" | jq -r '.next')
BASE_PHASE=$(printf '%s\n' "$DECIMAL_INFO" | jq -r '.base_phase')
DECIMAL_PHASE=$(gsd-sdk query phase.next-decimal "${AFTER_PHASE}" --pick next)
BASE_PHASE=$(gsd-sdk query phase.next-decimal "${AFTER_PHASE}" --pick base_phase)
```
或使用 --raw 标志:
```bash
DECIMAL_PHASE=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" phase next-decimal "${AFTER_PHASE}" --raw)
DECIMAL_PHASE=$(gsd-sdk query phase.next-decimal "${AFTER_PHASE}" --raw)
# 返回: 06.1
```
@@ -57,9 +56,9 @@ DECIMAL_PHASE=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" phase next-
小数阶段目录使用完整的小数编号:
```bash
SLUG=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" generate-slug "$DESCRIPTION" --raw)
SLUG=$(gsd-sdk query generate-slug "$DESCRIPTION" --raw)
PHASE_DIR=".planning/phases/${DECIMAL_PHASE}-${SLUG}"
mkdir -p "$PHASE_DIR"
```
示例:`.planning/phases/06.1-fix-critical-auth-bug/`
示例:`.planning/phases/06.1-fix-critical-auth-bug/`

View File

@@ -51,7 +51,7 @@ Phases:
提交内容:
```bash
node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" commit "docs: initialize [project-name] ([N] phases)" --files .planning/
gsd-sdk query commit "docs: initialize [project-name] ([N] phases)" .planning/
```
</format>
@@ -129,7 +129,7 @@ SUMMARY: .planning/phases/XX-name/{phase}-{plan}-SUMMARY.md
提交内容:
```bash
node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" commit "docs({phase}-{plan}): complete [plan-name] plan" --files .planning/phases/XX-name/{phase}-{plan}-PLAN.md .planning/phases/XX-name/{phase}-{plan}-SUMMARY.md .planning/STATE.md .planning/ROADMAP.md
gsd-sdk query commit "docs({phase}-{plan}): complete [plan-name] plan" .planning/phases/XX-name/{phase}-{plan}-PLAN.md .planning/phases/XX-name/{phase}-{plan}-SUMMARY.md .planning/STATE.md .planning/ROADMAP.md
```
**注意:** 代码文件不包含 - 已按任务提交。
@@ -149,7 +149,7 @@ Current: [task name]
提交内容:
```bash
node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" commit "wip: [phase-name] paused at task [X]/[Y]" --files .planning/
gsd-sdk query commit "wip: [phase-name] paused at task [X]/[Y]" .planning/
```
</format>

View File

@@ -1,13 +1,15 @@
# Git 规划提交
使用 gsd-tools CLI 提交规划工件,它会自动检查 `commit_docs` 配置和 gitignore 状态。
通过 `gsd-sdk query commit` 提交规划工件,它会自动检查 `commit_docs` 配置和 gitignore 状态(与旧版 `gsd-tools.cjs commit` 行为相同)
## 通过 CLI 提交
始终使用 `gsd-tools.cjs commit` 处理 `.planning/` 文件 — 它会自动处理 `commit_docs` 和 gitignore 检查:
先传提交说明,再传文件路径(位置参数)。`commit` 不要使用 `--files`(该标志仅用于 `commit-to-subrepo`)。
`.planning/` 文件始终使用此方式 —— 它会自动处理 `commit_docs` 与 gitignore 检查:
```bash
node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" commit "docs({scope}): {description}" --files .planning/STATE.md .planning/ROADMAP.md
gsd-sdk query commit "docs({scope}): {description}" .planning/STATE.md .planning/ROADMAP.md
```
如果 `commit_docs``false``.planning/` 被 gitignoreCLI 会返回 `skipped`(带原因)。无需手动条件检查。
@@ -17,7 +19,7 @@ node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" commit "docs({scope}): {des
`.planning/` 文件变更合并到上次提交:
```bash
node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" commit "" --files .planning/codebase/*.md --amend
gsd-sdk query commit "" .planning/codebase/*.md --amend
```
## 提交消息模式
@@ -35,4 +37,4 @@ node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" commit "" --files .planning
- config 中 `commit_docs: false`
- `.planning/` 被 gitignore
- 无变更可提交(用 `git status --porcelain .planning/` 检查)
- 无变更可提交(用 `git status --porcelain .planning/` 检查)

View File

@@ -36,19 +36,19 @@
- 用户必须将 `.planning/` 添加到 `.gitignore`
- 适用于OSS 贡献、客户项目、保持规划私有
**使用 gsd-tools.cjs(推荐):**
**使用 `gsd-sdk query`(推荐):**
```bash
# 提交时自动检查 commit_docs + gitignore
node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" commit "docs: update state" --files .planning/STATE.md
gsd-sdk query commit "docs: update state" .planning/STATE.md
# 通过 state load 加载配置(返回 JSON
INIT=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" state load)
INIT=$(gsd-sdk query state.load)
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
# commit_docs 在 JSON 输出中可用
# 或使用包含 commit_docs 的 init 命令:
INIT=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" init execute-phase "1")
INIT=$(gsd-sdk query init.execute-phase "1")
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
# commit_docs 包含在所有 init 命令输出中
```
@@ -58,7 +58,7 @@ if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
**通过 CLI 提交(自动处理检查):**
```bash
node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" commit "docs: update state" --files .planning/STATE.md
gsd-sdk query commit "docs: update state" .planning/STATE.md
```
CLI 在内部检查 `commit_docs` 配置和 gitignore 状态 —— 无需手动条件判断。
@@ -146,14 +146,14 @@ CLI 在内部检查 `commit_docs` 配置和 gitignore 状态 —— 无需手动
使用 `init execute-phase` 返回所有配置为 JSON
```bash
INIT=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" init execute-phase "1")
INIT=$(gsd-sdk query init.execute-phase "1")
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
# JSON 输出包含branching_strategy, phase_branch_template, milestone_branch_template
```
或使用 `state load` 获取配置值:
```bash
INIT=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" state load)
INIT=$(gsd-sdk query state.load)
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
# 从 JSON 解析 branching_strategy, phase_branch_template, milestone_branch_template
```

View File

@@ -49,6 +49,7 @@
* roadmap get-phase <phase> Extract phase section from ROADMAP.md
* roadmap analyze Full roadmap parse with disk status
* roadmap update-plan-progress <N> Update progress table row from disk (PLAN vs SUMMARY counts)
* roadmap annotate-dependencies <N> Add wave dependency notes + cross-cutting constraints to ROADMAP.md
*
* Requirements Operations:
* requirements mark-complete <ids> Mark requirement IDs as complete in REQUIREMENTS.md
@@ -690,8 +691,10 @@ async function runCommand(command, args, cwd, raw, defaultValue) {
roadmap.cmdRoadmapAnalyze(cwd, raw);
} else if (subcommand === 'update-plan-progress') {
roadmap.cmdRoadmapUpdatePlanProgress(cwd, args[2], raw);
} else if (subcommand === 'annotate-dependencies') {
roadmap.cmdRoadmapAnnotateDependencies(cwd, args[2], raw);
} else {
error('Unknown roadmap subcommand. Available: get-phase, analyze, update-plan-progress');
error('Unknown roadmap subcommand. Available: get-phase, analyze, update-plan-progress, annotate-dependencies');
}
break;
}
@@ -764,7 +767,8 @@ async function runCommand(command, args, cwd, raw, defaultValue) {
verify.cmdValidateConsistency(cwd, raw);
} else if (subcommand === 'health') {
const repairFlag = args.includes('--repair');
verify.cmdValidateHealth(cwd, { repair: repairFlag }, raw);
const backfillFlag = args.includes('--backfill');
verify.cmdValidateHealth(cwd, { repair: repairFlag, backfill: backfillFlag }, raw);
} else if (subcommand === 'agents') {
verify.cmdValidateAgents(cwd, raw);
} else {
@@ -1200,10 +1204,6 @@ async function runCommand(command, args, cwd, raw, defaultValue) {
'agents',
path.join('commands', 'gsd'),
'hooks',
// OpenCode/Kilo flat command dir
'command',
// Codex/Copilot skills dir
'skills',
];
function walkDir(dir, baseDir) {

View File

@@ -0,0 +1,52 @@
/**
* Canonical GSD artifact registry.
*
* Enumerates the file names that gsd workflows officially produce at the
* .planning/ root level. Used by gsd-health (W019) to flag unrecognized files
* so stale or misnamed artifacts don't silently mislead agents or reviewers.
*
* Add entries here whenever a new workflow produces a .planning/ root file.
*/
'use strict';
// Exact-match canonical file names at .planning/ root
const CANONICAL_EXACT = new Set([
'PROJECT.md',
'ROADMAP.md',
'STATE.md',
'REQUIREMENTS.md',
'MILESTONES.md',
'BACKLOG.md',
'LEARNINGS.md',
'THREADS.md',
'config.json',
'CLAUDE.md',
]);
// Pattern-match canonical file names (regex tests on the basename)
// Each pattern includes the name of the workflow that produces it as a comment.
const CANONICAL_PATTERNS = [
/^v\d+\.\d+(?:\.\d+)?-MILESTONE-AUDIT\.md$/i, // gsd-complete-milestone (pre-archive)
/^v\d+\.\d+(?:\.\d+)?-.*\.md$/i, // other version-stamped planning docs
];
/**
* Return true if `filename` (basename only, no path) matches a canonical
* .planning/ root artifact — either an exact name or a known pattern.
*
* @param {string} filename - Basename of the file (e.g. "STATE.md")
*/
function isCanonicalPlanningFile(filename) {
if (CANONICAL_EXACT.has(filename)) return true;
for (const pattern of CANONICAL_PATTERNS) {
if (pattern.test(filename)) return true;
}
return false;
}
module.exports = {
CANONICAL_EXACT,
CANONICAL_PATTERNS,
isCanonicalPlanningFile,
};

View File

@@ -4,7 +4,7 @@
* Scans all .planning/ artifact categories for items with open/unresolved state.
* Returns structured JSON for workflow consumption.
* Called by: gsd-tools.cjs audit-open
* Used by: /gsd-complete-milestone pre-close gate
* Used by: /gsd:complete-milestone pre-close gate
*/
'use strict';

View File

@@ -773,7 +773,7 @@ function cmdScaffold(cwd, type, options, raw) {
switch (type) {
case 'context': {
filePath = path.join(phaseDir, `${padded}-CONTEXT.md`);
content = `---\nphase: "${padded}"\nname: "${name || phaseInfo?.phase_name || 'Unnamed'}"\ncreated: ${today}\n---\n\n# Phase ${phase}: ${name || phaseInfo?.phase_name || 'Unnamed'} — Context\n\n## Decisions\n\n_Decisions will be captured during /gsd-discuss-phase ${phase}_\n\n## Discretion Areas\n\n_Areas where the executor can use judgment_\n\n## Deferred Ideas\n\n_Ideas to consider later_\n`;
content = `---\nphase: "${padded}"\nname: "${name || phaseInfo?.phase_name || 'Unnamed'}"\ncreated: ${today}\n---\n\n# Phase ${phase}: ${name || phaseInfo?.phase_name || 'Unnamed'} — Context\n\n## Decisions\n\n_Decisions will be captured during /gsd:discuss-phase ${phase}_\n\n## Discretion Areas\n\n_Areas where the executor can use judgment_\n\n## Deferred Ideas\n\n_Ideas to consider later_\n`;
break;
}
case 'uat': {

View File

@@ -0,0 +1,83 @@
'use strict';
/**
* Single source of truth for valid config key paths.
*
* Imported by:
* - config.cjs (isValidConfigKey validator)
* - tests/config-schema-docs-parity.test.cjs (CI drift guard)
*
* Adding a key here without documenting it in docs/CONFIGURATION.md will
* fail the parity test. Adding a key to docs/CONFIGURATION.md without
* adding it here will cause config-set to reject it at runtime.
*/
/** Exact-match config key paths accepted by config-set. */
const VALID_CONFIG_KEYS = new Set([
'mode', 'granularity', 'parallelization', 'commit_docs', 'model_profile',
'search_gitignored', 'brave_search', 'firecrawl', 'exa_search',
'workflow.research', 'workflow.plan_check', 'workflow.verifier',
'workflow.nyquist_validation', 'workflow.ai_integration_phase', 'workflow.ui_phase', 'workflow.ui_safety_gate',
'workflow.auto_advance', 'workflow.node_repair', 'workflow.node_repair_budget',
'workflow.tdd_mode',
'workflow.text_mode',
'workflow.research_before_questions',
'workflow.discuss_mode',
'workflow.skip_discuss',
'workflow.auto_prune_state',
'workflow.use_worktrees',
'workflow.code_review',
'workflow.code_review_depth',
'workflow.code_review_command',
'workflow.pattern_mapper',
'workflow.plan_bounce',
'workflow.plan_bounce_script',
'workflow.plan_bounce_passes',
'workflow.plan_chunked',
'workflow.security_enforcement',
'workflow.security_asvs_level',
'workflow.security_block_on',
'git.branching_strategy', 'git.base_branch', 'git.phase_branch_template', 'git.milestone_branch_template', 'git.quick_branch_template',
'planning.commit_docs', 'planning.search_gitignored', 'planning.sub_repos',
'workflow.cross_ai_execution', 'workflow.cross_ai_command', 'workflow.cross_ai_timeout',
'workflow.subagent_timeout',
'workflow.inline_plan_threshold',
'hooks.context_warnings',
'hooks.workflow_guard',
'statusline.show_last_command',
'workflow.ui_review',
'workflow.max_discuss_passes',
'features.thinking_partner',
'context',
'features.global_learnings',
'learnings.max_inject',
'project_code', 'phase_naming',
'manager.flags.discuss', 'manager.flags.plan', 'manager.flags.execute',
'response_language',
'intel.enabled',
'graphify.enabled',
'graphify.build_timeout',
'claude_md_path',
'claude_md_assembly.mode',
]);
/**
* Dynamic-pattern validators — keys matching these regexes are also accepted.
* Each entry has a `test` function and a human-readable `description`.
*/
const DYNAMIC_KEY_PATTERNS = [
{ test: (k) => /^agent_skills\.[a-zA-Z0-9_-]+$/.test(k), description: 'agent_skills.<agent-type>' },
{ test: (k) => /^review\.models\.[a-zA-Z0-9_-]+$/.test(k), description: 'review.models.<cli-name>' },
{ test: (k) => /^features\.[a-zA-Z0-9_]+$/.test(k), description: 'features.<feature_name>' },
{ test: (k) => /^claude_md_assembly\.blocks\.[a-zA-Z0-9_]+$/.test(k), description: 'claude_md_assembly.blocks.<section>' },
];
/**
* Returns true if keyPath is a valid config key (exact or dynamic pattern).
*/
function isValidConfigKey(keyPath) {
if (VALID_CONFIG_KEYS.has(keyPath)) return true;
return DYNAMIC_KEY_PATTERNS.some((p) => p.test(keyPath));
}
module.exports = { VALID_CONFIG_KEYS, DYNAMIC_KEY_PATTERNS, isValidConfigKey };

View File

@@ -10,64 +10,7 @@ const {
getAgentToModelMapForProfile,
formatAgentToModelMapAsTable,
} = require('./model-profiles.cjs');
const VALID_CONFIG_KEYS = new Set([
'mode', 'granularity', 'parallelization', 'commit_docs', 'model_profile',
'search_gitignored', 'brave_search', 'firecrawl', 'exa_search',
'workflow.research', 'workflow.plan_check', 'workflow.verifier',
'workflow.nyquist_validation', 'workflow.ai_integration_phase', 'workflow.ui_phase', 'workflow.ui_safety_gate',
'workflow.auto_advance', 'workflow.node_repair', 'workflow.node_repair_budget',
'workflow.tdd_mode',
'workflow.text_mode',
'workflow.research_before_questions',
'workflow.discuss_mode',
'workflow.skip_discuss',
'workflow.auto_prune_state',
'workflow._auto_chain_active',
'workflow.use_worktrees',
'workflow.code_review',
'workflow.code_review_depth',
'workflow.code_review_command',
'workflow.pattern_mapper',
'workflow.plan_bounce',
'workflow.plan_bounce_script',
'workflow.plan_bounce_passes',
'git.branching_strategy', 'git.base_branch', 'git.phase_branch_template', 'git.milestone_branch_template', 'git.quick_branch_template',
'planning.commit_docs', 'planning.search_gitignored',
'workflow.cross_ai_execution', 'workflow.cross_ai_command', 'workflow.cross_ai_timeout',
'workflow.subagent_timeout',
'workflow.inline_plan_threshold',
'hooks.context_warnings',
'features.thinking_partner',
'context',
'features.global_learnings',
'learnings.max_inject',
'project_code', 'phase_naming',
'manager.flags.discuss', 'manager.flags.plan', 'manager.flags.execute',
'response_language',
'intel.enabled',
'graphify.enabled',
'graphify.build_timeout',
'claude_md_path',
]);
/**
* Check whether a config key path is valid.
* Supports exact matches from VALID_CONFIG_KEYS plus dynamic patterns
* like `agent_skills.<agent-type>` where the sub-key is freeform.
*/
function isValidConfigKey(keyPath) {
if (VALID_CONFIG_KEYS.has(keyPath)) return true;
// Allow agent_skills.<agent-type> with any agent type string
if (/^agent_skills\.[a-zA-Z0-9_-]+$/.test(keyPath)) return true;
// Allow review.models.<cli-name> for per-CLI model selection in /gsd-review
if (/^review\.models\.[a-zA-Z0-9_-]+$/.test(keyPath)) return true;
// Allow features.<feature_name> — dynamic namespace for feature flags.
// Intentionally open-ended so new flags (e.g., features.global_learnings) work
// without updating VALID_CONFIG_KEYS each time.
if (/^features\.[a-zA-Z0-9_]+$/.test(keyPath)) return true;
return false;
}
const { VALID_CONFIG_KEYS, isValidConfigKey } = require('./config-schema.cjs');
const CONFIG_KEY_SUGGESTIONS = {
'workflow.nyquist_validation_enabled': 'workflow.nyquist_validation',
@@ -81,6 +24,8 @@ const CONFIG_KEY_SUGGESTIONS = {
'workflow.code_review_level': 'workflow.code_review_depth',
'workflow.review_depth': 'workflow.code_review_depth',
'review.model': 'review.models.<cli-name>',
'sub_repos': 'planning.sub_repos',
'plan_checker': 'workflow.plan_check',
};
function validateKnownConfigKeyPath(keyPath) {
@@ -96,7 +41,7 @@ function validateKnownConfigKeyPath(keyPath) {
* Merges (increasing priority):
* 1. Hardcoded defaults — every key that loadConfig() resolves, plus mode/granularity
* 2. User-level defaults from ~/.gsd/defaults.json (if present)
* 3. userChoices — the settings the user explicitly selected during /gsd-new-project
* 3. userChoices — the settings the user explicitly selected during /gsd:new-project
*
* Uses the canonical `git` namespace for branching keys (consistent with VALID_CONFIG_KEYS
* and the settings workflow). loadConfig() handles both flat and nested formats, so this
@@ -174,6 +119,9 @@ function buildNewProjectConfig(userChoices) {
plan_bounce_script: null,
plan_bounce_passes: 2,
auto_prune_state: false,
security_enforcement: CONFIG_DEFAULTS.security_enforcement,
security_asvs_level: CONFIG_DEFAULTS.security_asvs_level,
security_block_on: CONFIG_DEFAULTS.security_block_on,
},
hooks: {
context_warnings: true,
@@ -216,7 +164,7 @@ function buildNewProjectConfig(userChoices) {
* Command: create a fully-materialized .planning/config.json for a new project.
*
* Accepts user-chosen settings as a JSON string (the keys the user explicitly
* configured during /gsd-new-project). All remaining keys are filled from
* configured during /gsd:new-project). All remaining keys are filled from
* hardcoded defaults and optional ~/.gsd/defaults.json.
*
* Idempotent: if config.json already exists, returns { created: false }.

View File

@@ -263,6 +263,9 @@ const CONFIG_DEFAULTS = {
phase_naming: 'sequential', // 'sequential' (default, auto-increment) or 'custom' (arbitrary string IDs)
project_code: null, // optional short prefix for phase dirs (e.g., 'CK' → 'CK-01-foundation')
subagent_timeout: 300000, // 5 min default; increase for large codebases or slower models (ms)
security_enforcement: true, // workflow.security_enforcement — threat-model-anchored security verification via /gsd:secure-phase
security_asvs_level: 1, // workflow.security_asvs_level — OWASP ASVS verification level (1=opportunistic, 2=standard, 3=comprehensive)
security_block_on: 'high', // workflow.security_block_on — minimum severity that blocks phase advancement ('high' | 'medium' | 'low')
};
function loadConfig(cwd) {
@@ -391,6 +394,7 @@ function loadConfig(cwd) {
manager: parsed.manager || {},
response_language: get('response_language') || null,
claude_md_path: get('claude_md_path') || null,
claude_md_assembly: parsed.claude_md_assembly || null,
};
} catch {
// Fall back to ~/.gsd/defaults.json only for truly pre-project contexts (#1683)
@@ -1331,9 +1335,19 @@ function getRoadmapPhaseInternal(cwd, phaseNum) {
try {
const content = extractCurrentMilestone(fs.readFileSync(roadmapPath, 'utf-8'), cwd);
const escapedPhase = escapeRegex(phaseNum.toString());
// Match both numeric (Phase 1:) and custom (Phase PROJ-42:) headers
const phasePattern = new RegExp(`#{2,4}\\s*Phase\\s+${escapedPhase}:\\s*([^\\n]+)`, 'i');
// Strip leading zeros from purely numeric phase numbers so "03" matches "Phase 3:"
// in canonical ROADMAP headings. Non-numeric IDs (e.g. "PROJ-42") are kept as-is.
const normalized = /^\d+$/.test(String(phaseNum))
? String(phaseNum).replace(/^0+(?=\d)/, '')
: String(phaseNum);
const escapedPhase = escapeRegex(normalized);
// Match both numeric and custom (Phase PROJ-42:) headers.
// For purely numeric phases allow optional leading zeros so both "Phase 1:" and
// "Phase 01:" are matched regardless of whether the ROADMAP uses padded numbers.
const isNumeric = /^\d+$/.test(String(phaseNum));
const phasePattern = isNumeric
? new RegExp(`#{2,4}\\s*Phase\\s+0*${escapedPhase}:\\s*([^\\n]+)`, 'i')
: new RegExp(`#{2,4}\\s*Phase\\s+${escapedPhase}:\\s*([^\\n]+)`, 'i');
const headerMatch = content.match(phasePattern);
if (!headerMatch) return null;
@@ -1506,6 +1520,50 @@ function getMilestoneInfo(cwd) {
try {
const roadmap = fs.readFileSync(path.join(planningDir(cwd), 'ROADMAP.md'), 'utf-8');
// 0. Prefer STATE.md milestone: frontmatter as the authoritative source.
// This prevents falling through to a regex that may match an old heading
// when the active milestone's 🚧 marker is inside a <summary> tag without
// **bold** formatting (bug #2409).
let stateVersion = null;
if (cwd) {
try {
const statePath = path.join(planningDir(cwd), 'STATE.md');
if (fs.existsSync(statePath)) {
const stateRaw = fs.readFileSync(statePath, 'utf-8');
const m = stateRaw.match(/^milestone:\s*(.+)/m);
if (m) stateVersion = m[1].trim();
}
} catch { /* intentionally empty */ }
}
if (stateVersion) {
// Look up the name for this version in ROADMAP.md
const escapedVer = escapeRegex(stateVersion);
// Match heading-format: ## Roadmap v2.9: Name or ## v2.9 Name
const headingMatch = roadmap.match(
new RegExp(`##[^\\n]*${escapedVer}[:\\s]+([^\\n(]+)`, 'i')
);
if (headingMatch) {
// If the heading line contains ✅ the milestone is already shipped.
// Fall through to normal detection so the NEW active milestone is returned
// instead of the stale shipped one still recorded in STATE.md.
if (!headingMatch[0].includes('✅')) {
return { version: stateVersion, name: headingMatch[1].trim() };
}
// Shipped milestone — do not early-return; fall through to normal detection below.
} else {
// Match list-format: 🚧 **v2.9 Name** or 🚧 v2.9 Name
const listMatch = roadmap.match(
new RegExp(`🚧\\s*\\*?\\*?${escapedVer}\\s+([^*\\n]+)`, 'i')
);
if (listMatch) {
return { version: stateVersion, name: listMatch[1].trim() };
}
// Version found in STATE.md but no name match in ROADMAP — return bare version
return { version: stateVersion, name: 'milestone' };
}
}
// First: check for list-format roadmaps using 🚧 (in-progress) marker
// e.g. "- 🚧 **v2.1 Belgium** — Phases 24-28 (in progress)"
// e.g. "- 🚧 **v1.2.1 Tech Debt** — Phases 1-8 (in progress)"
@@ -1517,11 +1575,14 @@ function getMilestoneInfo(cwd) {
};
}
// Second: heading-format roadmaps — strip shipped milestones in <details> blocks
// Second: heading-format roadmaps — strip shipped milestones.
// <details> blocks are stripped by stripShippedMilestones; heading-format ✅ markers
// are excluded by the negative lookahead below so a stale STATE.md version (or any
// shipped ✅ heading) never wins over the first non-shipped milestone heading.
const cleaned = stripShippedMilestones(roadmap);
// Extract version and name from the same ## heading for consistency
// Negative lookahead skips headings that contain ✅ (shipped milestone marker).
// Supports 2+ segment versions: v1.2, v1.2.1, v2.0.1, etc.
const headingMatch = cleaned.match(/## .*v(\d+(?:\.\d+)+)[:\s]+([^\n(]+)/);
const headingMatch = cleaned.match(/## (?!.*✅).*v(\d+(?:\.\d+)+)[:\s]+([^\n(]+)/);
if (headingMatch) {
return {
version: 'v' + headingMatch[1],
@@ -1563,7 +1624,7 @@ function getMilestonePhaseFilter(cwd) {
}
const normalized = new Set(
[...milestonePhaseNums].map(n => (n.replace(/^0+/, '') || '0').toLowerCase())
[...milestonePhaseNums].map(n => (n.replace(/^0+(?=\d)/, '') || '0').toLowerCase())
);
function isDirInMilestone(dirName) {

View File

@@ -420,7 +420,7 @@ function buildPreview(gsd2Data, artifacts) {
lines.push('');
lines.push('Cannot migrate automatically:');
lines.push(' - GSD-2 cost/token ledger (no v1 equivalent)');
lines.push(' - GSD-2 database state (rebuilt from files on first /gsd-health)');
lines.push(' - GSD-2 database state (rebuilt from files on first /gsd:health)');
lines.push(' - VS Code extension state');
return lines.join('\n');

View File

@@ -458,8 +458,11 @@ function cmdInitNewMilestone(cwd, raw) {
try {
if (fs.existsSync(phasesDir)) {
// Bug #2445: filter phase dirs to current milestone only so stale dirs
// from a prior milestone that were not archived don't inflate the count.
const isDirInMilestone = getMilestonePhaseFilter(cwd);
phaseDirCount = fs.readdirSync(phasesDir, { withFileTypes: true })
.filter(entry => entry.isDirectory())
.filter(entry => entry.isDirectory() && isDirInMilestone(entry.name))
.length;
}
} catch {}
@@ -926,10 +929,10 @@ function cmdInitManager(cwd, raw) {
// Validate prerequisites
if (!fs.existsSync(paths.roadmap)) {
error('No ROADMAP.md found. Run /gsd-new-milestone first.');
error('No ROADMAP.md found. Run /gsd:new-milestone first.');
}
if (!fs.existsSync(paths.state)) {
error('No STATE.md found. Run /gsd-new-milestone first.');
error('No STATE.md found. Run /gsd:new-milestone first.');
}
const rawContent = fs.readFileSync(paths.roadmap, 'utf-8');
const content = extractCurrentMilestone(rawContent, cwd);
@@ -1108,7 +1111,7 @@ function cmdInitManager(cwd, raw) {
phase_name: phase.name,
action: 'execute',
reason: `${phase.plan_count} plans ready, dependencies met`,
command: `/gsd-execute-phase ${phase.number}`,
command: `/gsd:execute-phase ${phase.number}`,
});
} else if (phase.disk_status === 'discussed' || phase.disk_status === 'researched') {
recommendedActions.push({
@@ -1116,7 +1119,7 @@ function cmdInitManager(cwd, raw) {
phase_name: phase.name,
action: 'plan',
reason: 'Context gathered, ready for planning',
command: `/gsd-plan-phase ${phase.number}`,
command: `/gsd:plan-phase ${phase.number}`,
});
} else if ((phase.disk_status === 'empty' || phase.disk_status === 'no_directory') && phase.is_next_to_discuss) {
recommendedActions.push({
@@ -1124,7 +1127,7 @@ function cmdInitManager(cwd, raw) {
phase_name: phase.name,
action: 'discuss',
reason: 'Unblocked, ready to gather context',
command: `/gsd-discuss-phase ${phase.number}`,
command: `/gsd:discuss-phase ${phase.number}`,
});
}
}

View File

@@ -381,7 +381,7 @@ function cmdPhaseAdd(cwd, description, raw, customId) {
// Build phase entry
const dependsOn = config.phase_naming === 'custom' ? '' : `\n**Depends on:** Phase ${typeof _newPhaseId === 'number' ? _newPhaseId - 1 : 'TBD'}`;
const phaseEntry = `\n### Phase ${_newPhaseId}: ${description}\n\n**Goal:** [To be planned]\n**Requirements**: TBD${dependsOn}\n**Plans:** 0 plans\n\nPlans:\n- [ ] TBD (run /gsd-plan-phase ${_newPhaseId} to break down)\n`;
const phaseEntry = `\n### Phase ${_newPhaseId}: ${description}\n\n**Goal:** [To be planned]\n**Requirements**: TBD${dependsOn}\n**Plans:** 0 plans\n\nPlans:\n- [ ] TBD (run /gsd:plan-phase ${_newPhaseId} to break down)\n`;
// Find insertion point: before last "---" or at end
let updatedContent;
@@ -458,7 +458,7 @@ function cmdPhaseAddBatch(cwd, descriptions, raw) {
fs.mkdirSync(dirPath, { recursive: true });
fs.writeFileSync(path.join(dirPath, '.gitkeep'), '');
const dependsOn = config.phase_naming === 'custom' ? '' : `\n**Depends on:** Phase ${typeof newPhaseId === 'number' ? newPhaseId - 1 : 'TBD'}`;
const phaseEntry = `\n### Phase ${newPhaseId}: ${description}\n\n**Goal:** [To be planned]\n**Requirements**: TBD${dependsOn}\n**Plans:** 0 plans\n\nPlans:\n- [ ] TBD (run /gsd-plan-phase ${newPhaseId} to break down)\n`;
const phaseEntry = `\n### Phase ${newPhaseId}: ${description}\n\n**Goal:** [To be planned]\n**Requirements**: TBD${dependsOn}\n**Plans:** 0 plans\n\nPlans:\n- [ ] TBD (run /gsd:plan-phase ${newPhaseId} to break down)\n`;
const lastSeparator = rawContent.lastIndexOf('\n---');
rawContent = lastSeparator > 0
? rawContent.slice(0, lastSeparator) + phaseEntry + rawContent.slice(lastSeparator)
@@ -542,7 +542,7 @@ function cmdPhaseInsert(cwd, afterPhase, description, raw) {
fs.writeFileSync(path.join(dirPath, '.gitkeep'), '');
// Build phase entry
const phaseEntry = `\n### Phase ${_decimalPhase}: ${description} (INSERTED)\n\n**Goal:** [Urgent work - to be planned]\n**Requirements**: TBD\n**Depends on:** Phase ${afterPhase}\n**Plans:** 0 plans\n\nPlans:\n- [ ] TBD (run /gsd-plan-phase ${_decimalPhase} to break down)\n`;
const phaseEntry = `\n### Phase ${_decimalPhase}: ${description} (INSERTED)\n\n**Goal:** [Urgent work - to be planned]\n**Requirements**: TBD\n**Depends on:** Phase ${afterPhase}\n**Plans:** 0 plans\n\nPlans:\n- [ ] TBD (run /gsd:plan-phase ${_decimalPhase} to break down)\n`;
// Insert after the target phase section
const headerPattern = new RegExp(`(#{2,4}\\s*Phase\\s+0*${afterPhaseEscaped}:[^\\n]*\\n)`, 'i');
@@ -625,7 +625,7 @@ function renameIntegerPhases(phasesDir, removedInt) {
const m = dir.match(/^(\d+)([A-Z])?(?:\.(\d+))?-(.+)$/i);
if (!m) return null;
const dirInt = parseInt(m[1], 10);
return dirInt > removedInt ? { dir, oldInt: dirInt, letter: m[2] ? m[2].toUpperCase() : '', decimal: m[3] ? parseInt(m[3], 10) : null, slug: m[4] } : null;
return (dirInt > removedInt && dirInt < 999) ? { dir, oldInt: dirInt, letter: m[2] ? m[2].toUpperCase() : '', decimal: m[3] ? parseInt(m[3], 10) : null, slug: m[4] } : null;
})
.filter(Boolean)
.sort((a, b) => a.oldInt !== b.oldInt ? b.oldInt - a.oldInt : (b.decimal || 0) - (a.decimal || 0));
@@ -673,7 +673,7 @@ function updateRoadmapAfterPhaseRemoval(roadmapPath, targetPhase, isDecimal, rem
const oldPad = oldStr.padStart(2, '0'), newPad = newStr.padStart(2, '0');
content = content.replace(new RegExp(`(#{2,4}\\s*Phase\\s+)${oldStr}(\\s*:)`, 'gi'), `$1${newStr}$2`);
content = content.replace(new RegExp(`(Phase\\s+)${oldStr}([:\\s])`, 'g'), `$1${newStr}$2`);
content = content.replace(new RegExp(`${oldPad}-(\\d{2})`, 'g'), `${newPad}-$1`);
content = content.replace(new RegExp(`(?<![0-9-])${oldPad}-(\\d{2})(?![0-9-])`, 'g'), `${newPad}-$1`);
content = content.replace(new RegExp(`(\\|\\s*)${oldStr}\\.\\s`, 'g'), `$1${newStr}. `);
content = content.replace(new RegExp(`(Depends on:\\*\\*\\s*Phase\\s+)${oldStr}\\b`, 'gi'), `$1${newStr}`);
}
@@ -828,7 +828,7 @@ function cmdPhaseComplete(cwd, phaseNum, raw) {
// Update plan count in phase section.
// Use direct .replace() rather than replaceInCurrentMilestone() so this
// works when the current milestone section is itself inside a <details>
// block (the standard /gsd-new-project layout). replaceInCurrentMilestone
// block (the standard /gsd:new-project layout). replaceInCurrentMilestone
// scopes to content after the last </details>, which misses content inside
// the current milestone's own <details> wrapper (#2005).
// The phase-scoped heading pattern is specific enough to avoid matching
@@ -870,9 +870,10 @@ function cmdPhaseComplete(cwd, phaseNum, raw) {
const sectionText = phaseSectionMatch ? phaseSectionMatch[1] : '';
const reqMatch = sectionText.match(/\*\*Requirements:\*\*\s*([^\n]+)/i);
let reqContent = fs.readFileSync(reqPath, 'utf-8');
if (reqMatch) {
const reqIds = reqMatch[1].replace(/[\[\]]/g, '').split(/[,\s]+/).map(r => r.trim()).filter(Boolean);
let reqContent = fs.readFileSync(reqPath, 'utf-8');
for (const reqId of reqIds) {
const reqEscaped = escapeRegex(reqId);
@@ -887,10 +888,40 @@ function cmdPhaseComplete(cwd, phaseNum, raw) {
'$1 Complete $2'
);
}
atomicWriteFileSync(reqPath, reqContent);
requirementsUpdated = true;
}
// Scan body for all **REQ-ID** patterns, warn about any missing from the Traceability table.
// Always runs regardless of whether the roadmap has a Requirements: line.
const bodyReqIds = [];
const bodyReqPattern = /\*\*([A-Z][A-Z0-9]*-\d+)\*\*/g;
let bodyMatch;
while ((bodyMatch = bodyReqPattern.exec(reqContent)) !== null) {
const id = bodyMatch[1];
if (!bodyReqIds.includes(id)) bodyReqIds.push(id);
}
// Collect REQ-IDs present in the Traceability section only, to avoid
// picking up IDs from other tables in the document.
const traceabilityHeadingMatch = reqContent.match(/^#{1,6}\s+Traceability\b/im);
const traceabilitySection = traceabilityHeadingMatch
? reqContent.slice(traceabilityHeadingMatch.index)
: '';
const tableReqIds = new Set();
const tableRowPattern = /^\|\s*([A-Z][A-Z0-9]*-\d+)\s*\|/gm;
let tableMatch;
while ((tableMatch = tableRowPattern.exec(traceabilitySection)) !== null) {
tableReqIds.add(tableMatch[1]);
}
const unregistered = bodyReqIds.filter(id => !tableReqIds.has(id));
if (unregistered.length > 0) {
warnings.push(
`REQUIREMENTS.md: ${unregistered.length} REQ-ID(s) found in body but missing from Traceability table: ${unregistered.join(', ')} — add them manually to keep traceability in sync`
);
}
atomicWriteFileSync(reqPath, reqContent);
requirementsUpdated = true;
}
});
}

View File

@@ -173,7 +173,7 @@ const CLAUDE_INSTRUCTIONS = {
};
const CLAUDE_MD_FALLBACKS = {
project: 'Project not yet initialized. Run /gsd-new-project to set up.',
project: 'Project not yet initialized. Run /gsd:new-project to set up.',
stack: 'Technology stack not yet documented. Will populate after codebase mapping or first phase.',
conventions: 'Conventions not yet established. Will populate as patterns emerge during development.',
architecture: 'Architecture not yet mapped. Follow existing patterns found in the codebase.',
@@ -187,9 +187,9 @@ const CLAUDE_MD_WORKFLOW_ENFORCEMENT = [
'Before using Edit, Write, or other file-changing tools, start work through a GSD command so planning artifacts and execution context stay in sync.',
'',
'Use these entry points:',
'- `/gsd-quick` for small fixes, doc updates, and ad-hoc tasks',
'- `/gsd-debug` for investigation and bug fixing',
'- `/gsd-execute-phase` for planned phase work',
'- `/gsd:quick` for small fixes, doc updates, and ad-hoc tasks',
'- `/gsd:debug` for investigation and bug fixing',
'- `/gsd:execute-phase` for planned phase work',
'',
'Do not make direct repo edits outside a GSD workflow unless the user explicitly asks to bypass it.',
].join('\n');
@@ -198,7 +198,7 @@ const CLAUDE_MD_PROFILE_PLACEHOLDER = [
'<!-- GSD:profile-start -->',
'## Developer Profile',
'',
'> Profile not yet configured. Run `/gsd-profile-user` to generate your developer profile.',
'> Profile not yet configured. Run `/gsd:profile-user` to generate your developer profile.',
'> This section is managed by `generate-claude-profile` -- do not edit manually.',
'<!-- GSD:profile-end -->',
].join('\n');
@@ -285,7 +285,7 @@ function generateProjectSection(cwd) {
const projectPath = path.join(cwd, '.planning', 'PROJECT.md');
const content = safeReadFile(projectPath);
if (!content) {
return { content: CLAUDE_MD_FALLBACKS.project, source: 'PROJECT.md', hasFallback: true };
return { content: CLAUDE_MD_FALLBACKS.project, source: 'PROJECT.md', linkPath: null, hasFallback: true };
}
const parts = [];
const h1Match = content.match(/^# (.+)$/m);
@@ -306,9 +306,9 @@ function generateProjectSection(cwd) {
if (body) parts.push(`### Constraints\n\n${body}`);
}
if (parts.length === 0) {
return { content: CLAUDE_MD_FALLBACKS.project, source: 'PROJECT.md', hasFallback: true };
return { content: CLAUDE_MD_FALLBACKS.project, source: 'PROJECT.md', linkPath: null, hasFallback: true };
}
return { content: parts.join('\n\n'), source: 'PROJECT.md', hasFallback: false };
return { content: parts.join('\n\n'), source: 'PROJECT.md', linkPath: '.planning/PROJECT.md', hasFallback: false };
}
function generateStackSection(cwd) {
@@ -316,12 +316,14 @@ function generateStackSection(cwd) {
const researchPath = path.join(cwd, '.planning', 'research', 'STACK.md');
let content = safeReadFile(codebasePath);
let source = 'codebase/STACK.md';
let linkPath = '.planning/codebase/STACK.md';
if (!content) {
content = safeReadFile(researchPath);
source = 'research/STACK.md';
linkPath = '.planning/research/STACK.md';
}
if (!content) {
return { content: CLAUDE_MD_FALLBACKS.stack, source: 'STACK.md', hasFallback: true };
return { content: CLAUDE_MD_FALLBACKS.stack, source: 'STACK.md', linkPath: null, hasFallback: true };
}
const lines = content.split('\n');
const summaryLines = [];
@@ -336,14 +338,14 @@ function generateStackSection(cwd) {
if (line.startsWith('- ') || line.startsWith('* ')) summaryLines.push(line);
}
const summary = summaryLines.length > 0 ? summaryLines.join('\n') : content.trim();
return { content: summary, source, hasFallback: false };
return { content: summary, source, linkPath, hasFallback: false };
}
function generateConventionsSection(cwd) {
const conventionsPath = path.join(cwd, '.planning', 'codebase', 'CONVENTIONS.md');
const content = safeReadFile(conventionsPath);
if (!content) {
return { content: CLAUDE_MD_FALLBACKS.conventions, source: 'CONVENTIONS.md', hasFallback: true };
return { content: CLAUDE_MD_FALLBACKS.conventions, source: 'CONVENTIONS.md', linkPath: null, hasFallback: true };
}
const lines = content.split('\n');
const summaryLines = [];
@@ -352,14 +354,14 @@ function generateConventionsSection(cwd) {
if (line.startsWith('- ') || line.startsWith('* ') || line.startsWith('|')) summaryLines.push(line);
}
const summary = summaryLines.length > 0 ? summaryLines.join('\n') : content.trim();
return { content: summary, source: 'CONVENTIONS.md', hasFallback: false };
return { content: summary, source: 'CONVENTIONS.md', linkPath: '.planning/codebase/CONVENTIONS.md', hasFallback: false };
}
function generateArchitectureSection(cwd) {
const architecturePath = path.join(cwd, '.planning', 'codebase', 'ARCHITECTURE.md');
const content = safeReadFile(architecturePath);
if (!content) {
return { content: CLAUDE_MD_FALLBACKS.architecture, source: 'ARCHITECTURE.md', hasFallback: true };
return { content: CLAUDE_MD_FALLBACKS.architecture, source: 'ARCHITECTURE.md', linkPath: null, hasFallback: true };
}
const lines = content.split('\n');
const summaryLines = [];
@@ -368,13 +370,14 @@ function generateArchitectureSection(cwd) {
if (line.startsWith('- ') || line.startsWith('* ') || line.startsWith('|') || line.startsWith('```')) summaryLines.push(line);
}
const summary = summaryLines.length > 0 ? summaryLines.join('\n') : content.trim();
return { content: summary, source: 'ARCHITECTURE.md', hasFallback: false };
return { content: summary, source: 'ARCHITECTURE.md', linkPath: '.planning/codebase/ARCHITECTURE.md', hasFallback: false };
}
function generateWorkflowSection() {
return {
content: CLAUDE_MD_WORKFLOW_ENFORCEMENT,
source: 'GSD defaults',
linkPath: null,
hasFallback: false,
};
}
@@ -765,7 +768,7 @@ function cmdGenerateDevPreferences(cwd, options, raw) {
let stackBlock;
if (analysis.data_source === 'questionnaire') {
stackBlock = 'Stack preferences not available (questionnaire-only profile). Run `/gsd-profile-user --refresh` with session data to populate.';
stackBlock = 'Stack preferences not available (questionnaire-only profile). Run `/gsd:profile-user --refresh` with session data to populate.';
} else if (options.stack) {
stackBlock = options.stack;
} else {
@@ -851,7 +854,7 @@ function cmdGenerateClaudeProfile(cwd, options, raw) {
'<!-- GSD:profile-start -->',
'## Developer Profile',
'',
`> Generated by GSD from ${dataSource}. Run \`/gsd-profile-user --refresh\` to update.`,
`> Generated by GSD from ${dataSource}. Run \`/gsd:profile-user --refresh\` to update.`,
'',
'| Dimension | Rating | Confidence |',
'|-----------|--------|------------|',
@@ -948,19 +951,35 @@ function cmdGenerateClaudeMd(cwd, options, raw) {
}
}
let assemblyConfig = {};
let configClaudeMdPath = './CLAUDE.md';
try {
const config = loadConfig(cwd);
if (config.claude_md_path) configClaudeMdPath = config.claude_md_path;
if (config.claude_md_assembly) assemblyConfig = config.claude_md_assembly;
} catch { /* use default */ }
let outputPath = options.output;
if (!outputPath) {
// Read claude_md_path from config, default to ./CLAUDE.md
let configClaudeMdPath = './CLAUDE.md';
try {
const config = loadConfig(cwd);
if (config.claude_md_path) configClaudeMdPath = config.claude_md_path;
} catch { /* use default */ }
outputPath = path.isAbsolute(configClaudeMdPath) ? configClaudeMdPath : path.join(cwd, configClaudeMdPath);
} else if (!path.isAbsolute(outputPath)) {
outputPath = path.join(cwd, outputPath);
}
const globalAssemblyMode = assemblyConfig.mode || 'embed';
const blockModes = assemblyConfig.blocks || {};
// Return the assembled content for a section, respecting link vs embed mode.
// "link" mode writes `@<linkPath>` when the generator has a real source file.
// Falls back to "embed" for sections without a linkable source (workflow, fallbacks).
function buildSectionContent(name, gen, heading) {
const effectiveMode = blockModes[name] || globalAssemblyMode;
if (effectiveMode === 'link' && gen.linkPath && !gen.hasFallback) {
return buildSection(name, gen.source, `${heading}\n\n@${gen.linkPath}`);
}
return buildSection(name, gen.source, `${heading}\n\n${gen.content}`);
}
let existingContent = safeReadFile(outputPath);
let action;
@@ -969,8 +988,7 @@ function cmdGenerateClaudeMd(cwd, options, raw) {
for (const name of MANAGED_SECTIONS) {
const gen = generated[name];
const heading = sectionHeadings[name];
const body = `${heading}\n\n${gen.content}`;
sections.push(buildSection(name, gen.source, body));
sections.push(buildSectionContent(name, gen, heading));
}
sections.push('');
sections.push(CLAUDE_MD_PROFILE_PLACEHOLDER);
@@ -985,13 +1003,15 @@ function cmdGenerateClaudeMd(cwd, options, raw) {
for (const name of MANAGED_SECTIONS) {
const gen = generated[name];
const heading = sectionHeadings[name];
const body = `${heading}\n\n${gen.content}`;
const fullSection = buildSection(name, gen.source, body);
const fullSection = buildSectionContent(name, gen, heading);
const hasMarkers = fileContent.indexOf(`<!-- GSD:${name}-start`) !== -1;
if (hasMarkers) {
if (options.auto) {
const expectedBody = `${heading}\n\n${gen.content}`;
const effectiveMode = blockModes[name] || globalAssemblyMode;
const expectedBody = (effectiveMode === 'link' && gen.linkPath && !gen.hasFallback)
? `${heading}\n\n@${gen.linkPath}`
: `${heading}\n\n${gen.content}`;
if (detectManualEdit(fileContent, name, expectedBody)) {
sectionsSkipped.push(name);
const genIdx = sectionsGenerated.indexOf(name);
@@ -1033,7 +1053,7 @@ function cmdGenerateClaudeMd(cwd, options, raw) {
let message = `Generated ${genCount}/${totalManaged} sections.`;
if (sectionsFallback.length > 0) message += ` Fallback: ${sectionsFallback.join(', ')}.`;
if (sectionsSkipped.length > 0) message += ` Skipped (manually edited): ${sectionsSkipped.join(', ')}.`;
if (profileStatus === 'placeholder_added') message += ' Run /gsd-profile-user to unlock Developer Profile.';
if (profileStatus === 'placeholder_added') message += ' Run /gsd:profile-user to unlock Developer Profile.';
const result = {
claude_md_path: outputPath,

View File

@@ -353,8 +353,171 @@ function cmdRoadmapUpdatePlanProgress(cwd, phaseNum, raw) {
}, raw, `${summaryCount}/${planCount} ${status}`);
}
/**
* Annotate the ROADMAP.md plan list for a phase with wave dependency notes
* and a cross-cutting constraints subsection derived from PLAN frontmatter.
*
* Wave dependency notes: "Wave 2 — blocked on Wave 1 completion" inserted as
* bold headers before each wave group in the plan checklist.
*
* Cross-cutting constraints: must_haves.truths strings that appear in 2+ plans
* are surfaced in a "Cross-cutting constraints" subsection below the plan list.
*
* The operation is idempotent: if wave headers already exist in the section
* the function returns without modifying the file.
*/
function cmdRoadmapAnnotateDependencies(cwd, phaseNum, raw) {
if (!phaseNum) {
error('phase number required for roadmap annotate-dependencies');
}
const roadmapPath = planningPaths(cwd).roadmap;
if (!fs.existsSync(roadmapPath)) {
output({ updated: false, reason: 'ROADMAP.md not found' }, raw, 'no roadmap');
return;
}
const phaseInfo = findPhaseInternal(cwd, phaseNum);
if (!phaseInfo || phaseInfo.plans.length === 0) {
output({ updated: false, reason: 'no plans found for phase', phase: phaseNum }, raw, 'no plans');
return;
}
const { extractFrontmatter, parseMustHavesBlock } = require('./frontmatter.cjs');
// Read each PLAN.md and extract wave + must_haves.truths
const planData = [];
for (const planFile of phaseInfo.plans) {
const planPath = path.join(path.resolve(cwd, phaseInfo.directory), planFile);
try {
const content = fs.readFileSync(planPath, 'utf-8');
const fm = extractFrontmatter(content);
const wave = parseInt(fm.wave, 10) || 1;
const planId = planFile.replace(/-PLAN\.md$/i, '').replace(/PLAN\.md$/i, '');
const truths = parseMustHavesBlock(content, 'truths') || [];
planData.push({ planFile, planId, wave, truths });
} catch { /* skip unreadable plans */ }
}
if (planData.length === 0) {
output({ updated: false, reason: 'could not read plan frontmatter' }, raw, 'no frontmatter');
return;
}
// Group plans by wave (sorted)
const waveGroups = new Map();
for (const p of planData) {
if (!waveGroups.has(p.wave)) waveGroups.set(p.wave, []);
waveGroups.get(p.wave).push(p);
}
const waves = [...waveGroups.keys()].sort((a, b) => a - b);
// Find cross-cutting truths: appear in 2+ plans (de-duplicated, case-insensitive)
const truthCounts = new Map();
for (const { truths } of planData) {
const seen = new Set();
for (const t of truths) {
const key = t.trim().toLowerCase();
if (!key || seen.has(key)) continue;
seen.add(key);
truthCounts.set(key, (truthCounts.get(key) || { count: 0, text: t.trim() }));
truthCounts.get(key).count++;
}
}
const crossCuttingTruths = [...truthCounts.values()]
.filter(v => v.count >= 2)
.map(v => v.text);
// Patch ROADMAP.md
let updated = false;
withPlanningLock(cwd, () => {
let content = fs.readFileSync(roadmapPath, 'utf-8');
// Find the phase section
const phaseEscaped = escapeRegex(phaseNum);
const phaseHeaderPattern = new RegExp(`(#{2,4}\\s*Phase\\s+${phaseEscaped}:[^\\n]*)`, 'i');
const phaseMatch = content.match(phaseHeaderPattern);
if (!phaseMatch) return;
const phaseStart = phaseMatch.index;
const restAfterHeader = content.slice(phaseStart);
const nextPhaseOffset = restAfterHeader.slice(1).search(/\n#{2,4}\s+Phase\s+\d/i);
const phaseEnd = nextPhaseOffset >= 0 ? phaseStart + 1 + nextPhaseOffset : content.length;
const phaseSection = content.slice(phaseStart, phaseEnd);
// Idempotency: skip if annotation markers already present
if (
/\*\*Wave\s+\d+/i.test(phaseSection) ||
/\*\*Cross-cutting constraints:\*\*/i.test(phaseSection)
) return;
// Find the Plans: section within the phase section
const plansBlockMatch = phaseSection.match(/(Plans:\s*\n)((?:\s*-\s*\[[ x]\][^\n]*\n?)*)/i);
if (!plansBlockMatch) return;
const plansHeader = plansBlockMatch[1];
const existingList = plansBlockMatch[2];
const listLines = existingList.split('\n').filter(l => /^\s*-\s*\[/.test(l));
if (listLines.length === 0) return;
// Build wave-annotated plan list
const linesByWave = new Map();
for (const line of listLines) {
// Match plan ID from line: "- [ ] 01-01-PLAN.md — ..." or "- [ ] 01-01: ..."
const idMatch = line.match(/\[\s*[x ]\s*\]\s*([\w-]+?)(?:-PLAN\.md|\.md|:|\s—)/i);
const planId = idMatch ? idMatch[1] : null;
const planEntry = planId ? planData.find(p => p.planId === planId) : null;
const wave = planEntry ? planEntry.wave : 1;
if (!linesByWave.has(wave)) linesByWave.set(wave, []);
linesByWave.get(wave).push(line);
}
const annotatedLines = [];
const sortedWaves = [...linesByWave.keys()].sort((a, b) => a - b);
for (let i = 0; i < sortedWaves.length; i++) {
const w = sortedWaves[i];
const waveLines = linesByWave.get(w);
if (sortedWaves.length > 1) {
const dep = i > 0 ? ` *(blocked on Wave ${sortedWaves[i - 1]} completion)*` : '';
annotatedLines.push(`**Wave ${w}**${dep}`);
}
annotatedLines.push(...waveLines);
if (i < sortedWaves.length - 1) annotatedLines.push('');
}
// Append cross-cutting constraints subsection if any found
if (crossCuttingTruths.length > 0) {
annotatedLines.push('');
annotatedLines.push('**Cross-cutting constraints:**');
for (const t of crossCuttingTruths) {
annotatedLines.push(`- ${t}`);
}
}
const newListBlock = annotatedLines.join('\n') + '\n';
const newPhaseSection = phaseSection.replace(
plansBlockMatch[0],
plansHeader + newListBlock
);
const nextContent = content.slice(0, phaseStart) + newPhaseSection + content.slice(phaseEnd);
if (nextContent === content) return;
atomicWriteFileSync(roadmapPath, nextContent);
updated = true;
});
output({
updated,
phase: phaseNum,
waves: waves.length,
cross_cutting_constraints: crossCuttingTruths.length,
}, raw, updated ? `annotated ${waves.length} wave(s), ${crossCuttingTruths.length} constraint(s)` : 'skipped (already annotated or no plan list)');
}
module.exports = {
cmdRoadmapGetPhase,
cmdRoadmapAnalyze,
cmdRoadmapUpdatePlanProgress,
cmdRoadmapAnnotateDependencies,
};

View File

@@ -141,7 +141,7 @@ const INJECTION_PATTERNS = [
// Requires > to close the tag (not just whitespace) to avoid matching generic types like Promise<User | null>
/<\/?(?:system|assistant|human)>/i,
/\[SYSTEM\]/i,
/\[INST\]/i,
/\[\/?(INST)\]/i,
/<<\s*SYS\s*>>/i,
// Exfiltration attempts
@@ -163,7 +163,7 @@ const OBFUSCATION_PATTERN_ENTRIES = [
},
{
pattern: /<\/?(system|human|assistant|user)\s*>/i,
message: 'Delimiter injection pattern: <system>/<assistant>/<user> tag detected',
message: 'Delimiter injection pattern: <system>/<human>/<assistant>/<user> tag detected',
},
{
pattern: /0x[0-9a-fA-F]{16,}/,
@@ -245,14 +245,15 @@ function sanitizeForPrompt(text) {
// Neutralize XML/HTML tags that mimic system boundaries
// Replace < > with full-width equivalents to prevent tag interpretation
// Note: <instructions> is excluded — GSD uses it as legitimate prompt structure
sanitized = sanitized.replace(/<(\/?)(?:system|assistant|human)>/gi,
// Matches system|assistant|human|user with optional whitespace before the closing >
sanitized = sanitized.replace(/<(\/?)\s*(?:system|assistant|human|user)\s*>/gi,
(_, slash) => `${slash || ''}system-text`);
// Neutralize [SYSTEM] / [INST] markers
sanitized = sanitized.replace(/\[(SYSTEM|INST)\]/gi, '[$1-TEXT]');
// Neutralize [SYSTEM] / [INST] / [/INST] markers — both opening and closing variants
sanitized = sanitized.replace(/\[(\/?)(SYSTEM|INST)\]/gi, (_, slash, tag) => `[${slash}${tag.toUpperCase()}-TEXT]`);
// Neutralize <<SYS>> markers
sanitized = sanitized.replace(/<<\s*SYS\s*>>/gi, '«SYS-TEXT»');
// Neutralize <<SYS>> and <</SYS>> markers (Llama-style delimiters)
sanitized = sanitized.replace(/<<\/?\s*SYS\s*>>/gi, '«SYS-TEXT»');
return sanitized;
}

View File

@@ -29,12 +29,13 @@ process.on('exit', () => {
// Shared helper: extract a field value from STATE.md content.
// Supports both **Field:** bold and plain Field: format.
// Horizontal whitespace only after ':' so YAML keys like `progress:` do not match as `Progress:` (parity with sdk/helpers stateExtractField).
function stateExtractField(content, fieldName) {
const escaped = escapeRegex(fieldName);
const boldPattern = new RegExp(`\\*\\*${escaped}:\\*\\*\\s*(.+)`, 'i');
const boldPattern = new RegExp(`\\*\\*${escaped}:\\*\\*[ \\t]*(.+)`, 'i');
const boldMatch = content.match(boldPattern);
if (boldMatch) return boldMatch[1].trim();
const plainPattern = new RegExp(`^${escaped}:\\s*(.+)`, 'im');
const plainPattern = new RegExp(`^${escaped}:[ \\t]*(.+)`, 'im');
const plainMatch = content.match(plainPattern);
return plainMatch ? plainMatch[1].trim() : null;
}
@@ -720,7 +721,13 @@ function buildStateFrontmatter(bodyContent, cwd) {
const status = stateExtractField(bodyContent, 'Status');
const progressRaw = stateExtractField(bodyContent, 'Progress');
const lastActivity = stateExtractField(bodyContent, 'Last Activity');
const stoppedAt = stateExtractField(bodyContent, 'Stopped At') || stateExtractField(bodyContent, 'Stopped at');
// Bug #2444: scope Stopped At extraction to the ## Session section so that
// historical "Stopped at:" prose elsewhere in the body (e.g. in a
// Session Continuity Archive section) never overwrites the current value.
// Fall back to full-body search only when no ## Session section exists.
const sessionSectionMatch = bodyContent.match(/##\s*Session\s*\n([\s\S]*?)(?=\n##|$)/i);
const sessionBodyScope = sessionSectionMatch ? sessionSectionMatch[1] : bodyContent;
const stoppedAt = stateExtractField(sessionBodyScope, 'Stopped At') || stateExtractField(sessionBodyScope, 'Stopped at');
const pausedAt = stateExtractField(bodyContent, 'Paused At');
let milestone = null;
@@ -747,9 +754,33 @@ function buildStateFrontmatter(bodyContent, cwd) {
let cached = _diskScanCache.get(cwd);
if (!cached) {
const isDirInMilestone = getMilestonePhaseFilter(cwd);
const phaseDirs = fs.readdirSync(phasesDir, { withFileTypes: true })
const allMatchingDirs = fs.readdirSync(phasesDir, { withFileTypes: true })
.filter(e => e.isDirectory()).map(e => e.name)
.filter(isDirInMilestone);
// Bug #2445: when stale phase dirs from a prior milestone remain in
// .planning/phases/ alongside new dirs with the same phase number,
// de-duplicate by normalized phase number keeping the most recently
// modified dir. This prevents double-counting (e.g. two "Phase 1" dirs).
const seenPhaseNums = new Map(); // normalizedNum -> dirName
for (const dir of allMatchingDirs) {
const m = dir.match(/^0*(\d+[A-Za-z]?(?:\.\d+)*)/);
const key = m ? m[1].toLowerCase() : dir;
if (!seenPhaseNums.has(key)) {
seenPhaseNums.set(key, dir);
} else {
// Keep the dir that is newer on disk (more likely current milestone)
try {
const existing = path.join(phasesDir, seenPhaseNums.get(key));
const candidate = path.join(phasesDir, dir);
if (fs.statSync(candidate).mtimeMs > fs.statSync(existing).mtimeMs) {
seenPhaseNums.set(key, dir);
}
} catch { /* keep existing on stat error */ }
}
}
const phaseDirs = [...seenPhaseNums.values()];
let diskTotalPlans = 0;
let diskTotalSummaries = 0;
let diskCompletedPhases = 0;

View File

@@ -225,6 +225,11 @@ function parseVerificationItems(content, status) {
const numberedMatch = line.match(/^(\d+)\.\s+(.+)/);
if (tableMatch) {
// Skip rows that already have a passing result (PASS, pass, resolved, etc.)
const rowRemainder = line.slice(tableMatch.index + tableMatch[0].length);
const cellValues = rowRemainder.split('|').map(c => c.trim());
const hasPassResult = cellValues.some(c => /^pass$/i.test(c) || /^resolved$/i.test(c));
if (hasPassResult) continue;
items.push({
test: parseInt(tableMatch[1], 10),
name: tableMatch[2].trim(),

View File

@@ -555,7 +555,7 @@ function cmdValidateHealth(cwd, options, raw) {
// ─── Check 1: .planning/ exists ───────────────────────────────────────────
if (!fs.existsSync(planBase)) {
addIssue('error', 'E001', '.planning/ directory not found', 'Run /gsd-new-project to initialize');
addIssue('error', 'E001', '.planning/ directory not found', 'Run /gsd:new-project to initialize');
output({
status: 'broken',
errors,
@@ -568,7 +568,7 @@ function cmdValidateHealth(cwd, options, raw) {
// ─── Check 2: PROJECT.md exists and has required sections ─────────────────
if (!fs.existsSync(projectPath)) {
addIssue('error', 'E002', 'PROJECT.md not found', 'Run /gsd-new-project to create');
addIssue('error', 'E002', 'PROJECT.md not found', 'Run /gsd:new-project to create');
} else {
const content = fs.readFileSync(projectPath, 'utf-8');
const requiredSections = ['## What This Is', '## Core Value', '## Requirements'];
@@ -581,12 +581,12 @@ function cmdValidateHealth(cwd, options, raw) {
// ─── Check 3: ROADMAP.md exists ───────────────────────────────────────────
if (!fs.existsSync(roadmapPath)) {
addIssue('error', 'E003', 'ROADMAP.md not found', 'Run /gsd-new-milestone to create roadmap');
addIssue('error', 'E003', 'ROADMAP.md not found', 'Run /gsd:new-milestone to create roadmap');
}
// ─── Check 4: STATE.md exists and references valid phases ─────────────────
if (!fs.existsSync(statePath)) {
addIssue('error', 'E004', 'STATE.md not found', 'Run /gsd-health --repair to regenerate', true);
addIssue('error', 'E004', 'STATE.md not found', 'Run /gsd:health --repair to regenerate', true);
repairs.push('regenerateState');
} else {
const stateContent = fs.readFileSync(statePath, 'utf-8');
@@ -613,7 +613,7 @@ function cmdValidateHealth(cwd, options, raw) {
'warning',
'W002',
`STATE.md references phase ${ref}, but only phases ${[...diskPhases].sort().join(', ')} exist`,
'Review STATE.md manually before changing it; /gsd-health --repair will not overwrite an existing STATE.md for phase mismatches'
'Review STATE.md manually before changing it; /gsd:health --repair will not overwrite an existing STATE.md for phase mismatches'
);
}
}
@@ -622,7 +622,7 @@ function cmdValidateHealth(cwd, options, raw) {
// ─── Check 5: config.json valid JSON + valid schema ───────────────────────
if (!fs.existsSync(configPath)) {
addIssue('warning', 'W003', 'config.json not found', 'Run /gsd-health --repair to create with defaults', true);
addIssue('warning', 'W003', 'config.json not found', 'Run /gsd:health --repair to create with defaults', true);
repairs.push('createConfig');
} else {
try {
@@ -634,7 +634,7 @@ function cmdValidateHealth(cwd, options, raw) {
addIssue('warning', 'W004', `config.json: invalid model_profile "${parsed.model_profile}"`, `Valid values: ${validProfiles.join(', ')}`);
}
} catch (err) {
addIssue('error', 'E005', `config.json: JSON parse error - ${err.message}`, 'Run /gsd-health --repair to reset to defaults', true);
addIssue('error', 'E005', `config.json: JSON parse error - ${err.message}`, 'Run /gsd:health --repair to reset to defaults', true);
repairs.push('resetConfig');
}
}
@@ -645,11 +645,11 @@ function cmdValidateHealth(cwd, options, raw) {
const configRaw = fs.readFileSync(configPath, 'utf-8');
const configParsed = JSON.parse(configRaw);
if (configParsed.workflow && configParsed.workflow.nyquist_validation === undefined) {
addIssue('warning', 'W008', 'config.json: workflow.nyquist_validation absent (defaults to enabled but agents may skip)', 'Run /gsd-health --repair to add key', true);
addIssue('warning', 'W008', 'config.json: workflow.nyquist_validation absent (defaults to enabled but agents may skip)', 'Run /gsd:health --repair to add key', true);
if (!repairs.includes('addNyquistKey')) repairs.push('addNyquistKey');
}
if (configParsed.workflow && configParsed.workflow.ai_integration_phase === undefined) {
addIssue('warning', 'W016', 'config.json: workflow.ai_integration_phase absent (defaults to enabled — run /gsd-ai-integration-phase before planning AI system phases)', 'Run /gsd-health --repair to add key', true);
addIssue('warning', 'W016', 'config.json: workflow.ai_integration_phase absent (defaults to enabled — run /gsd:ai-integration-phase before planning AI system phases)', 'Run /gsd:health --repair to add key', true);
if (!repairs.includes('addAiIntegrationPhaseKey')) repairs.push('addAiIntegrationPhaseKey');
}
} catch { /* intentionally empty */ }
@@ -699,7 +699,7 @@ function cmdValidateHealth(cwd, options, raw) {
try {
const researchContent = fs.readFileSync(path.join(phasesDir, e.name, researchFile), 'utf-8');
if (researchContent.includes('## Validation Architecture')) {
addIssue('warning', 'W009', `Phase ${e.name}: has Validation Architecture in RESEARCH.md but no VALIDATION.md`, 'Re-run /gsd-plan-phase with --research to regenerate');
addIssue('warning', 'W009', `Phase ${e.name}: has Validation Architecture in RESEARCH.md but no VALIDATION.md`, 'Re-run /gsd:plan-phase with --research to regenerate');
}
} catch { /* intentionally empty */ }
}
@@ -792,7 +792,7 @@ function cmdValidateHealth(cwd, options, raw) {
if (statusVal !== 'complete' && statusVal !== 'done') {
addIssue('warning', 'W011',
`STATE.md says current phase is ${statePhase} (status: ${statusVal || 'unknown'}) but ROADMAP.md shows it as [x] complete — state files may be out of sync`,
'Run /gsd-progress to re-derive current position, or manually update STATE.md');
'Run /gsd:progress to re-derive current position, or manually update STATE.md');
}
}
}
@@ -871,6 +871,54 @@ function cmdValidateHealth(cwd, options, raw) {
}
} catch { /* git worktree not available or not a git repo — skip silently */ }
// ─── Check 12: MILESTONES.md / archive snapshot drift (#2446) ─────────────
const milestonesPath = path.join(planBase, 'MILESTONES.md');
const milestonesArchiveDir = path.join(planBase, 'milestones');
const missingFromRegistry = [];
try {
if (fs.existsSync(milestonesArchiveDir)) {
const archiveFiles = fs.readdirSync(milestonesArchiveDir);
const archivedVersions = archiveFiles
.map(f => f.match(/^(v\d+\.\d+(?:\.\d+)?)-ROADMAP\.md$/))
.filter(Boolean)
.map(m => m[1]);
if (archivedVersions.length > 0) {
const registryContent = fs.existsSync(milestonesPath)
? fs.readFileSync(milestonesPath, 'utf-8')
: '';
for (const ver of archivedVersions) {
if (!registryContent.includes(`## ${ver}`)) {
missingFromRegistry.push(ver);
}
}
if (missingFromRegistry.length > 0) {
addIssue('warning', 'W018',
`MILESTONES.md missing ${missingFromRegistry.length} archived milestone(s): ${missingFromRegistry.join(', ')}`,
'Run /gsd:health --backfill to synthesize missing entries from archive snapshots',
true);
repairs.push('backfillMilestones');
}
}
}
} catch { /* intentionally empty — milestone sync check is advisory */ }
// ─── Check 13: Unrecognized .planning/ root files (W019) ──────────────────
try {
const { isCanonicalPlanningFile } = require('./artifacts.cjs');
const entries = fs.readdirSync(planBase, { withFileTypes: true });
for (const entry of entries) {
if (!entry.isFile()) continue;
if (!entry.name.endsWith('.md')) continue;
if (!isCanonicalPlanningFile(entry.name)) {
addIssue('warning', 'W019',
`Unrecognized .planning/ file: ${entry.name} — not a canonical GSD artifact`,
'Move to .planning/milestones/ archive subdir or delete if stale. See templates/README.md for the canonical artifact list.',
false);
}
}
} catch { /* artifact check is advisory — skip on error */ }
// ─── Perform repairs if requested ─────────────────────────────────────────
const repairActions = [];
if (options.repair && repairs.length > 0) {
@@ -921,7 +969,7 @@ function cmdValidateHealth(cwd, options, raw) {
stateContent += `**Current phase:** (determining...)\n`;
stateContent += `**Status:** Resuming\n\n`;
stateContent += `## Session Log\n\n`;
stateContent += `- ${new Date().toISOString().split('T')[0]}: STATE.md regenerated by /gsd-health --repair\n`;
stateContent += `- ${new Date().toISOString().split('T')[0]}: STATE.md regenerated by /gsd:health --repair\n`;
writeStateMd(statePath, stateContent, cwd);
repairActions.push({ action: repair, success: true, path: 'STATE.md' });
break;
@@ -960,6 +1008,39 @@ function cmdValidateHealth(cwd, options, raw) {
}
break;
}
case 'backfillMilestones': {
if (!options.backfill && !options.repair) break;
const today = new Date().toISOString().split('T')[0];
let backfilled = 0;
for (const ver of missingFromRegistry) {
try {
const snapshotPath = path.join(milestonesArchiveDir, `${ver}-ROADMAP.md`);
const snapshot = fs.existsSync(snapshotPath) ? fs.readFileSync(snapshotPath, 'utf-8') : null;
// Build minimal entry from snapshot title or version
const titleMatch = snapshot && snapshot.match(/^#\s+(.+)$/m);
const milestoneName = titleMatch ? titleMatch[1].replace(/^Milestone\s+/i, '').replace(/^v[\d.]+\s*/, '').trim() : ver;
const entry = `## ${ver}${milestoneName && milestoneName !== ver ? ` ${milestoneName}` : ''} (Backfilled: ${today})\n\n**Note:** Synthesized from archive snapshot by \`/gsd:health --backfill\`. Original completion date unknown.\n\n---\n\n`;
const milestonesContent = fs.existsSync(milestonesPath)
? fs.readFileSync(milestonesPath, 'utf-8')
: '';
if (!milestonesContent.trim()) {
fs.writeFileSync(milestonesPath, `# Milestones\n\n${entry}`, 'utf-8');
} else {
const headerMatch = milestonesContent.match(/^(#{1,3}\s+[^\n]*\n\n?)/);
if (headerMatch) {
const header = headerMatch[1];
const rest = milestonesContent.slice(header.length);
fs.writeFileSync(milestonesPath, header + entry + rest, 'utf-8');
} else {
fs.writeFileSync(milestonesPath, entry + milestonesContent, 'utf-8');
}
}
backfilled++;
} catch { /* intentionally empty — partial backfill is acceptable */ }
}
repairActions.push({ action: repair, success: true, detail: `Backfilled ${backfilled} milestone(s) into MILESTONES.md` });
break;
}
}
} catch (err) {
repairActions.push({ action: repair, success: false, error: err.message });
@@ -980,14 +1061,16 @@ function cmdValidateHealth(cwd, options, raw) {
const repairableCount = errors.filter(e => e.repairable).length +
warnings.filter(w => w.repairable).length;
output({
const result = {
status,
errors,
warnings,
info,
repairable_count: repairableCount,
repairs_performed: repairActions.length > 0 ? repairActions : undefined,
}, raw);
};
output(result, raw);
return result;
}
/**

View File

@@ -78,7 +78,7 @@ function cmdWorkstreamCreate(cwd, name, options, raw) {
const baseDir = planningRoot(cwd);
if (!fs.existsSync(baseDir)) {
error('.planning/ directory not found — run /gsd-new-project first');
error('.planning/ directory not found — run /gsd:new-project first');
}
const wsRoot = path.join(baseDir, 'workstreams');

View File

@@ -72,21 +72,21 @@ reads is inert — the consumption mechanism is what gives an artifact meaning.
- **Location**: `.planning/spikes/SPIKE-NNN/`
- **Consumed by**: Planner when spike is referenced; `pause-work` for spike context handoff
### Spike README.md / MANIFEST.md (per-spike, via /gsd-spike)
### Spike README.md / MANIFEST.md (per-spike, via /gsd:spike)
- **Shape**: YAML frontmatter (spike, name, validates, verdict, related, tags) + run instructions + results
- **Lifecycle**: Created by `/gsd-spike` → Verified → Wrapped up by `/gsd-spike-wrap-up`
- **Lifecycle**: Created by `/gsd:spike` → Verified → Wrapped up by `/gsd:spike-wrap-up`
- **Location**: `.planning/spikes/NNN-name/README.md`, `.planning/spikes/MANIFEST.md`
- **Consumed by**: `/gsd-spike-wrap-up` for curation; `pause-work` for spike context handoff
- **Consumed by**: `/gsd:spike-wrap-up` for curation; `pause-work` for spike context handoff
### Sketch README.md / MANIFEST.md / index.html (per-sketch)
- **Shape**: YAML frontmatter (sketch, name, question, winner, tags) + variants as tabbed HTML
- **Lifecycle**: Created by `/gsd-sketch` → Evaluated → Wrapped up by `/gsd-sketch-wrap-up`
- **Lifecycle**: Created by `/gsd:sketch` → Evaluated → Wrapped up by `/gsd:sketch-wrap-up`
- **Location**: `.planning/sketches/NNN-name/README.md`, `.planning/sketches/NNN-name/index.html`, `.planning/sketches/MANIFEST.md`
- **Consumed by**: `/gsd-sketch-wrap-up` for curation; `pause-work` for sketch context handoff
- **Consumed by**: `/gsd:sketch-wrap-up` for curation; `pause-work` for sketch context handoff
### WRAP-UP-SUMMARY.md (per wrap-up session)
- **Shape**: Curation results, included/excluded items, feature/design area groupings
- **Lifecycle**: Created by `/gsd-spike-wrap-up` or `/gsd-sketch-wrap-up`
- **Lifecycle**: Created by `/gsd:spike-wrap-up` or `/gsd:sketch-wrap-up`
- **Location**: `.planning/spikes/WRAP-UP-SUMMARY.md` or `.planning/sketches/WRAP-UP-SUMMARY.md`
- **Consumed by**: Project history; not read by automated workflows

View File

@@ -12,7 +12,7 @@ Every workflow that spawns agents or reads significant content must follow these
1. **Never** read agent definition files (`agents/*.md`) -- `subagent_type` auto-loads them
2. **Never** inline large files into subagent prompts -- tell agents to read files from disk instead
3. **Read depth scales with context window** -- check `context_window_tokens` in `.planning/config.json`:
3. **Read depth scales with context window** -- check `context_window` in `.planning/config.json`:
- At < 500000 tokens (default 200k): read only frontmatter, status fields, or summaries. Never read full SUMMARY.md, VERIFICATION.md, or RESEARCH.md bodies.
- At >= 500000 tokens (1M model): MAY read full subagent output bodies when the content is needed for inline presentation or decision-making. Still avoid unnecessary reads.
4. **Delegate** heavy work to subagents -- the orchestrator routes, it doesn't execute
@@ -25,7 +25,7 @@ Every workflow that spawns agents or reads significant content must follow these
| < 500k (200k model) | Frontmatter only | Frontmatter only | Frontmatter only | Current phase only |
| >= 500k (1M model) | Full body permitted | Full body permitted | Full body permitted | Current phase only |
**How to check:** Read `.planning/config.json` and inspect `context_window_tokens`. If the field is absent, treat as 200k (conservative default).
**How to check:** Read `.planning/config.json` and inspect `context_window`. If the field is absent, treat as 200k (conservative default).
## Context Degradation Tiers

View File

@@ -50,13 +50,13 @@ Standard format for presenting next steps after completing a command or workflow
`/clear` then:
`/gsd-execute-phase 2`
`/gsd:execute-phase 2`
---
**Also available:**
- Review plan before executing
- `/gsd-list-phase-assumptions 2` — check assumptions
- `/gsd:list-phase-assumptions 2` — check assumptions
---
```
@@ -75,7 +75,7 @@ Add note that this is the last plan and what comes after:
`/clear` then:
`/gsd-execute-phase 2`
`/gsd:execute-phase 2`
---
@@ -97,13 +97,13 @@ Add note that this is the last plan and what comes after:
`/clear` then:
`/gsd-plan-phase 2`
`/gsd:plan-phase 2`
---
**Also available:**
- `/gsd-discuss-phase 2` — gather context first
- `/gsd-research-phase 2` — investigate unknowns
- `/gsd:discuss-phase 2` — gather context first
- `/gsd:research-phase 2` — investigate unknowns
- Review roadmap
---
@@ -126,13 +126,13 @@ Show completion status before next action:
`/clear` then:
`/gsd-plan-phase 3`
`/gsd:plan-phase 3`
---
**Also available:**
- `/gsd-discuss-phase 3` — gather context first
- `/gsd-research-phase 3` — investigate unknowns
- `/gsd:discuss-phase 3` — gather context first
- `/gsd:research-phase 3` — investigate unknowns
- Review what Phase 2 built
---
@@ -151,11 +151,11 @@ When there's no clear primary action:
`/clear` then one of:
**To plan directly:** `/gsd-plan-phase 3`
**To plan directly:** `/gsd:plan-phase 3`
**To discuss context first:** `/gsd-discuss-phase 3`
**To discuss context first:** `/gsd:discuss-phase 3`
**To research unknowns:** `/gsd-research-phase 3`
**To research unknowns:** `/gsd:research-phase 3`
---
```
@@ -175,7 +175,7 @@ All 4 phases shipped
`/clear` then:
`/gsd-new-milestone`
`/gsd:new-milestone`
---
```
@@ -218,7 +218,7 @@ Extract: `**02-03: Refresh Token Rotation** — Add /api/auth/refresh with slidi
## To Continue
Run `/clear`, then paste:
/gsd-execute-phase 2
/gsd:execute-phase 2
```
User has no idea what 02-03 is about.
@@ -226,7 +226,7 @@ User has no idea what 02-03 is about.
### Don't: Missing /clear explanation
```
`/gsd-plan-phase 3`
`/gsd:plan-phase 3`
Run /clear first.
```
@@ -246,7 +246,7 @@ Sounds like an afterthought. Use "Also available:" instead.
```
```
/gsd-plan-phase 3
/gsd:plan-phase 3
```
```

View File

@@ -1,6 +1,6 @@
# Doc Conflict Engine
Shared conflict-detection contract for workflows that ingest external content into `.planning/` (e.g., `/gsd-import`, `/gsd-ingest-docs`). Defines the report format, severity semantics, and safety-gate behavior. The specific checks that populate each severity bucket are workflow-specific and defined by the calling workflow.
Shared conflict-detection contract for workflows that ingest external content into `.planning/` (e.g., `/gsd:import`, `/gsd:ingest-docs`). Defines the report format, severity semantics, and safety-gate behavior. The specific checks that populate each severity bucket are workflow-specific and defined by the calling workflow.
---

View File

@@ -1,6 +1,6 @@
# Domain-Aware Probing Patterns
Shared reference for `/gsd-begin`, `/gsd-discuss-phase`, and domain exploration workflows.
Shared reference for `/gsd-begin`, `/gsd:discuss-phase`, and domain exploration workflows.
When the user mentions a technology area, use these probes to ask insightful follow-up questions. Don't run through them as a checklist -- pick the 2-3 most relevant based on context. The goal is to surface hidden assumptions and trade-offs the user may not have considered yet.

View File

@@ -47,7 +47,7 @@ Simple 2-option confirmation for re-planning, rebuild, replace plans, commit.
4-option escalation for review escalation (max retries exceeded).
- question: "Phase {N} has failed verification {attempt} times. How should we proceed?"
- header: "Escalate"
- options: Accept gaps | Re-plan (via /gsd-plan-phase) | Debug (via /gsd-debug) | Retry
- options: Accept gaps | Re-plan (via /gsd:plan-phase) | Debug (via /gsd:debug) | Retry
## Pattern: multi-option-gaps
4-option gap handler for review gaps-found.
@@ -78,7 +78,7 @@ Up to 4 suggested next actions with selection (status, resume workflows).
3-option confirmation for quick task scope validation.
- question: "This task looks complex. Proceed as quick task or use full planning?"
- header: "Scope"
- options: Quick task | Full plan (via /gsd-plan-phase) | Revise
- options: Quick task | Full plan (via /gsd:plan-phase) | Revise
## Pattern: depth-select
3-option depth selection for planning workflow preferences.

View File

@@ -38,7 +38,7 @@ Canonical gate types used across GSD workflows. Every validation checkpoint maps
**Recovery:** Developer investigates root cause, fixes, restarts from checkpoint.
**Examples:**
- Context window critically low during execution
- STATE.md in error state blocking /gsd-next
- STATE.md in error state blocking /gsd:next
- Verification finds critical missing deliverables
---

View File

@@ -274,7 +274,7 @@ Set `commit_docs: false` so planning docs stay local and are not committed to an
### How It Works
1. **Auto-detection:** During `/gsd-new-project`, directories with their own `.git` folder are detected and offered for selection as sub-repos. On subsequent runs, `loadConfig` auto-syncs the `sub_repos` list with the filesystem — adding newly created repos and removing deleted ones. This means `config.json` may be rewritten automatically when repos change on disk.
1. **Auto-detection:** During `/gsd:new-project`, directories with their own `.git` folder are detected and offered for selection as sub-repos. On subsequent runs, `loadConfig` auto-syncs the `sub_repos` list with the filesystem — adding newly created repos and removing deleted ones. This means `config.json` may be rewritten automatically when repos change on disk.
2. **File grouping:** Code files are grouped by their sub-repo prefix (e.g., `backend/src/api/users.ts` belongs to the `backend/` repo).
3. **Independent commits:** Each sub-repo receives its own atomic commit via `gsd-tools.cjs commit-to-subrepo`. File paths are made relative to the sub-repo root before staging.
4. **Planning stays local:** The `.planning/` directory is not committed; it acts as cross-repo coordination.

View File

@@ -75,7 +75,7 @@ If you're using Claude Code with OpenRouter, a local model, or any non-Anthropic
```bash
# Via settings command
/gsd-settings
/gsd:settings
# → Select "Inherit" for model profile
# Or manually in .planning/config.json
@@ -115,7 +115,7 @@ Overrides take precedence over the profile. Valid values: `opus`, `sonnet`, `hai
## Switching Profiles
Runtime: `/gsd-set-profile <profile>`
Runtime: `/gsd:set-profile <profile>`
Per-project default: Set in `.planning/config.json`:
```json

View File

@@ -0,0 +1,49 @@
# Chunked Mode Return Formats
Used when `plan-phase` spawns `gsd-planner` with `CHUNKED_MODE=true` (triggered by `--chunked`
flag or `workflow.plan_chunked: true` config). Splits the single long-lived planner Task into
shorter-lived Tasks to bound the blast radius of Windows stdio hangs.
## Modes
### outline-only
Write **only** `{PHASE_DIR}/{PADDED_PHASE}-PLAN-OUTLINE.md`. Do not write any PLAN.md files.
Return:
```markdown
## OUTLINE COMPLETE
**Phase:** {phase-name}
**Plans:** {N} plan(s) in {M} wave(s)
| Plan ID | Objective | Wave | Depends On | Requirements |
|---------|-----------|------|-----------|-------------|
| {padded_phase}-01 | [brief objective] | 1 | none | REQ-001, REQ-002 |
| {padded_phase}-02 | [brief objective] | 1 | none | REQ-003 |
```
The orchestrator reads this table, then spawns one single-plan Task per row.
### single-plan
Write **exactly one** `{PHASE_DIR}/{plan_id}-PLAN.md`. Do not write any other plan files.
Return:
```markdown
## PLAN COMPLETE
**Plan:** {plan-id}
**Objective:** {brief}
**File:** {PHASE_DIR}/{plan-id}-PLAN.md
**Tasks:** {N}
```
The orchestrator verifies the file exists on disk after each return, commits it, then moves
to the next plan entry from the outline.
## Resume Behaviour
If the orchestrator detects that `PLAN-OUTLINE.md` already exists (from a prior interrupted
run), it skips the outline-only Task and goes directly to single-plan Tasks, skipping any
`{plan_id}-PLAN.md` files that already exist on disk.

View File

@@ -36,7 +36,7 @@ Configuration options for `.planning/` directory behavior.
| `workflow.use_worktrees` | `true` | Whether executor agents run in isolated git worktrees. Set to `false` to disable worktrees — agents execute sequentially on the main working tree instead. Recommended for solo developers or when worktree merges cause issues. |
| `workflow.subagent_timeout` | `300000` | Timeout in milliseconds for parallel subagent tasks (e.g. codebase mapping). Increase for large codebases or slower models. Default: 300000 (5 minutes). |
| `workflow.inline_plan_threshold` | `2` | Plans with this many tasks or fewer execute inline (Pattern C) instead of spawning a subagent. Avoids ~14K token spawn overhead for small plans. Set to `0` to always spawn subagents. |
| `manager.flags.discuss` | `""` | Flags passed to `/gsd-discuss-phase` when dispatched from manager (e.g. `"--auto --analyze"`) |
| `manager.flags.discuss` | `""` | Flags passed to `/gsd:discuss-phase` when dispatched from manager (e.g. `"--auto --analyze"`) |
| `manager.flags.plan` | `""` | Flags passed to plan workflow when dispatched from manager |
| `manager.flags.execute` | `""` | Flags passed to execute workflow when dispatched from manager |
| `response_language` | `null` | Language for user-facing questions and prompts across all phases/subagents (e.g. `"Portuguese"`, `"Japanese"`, `"Spanish"`). When set, all spawned agents include a directive to respond in this language. |
@@ -54,7 +54,7 @@ Configuration options for `.planning/` directory behavior.
- User must add `.planning/` to `.gitignore`
- Useful for: OSS contributions, client projects, keeping planning private
**Using gsd-tools.cjs (preferred):**
**Using `gsd-sdk query` (preferred):**
```bash
# Commit with automatic commit_docs + gitignore checks:
@@ -236,7 +236,7 @@ Generated from `CONFIG_DEFAULTS` (core.cjs) and `VALID_CONFIG_KEYS` (config.cjs)
| `context_window` | number | `200000` | `200000`, `1000000` | Context window size; set `1000000` for 1M-context models |
| `resolve_model_ids` | boolean\|string | `false` | `false`, `true`, `"omit"` | Map model aliases to full Claude IDs; `"omit"` returns empty string |
| `context` | string\|null | `null` | `"dev"`, `"research"`, `"review"` | Execution context profile that adjusts agent behavior: `"dev"` for development tasks, `"research"` for investigation/exploration, `"review"` for code review workflows |
| `review.models.<cli>` | string\|null | `null` | Any model ID string | Per-CLI model override for /gsd-review (e.g., `review.models.gemini`). Falls back to CLI default when null. |
| `review.models.<cli>` | string\|null | `null` | Any model ID string | Per-CLI model override for /gsd:review (e.g., `review.models.gemini`). Falls back to CLI default when null. |
### Workflow Fields
@@ -252,7 +252,7 @@ Set via `workflow.*` namespace in config.json (e.g., `"workflow": { "research":
| `workflow.auto_advance` | boolean | `false` | `true`, `false` | Auto-advance to next phase after completion |
| `workflow.node_repair` | boolean | `true` | `true`, `false` | Attempt automatic repair of failed plan nodes |
| `workflow.node_repair_budget` | number | `2` | Any positive integer | Max repair retries per failed node |
| `workflow.ai_integration_phase` | boolean | `true` | `true`, `false` | Run /gsd-ai-integration-phase before planning AI system phases |
| `workflow.ai_integration_phase` | boolean | `true` | `true`, `false` | Run /gsd:ai-integration-phase before planning AI system phases |
| `workflow.ui_phase` | boolean | `true` | `true`, `false` | Generate UI-SPEC.md for frontend phases |
| `workflow.ui_safety_gate` | boolean | `true` | `true`, `false` | Require safety gate approval for UI changes |
| `workflow.text_mode` | boolean | `false` | `true`, `false` | Use plain-text numbered lists instead of AskUserQuestion menus |
@@ -265,6 +265,9 @@ Set via `workflow.*` namespace in config.json (e.g., `"workflow": { "research":
| `workflow.code_review` | boolean | `true` | `true`, `false` | Enable built-in code review step in the ship workflow |
| `workflow.code_review_depth` | string | `"standard"` | `"light"`, `"standard"`, `"deep"` | Depth level for code review analysis in the ship workflow |
| `workflow._auto_chain_active` | boolean | `false` | `true`, `false` | Internal: tracks whether autonomous chaining is active |
| `workflow.security_enforcement` | boolean | `true` | `true`, `false` | Enable threat-model-anchored security verification via `/gsd:secure-phase`. When `false`, security checks are skipped entirely |
| `workflow.security_asvs_level` | number | `1` | `1`, `2`, `3` | OWASP ASVS verification level. Level 1 = opportunistic, Level 2 = standard, Level 3 = comprehensive |
| `workflow.security_block_on` | string | `"high"` | `"high"`, `"medium"`, `"low"` | Minimum severity that blocks phase advancement |
### Git Fields
@@ -315,11 +318,11 @@ Set via `learnings.*` namespace (e.g., `"learnings": { "max_inject": 5 }`). Used
### Intel Fields
Set via `intel.*` namespace (e.g., `"intel": { "enabled": true }`). Controls the queryable codebase intelligence system consumed by `/gsd-intel`.
Set via `intel.*` namespace (e.g., `"intel": { "enabled": true }`). Controls the queryable codebase intelligence system consumed by `/gsd:intel`.
| Key | Type | Default | Allowed Values | Description |
|-----|------|---------|----------------|-------------|
| `intel.enabled` | boolean | `false` | `true`, `false` | Enable queryable codebase intelligence system. When `true`, `/gsd-intel` commands build and query a JSON index in `.planning/intel/`. |
| `intel.enabled` | boolean | `false` | `true`, `false` | Enable queryable codebase intelligence system. When `true`, `/gsd:intel` commands build and query a JSON index in `.planning/intel/`. |
### Manager Fields
@@ -327,7 +330,7 @@ Set via `manager.*` namespace (e.g., `"manager": { "flags": { "discuss": "--auto
| Key | Type | Default | Allowed Values | Description |
|-----|------|---------|----------------|-------------|
| `manager.flags.discuss` | string | `""` | Any CLI flags string | Flags passed to `/gsd-discuss-phase` from manager (e.g., `"--auto --analyze"`) |
| `manager.flags.discuss` | string | `""` | Any CLI flags string | Flags passed to `/gsd:discuss-phase` from manager (e.g., `"--auto --analyze"`) |
| `manager.flags.plan` | string | `""` | Any CLI flags string | Flags passed to plan workflow from manager |
| `manager.flags.execute` | string | `""` | Any CLI flags string | Flags passed to execute workflow from manager |

View File

@@ -69,7 +69,7 @@ Apply this recommendation to the revision? [Yes] / [No, let me decide]
### 3. Explore — Approach Comparison (requires #1729)
**When:** During Socratic conversation, when multiple viable approaches emerge.
**Note:** This integration point will be added when /gsd-explore (#1729) lands.
**Note:** This integration point will be added when /gsd:explore (#1729) lands.
---

Some files were not shown because too many files have changed in this diff Show More