a33cbe72f569e75e72d94de85d0930296d1ca1df
93 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
8bc255c266 |
fix(workstream): normalize migration workstream names (#3269)
* fix(workstream): normalize migrate-name to valid slug * docs(context): record workstream migrate-name slug invariant * fix(catalog-cjs): balanced fallback for unknown profile (CR finding A) profiles[profile] could return undefined for any profile key absent from the catalog entry, causing downstream callers like formatAgentToModelMapAsTable to crash on .length. Add ?? profiles.balanced fallback to match the SDK adapter. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test(sdk): anchor path resolution on import.meta.url not cwd (CR finding B) resolve(process.cwd(), '..') breaks when Vitest is invoked from the repo root because cwd is already the repo root and '..' goes one level above. Replace with a file-relative path using fileURLToPath(new URL('../../../', import.meta.url)) anchored at the test file's location (sdk/src/query/). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test: derive Group B runtime list from catalog (CR finding C) Hardcoded ['kilo', 'cline', ...] throws TypeError if a runtime name is removed from the catalog. Derive group B dynamically via Object.keys(catalog.runtimeTierDefaults).filter(r => !r.opus) so the test never goes stale and auto-covers future Group B additions. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs(workflow): add hermes to Step B runtime options (CR finding D) hermes appears in the Group A built-in defaults table but was missing from the AskUserQuestion options in Step B, forcing users to manually type it via 'Other (Group B or custom)'. Add explicit hermes entry for UI consistency. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs(config): refresh dynamic_routing tier table; fix stale L671 (findings E+F) Finding E: tier table was missing 6 heavy-tier agents and 15 standard/light agents added by this PR. Updated all three rows to match catalog routingTier assignments (33 agents total). Finding F: removed stale '18 of 31' claim and agent enumeration; replaced with accurate note that all 33 agents have explicit catalog entries. Updated authoritative source pointers to model-catalog.cjs / model-catalog.ts. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test(core): add profile-fallback unit tests for quality and budget (CR nitpick G) The PR introduced quality→opus and budget→haiku unknown-agent fallbacks but only balanced→sonnet and inherit→inherit were tested. Add two tests covering the remaining two branches to complete coverage. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * adr: define planning workspace and worktree seam * refactor(worktree): extract worktree safety policy module * refactor(workstream): extract active workstream pointer store seam * test(worktree): cover policy branch paths and persist seam guardrails * refactor(worktree): centralize health inventory seam for W017 * fix(workspace): align SDK project path policy with CJS planningDir * refactor(query): unify SDK planning path projection seam * refactor(init): route workspace projection through planningPaths seam * docs(adr): add SDK architecture and planning path ADRs * refactor(worktree): deepen name, pointer, inventory, and config seams * docs(config): harmonize claude-opus-4-6 to 4-7 in resolve_model_ids example (CR finding 2) * fix(sdk): return undefined for model_profile='inherit' sentinel (CR finding 3) * docs(adr): renumber conflicting 0003-sdk-package-seam-module to 0007, update seam-map reference (CR finding 4) * fix(workstream): align CJS and SDK name validation to accept dots, guard path traversal via includes('..') (CR finding 5) * fix(sdk): guard writeActiveWorkstream against non-existent workstream directory, k014/k031 parity (CR finding 6) * chore(changeset): add #3269 changeset (CR finding 1 — proper changeset for this PR) * docs(inventory): register 3 new CLI modules in INVENTORY.md/MANIFEST (active-workstream-store, workstream-name-policy, worktree-safety) * fix(sdk): use relPlanningPath(workstream) in planningPaths, fix setActiveWorkstream/getActiveWorkstream name errors in workstream.ts * fix(sdk): validate GSD_WORKSTREAM in planningPaths before use (#3269 regression) planningPaths() called resolveWorkspaceContext() which returned GSD_WORKSTREAM raw (no validation). An invalid value like '../evil' was used as effectiveWorkstream, constructing a bad path; roadmapAnalyze() caught the ENOENT and returned a no-phase_count error object instead of the root ROADMAP result. Fix: validate envCtx.workstream with validateWorkstreamName() in planningPaths() before accepting it as effectiveWorkstream. Invalid env → null → root .planning/ fallback, preserving the bug-2791 contract: invalid GSD_WORKSTREAM is silently ignored and falls back to the root context (phase_count: 0 for empty root ROADMAP). The bug-2791 regression test now passes. No other call sites read GSD_WORKSTREAM without validation: query-runtime-context.ts already validates; cli.ts already validates; context-engine.ts takes a caller-validated workstream parameter. Closes #3268 (regression introduced by #3269 workstream-name-policy work). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
97bde8615f |
fix(cjs): accept dotted canonical command form (#3243) (#3248)
* test: reproduce CJS dispatcher rejecting dotted form (#3243) runGsdTools assertions confirm that generate-slug.hello-world, current-timestamp.date, validate.plan, roadmap.analyze, phases.list, and check.decision-coverage-plan all fail with "Unknown command: <dotted>" — the dispatcher switch only accepts the spaced form. Edge cases (no dots unchanged, leading-dot rejected, unknown dotted form suggests spaced equivalent) are also specified; those three pass already because the shim is not yet implemented. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(cjs): accept dotted canonical command form (#3243) Add a shim at the top of main() in gsd-tools.cjs that splits args[0] on the first dot when present, normalizing "state.update" → command='state' args=['state','update',...] before the switch statement is reached. Any caller that bypasses the SDK (stale npm-installed binary, workflow shell-out, third-party script) can now use the canonical dotted form natively without hitting "Unknown command: <domain>.<subcommand>". The shim guards against empty head/rest so ".hidden" and bare "." args are unchanged and fall through to the existing "Unknown command" path. Also improves the default "Unknown command" error message to suggest the spaced equivalent when a dotted form was passed — e.g. for "foo.bar" the error now reads: Unknown command: foo — did you mean: "foo bar"? Parallel to dottedCommandToCjsArgv in sdk/src/query/query-fallback-bridge-adapter.ts; intentionally kept separate to avoid SDK coupling. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * changeset: pr=3248 for #3243 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test: tighten dotted-form suggestion assertion (CR nitpick) * fix(cjs): suggestion uses first-dot split (CR finding 1, multi-dot consistency) The "did you mean" hint in the Unknown-command default case was replacing ALL dots with spaces (state.update.foo → "state update foo"), but the dispatcher shim only splits on the FIRST dot (state.update.foo → head=state, rest=update.foo). Apply CR's exact patch to use indexOf+slice so suggestion matches dispatch behavior. Add a multi-dot regression test (a.b.c must suggest "a b.c", not "a b c"). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
e3b64b39f8 |
fix(#3019): query --help reaches handler instead of short-circuiting (#3026)
* fix(#3019): query --help reaches handler instead of short-circuiting to top-level usage The query argv parser in sdk/src/cli.ts harvested -h/--help as a global flag and main() short-circuited dispatch when args.help was true. Net effect: every `gsd-sdk query <anything> --help` printed top-level USAGE instead of contextual subcommand help. There was no path for users to discover what arguments a query subcommand accepts — they had to trigger "required" errors by trial and error. Two-layer fix: 1. sdk/src/cli.ts (parseCliArgsQueryPermissive) - Push -h / --help onto queryArgv instead of consuming them silently, so the registered handler / gsd-tools.cjs fallback gets to interpret the flag and render contextual help. - Only honor the global help flag when there is NO real subcommand to dispatch to (i.e. queryArgv contains only help flags). Preserves `gsd-sdk query --help` → top-level USAGE while letting `gsd-sdk query phase add --help` reach the handler. 2. get-shit-done/bin/gsd-tools.cjs - Render top-level usage on --help / -h / -? / --usage instead of erroring with "Unknown flag". The discovery hint in the usage text points users at the working method (run without args → error names required arguments) and references #3019 for tracking subcommand- level help printers. - --version remains rejected (no discovery use-case). #1818 anti-hallucination invariant preserved: the destructive command NEVER executes when --help is present. The new shape returns success:true + usage on stdout instead of the old success:false + error on stderr — both satisfy "destructive command did not run", and the new shape also restores discoverability. Tests: - sdk/src/cli.test.ts: 4 new vitest cases covering #3019 — query argv parser keeps --help with subcommand, parses -h short flag, preserves bare `query --help` top-level behavior, preserves --help position when intermixed with other query flags. - tests/bug-3019-help-passthrough.test.cjs: 5 node:test cases on the fallback — bare gsd-tools (no args) errors with usage; --help renders usage on stdout exit 0; -h same; subcommand --help renders usage; usage hint mentions discovery method (without prose substring matching — parses into typed sections). - tests/bug-1818-unknown-flags.test.cjs: rewritten to assert the new invariant ("destructive command did not run" + "usage was rendered") instead of the old shape ("--help is rejected with non-zero exit"). Each destructive test seeds a sentinel artifact (phase dir, slug output) and asserts it survives. Verification: - 47/47 vitest pass on sdk/src/cli.test.ts - 5/5 pass on tests/bug-3019-help-passthrough.test.cjs - 8/8 pass on tests/bug-1818-unknown-flags.test.cjs (rewritten) - 6763/6763 pass on full node:test suite - lint-no-source-grep clean (0 violations) Closes #3019 * fix(#3019): SDK fallback forwards plain-text help, broader usage list (CR) CodeRabbit on PR #3026 (4 findings — 1 Major outside-diff, 2 inline, 1 nitpick): 1. **Major outside-diff** — sdk/src/cli.ts:442-454. The fallback path that delegates to gsd-tools.cjs called parseCliQueryJsonOutput (JSON.parse) on stdout. Now that gsd-tools renders plain-text usage on --help, JSON.parse threw "Unexpected token 'U'". Wrapped the parse in try/catch — on parse failure, forward the plain stdout verbatim so subcommand help reaches the user. Regression test: tests/bug-3019-help-passthrough.test.cjs spawns the built SDK and asserts `gsd-sdk query phase --help` exits 0, stdout contains the gsd-tools usage, and stderr does NOT contain a JSON-parse error. 2. .changeset/help-passthrough.md:3 — `pr: TBD` → `pr: 3026`. 3. gsd-tools.cjs:346 (TOP_LEVEL_USAGE): - Removed self-referencing `#3019` link (immediately stale after this PR merges). - Expanded Commands list from 17 → all 47 dispatcher cases: agent-skills, audit-open, audit-uat, check-commit, commit, … phase, phases, roadmap, milestone, validate, progress, intel, graphify, learnings, etc. — the bulk of the surface that was previously unreachable via --help discovery. 4. Nitpick: `isUsageOutput` was duplicated in bug-1818 and bug-3019-help-passthrough tests. Moved to tests/helpers.cjs with structural-comment, removed both duplicates. Verification: 47/47 vitest pass, 14/14 regression tests pass, 6764/6764 full suite, lint clean. * test(#3019): use t.skip() instead of bare return when SDK not built (CR) CodeRabbit follow-up on PR #3026: The integration test guarded against missing sdk/dist/cli.js with a bare `return;` — node:test counts that as a passing test (0 assertions exercised, 0 failures). On a CI checkout that hasn't run the SDK build, the #3026 regression test silently green-lit and no signal ever surfaced that the integration check was skipped. Switched to `t.skip(...)` via the test context parameter so the omission shows up in the test report. The unit-level fix (sdk/src/cli.ts) is still covered by vitest, so the skip only affects the end-to-end spawn-built-SDK check. Verification: 6/6 pass when SDK is built; 5 pass + 1 skip when not. |
||
|
|
f55069ecbf |
test(#2974): migrate 8 test files to typed-IR assertions (#3016)
* test(#2974): migrate 8 test files to typed-IR assertions Replaces raw stdout/stderr substring matching with structured-field assertions per CONTRIBUTING.md "Prohibited: Raw Text Matching on Test Outputs". Adds shared infrastructure for typed error emission so this pattern is the easy path going forward. Shared infrastructure: - core.cjs: ERROR_REASON frozen enum + setJsonErrorMode/getJsonErrorMode - gsd-tools.cjs: --json-errors CLI flag, parsed before subcommand dispatch - config.cjs: typed reasons at all 7 error sites - graphify.cjs: GRAPHIFY_REASON enum + reason/timeout_ms in execGraphify result - bin/install.js: pure buildSdkFailFastReport() IR builder + renderer - hooks/gsd-session-state.sh, gsd-phase-boundary.sh: emit Claude Code hookSpecificOutput JSON envelope with typed state_present/config_mode/ planning_modified/file_path fields (no-op when hooks.community is off) Test migrations (all pass, 171 tests across the 8 files): - bug-2649-sdk-fail-fast: assert on ir.reason / ir.context / ir.fix_command - bug-2687-config-read-warning-parity: assert.equal stderr === '' - bug-2796-arg-parsing-regression: assert on result.json.updated/.phase - bug-2838-summary-rescue: parse rescue footer, assert mtime invariant - bug-2943-config-get-context-window: parse JSON, assert ERROR_REASON.CONFIG_KEY_NOT_FOUND - graphify: assert reason === GRAPHIFY_REASON.ENOENT/TIMEOUT - hooks-opt-in: parse hookSpecificOutput, assert typed fields - security-scan: reclassified as source-text-is-the-product (scan label output and CI workflow YAML ARE the deployed contract) Verification: lint-no-source-grep clean (0 violations), full suite 6741/6741 pass. Closes #2974 * test(#2974): address CR feedback — typed code field, robust idempotency Two CodeRabbit findings on #3016 addressed: 1. tests/hooks-opt-in.test.cjs:355 (Minor, inline) — parsed.reason.includes('Conventional Commits') was still substring matching after the typed-IR migration. Fixed at the source: the gsd-validate-commit hook now emits a typed `code` field ('CONVENTIONAL_COMMITS_VIOLATION', 'COMMIT_SUBJECT_TOO_LONG') alongside the human-readable `reason`. Test asserts strictEqual on the code; the prose copy is no longer part of the test contract. 2. tests/bug-2838-summary-rescue-gitignored-planning.test.cjs:224-250 (Outside-diff) — mtimeMs alone can stay unchanged on coarse-grained filesystems (HFS+, FAT) when two rewrites land within the same timestamp tick, falsely passing the idempotency assertion. Replaced with a full snapshot (mtimeMs, ctimeMs, size, ino, sha256 of contents) compared via assert.deepStrictEqual — the hash catches any rewrite the timestamp would miss. Verification: 30/30 pass on the two affected files; lint-no-source-grep clean (0 violations across 368 test files). |
||
|
|
faee0287a0 |
fix(detect-custom-files): add skills/ to GSD_MANAGED_DIRS (#2942) (#2945)
After v1.39.0 skill consolidation (#2790), skills/ became a GSD-managed root that the installer wipes on update. GSD_MANAGED_DIRS in gsd-tools.cjs was missing 'skills', so user-added skill directories (e.g. skills/custom-skill/SKILL.md) were never walked and silently destroyed during /gsd-update. - Add 'skills' to GSD_MANAGED_DIRS so the directory is walked - Add tests/bug-2942-detect-custom-skills.test.cjs with 5 targeted tests - Update tests/update-custom-backup.test.cjs: replace the now-incorrect "skills/ must NOT be scanned" assertion (written pre-#2790) with a test that verifies custom skills ARE detected and GSD-owned skills are not falsely flagged Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
9a13d2fc0b |
fix(#2911): audit-open emits raw human report and parseable JSON
Two bugs in the audit-open dispatch case in bin/gsd-tools.cjs:
1. Bare output(...) calls (only core.output is in scope) threw
ReferenceError: output is not defined on every invocation,
blocking the first step of /gsd-complete-milestone.
2. Even after switching to core.output(formattedReport, raw), the
human-readable branch JSON-stringified the formatted text because
core.output only bypasses JSON encoding when called as
core.output(null, true, rawValue).
Fix:
- --json path: core.output(result, raw) — pass the object,
let core.output JSON-stringify (don't pre-stringify).
- text path: core.output(null, true, formatAuditReport(result))
— use the rawValue form to emit verbatim section dividers and
item lists.
Adds tests/bug-2911-audit-open-output-shape.test.cjs which parses
both modes structurally — line-by-line for text mode (asserting the
report headers exist as standalone lines, not as escaped \n inside a
JSON quoted string), and JSON.parse + key-by-key shape assertions for
--json mode (matching the contract returned by auditOpenArtifacts).
|
||
|
|
444db1714b |
refactor(query): manifest-backed routing seam + family adapters (#2908)
Merging validated command-seam foundation. |
||
|
|
abb2cb63f6 |
refactor: extract planning-workspace seam from core.cjs (#2901)
* refactor: extract planning workspace seam from core * docs: document planning-workspace module and inventory updates * fix: harden planning lock timeout and preserve workstream set contract --------- Co-authored-by: Tom Boucher <thomas.boucher@sas.com> |
||
|
|
5fdc950eb7 |
feat(#2792): namespace meta-skills + keyword-tag descriptions + context utilization guard (#2825)
* feat(#2792): namespace meta-skills retargeted at the post-#2790 surface This branch is now based on #2790's HEAD (the consolidation PR) instead of main, and every routing table targets the consolidated surface so a user routed by a namespace meta-skill never lands at a deleted / folded sub-skill. Cross-PR inconsistencies the original PR #2825 carried (vs #2790): - ns-ideate routed to gsd-note / gsd-add-todo / gsd-add-backlog / gsd-plant-seed → all folded into gsd-capture by #2790. Now routes to gsd-capture (the parent picks the mode from the user's intent). - ns-context routed to gsd-scan and gsd-intel → folded into gsd-map-codebase --fast / --query by #2790. Now routes to those flag forms. - ns-manage routed all workspace intent to gsd-list-workspaces (a list-only entry) → CR also flagged the over-narrow target. #2790 folds into gsd-workspace; routing now points there. - ns-workflow routed to gsd-research-phase → deleted outright by #2790. Removed. - ns-project routed to gsd-plan-milestone-gaps → deleted outright by #2790. Removed. - None of the namespaces previously surfaced #2790's new consolidated skills (gsd-capture, gsd-phase, gsd-config, gsd-workspace, gsd-progress). All five are now reachable through the routers. - extract_learnings → extract-learnings (canonicalized by #2858). Defect fixes within the namespace skills: - Hyphen-form `name:` (gsd-workflow, …) per the canonical naming contract — the colon-form addressed CR's drift complaint. - `Skill` added to allowed-tools on every router. The body instructs "Invoke the matched skill directly using the Skill tool" — without Skill in the permission list the meta-skill cannot route at all. New regression guard in tests/enh-2792-namespace-skills.test.cjs: every gsd-* token in any namespace router's table column resolves to a surviving commands/gsd/*.md file (or to a known consolidated parent for flag-form targets like gsd-map-codebase --fast). This single test would have caught every dead-end route the original PR shipped with. Skill-count cap in tests/enh-2790-skill-consolidation.test.cjs now filters out ns-*.md from its <= 63 cap. Namespace routers are descriptor-only entries, not part of the consolidation surface that cap is policing — they have their own contract in tests/enh-2792-namespace-skills.test.cjs. INVENTORY.md gains a "Namespace Meta-Skills" section with the 6 router rows; INVENTORY-MANIFEST.json gains 6 entries; the headline count moves 59 → 65 to match. Out of scope for this rebase: the gsd-health --context flag (PR #2825 advertised the contract but didn't implement it). That's a separate feature concern and is left untouched here. 5908/5908 on `npm test`. * feat(#2792): implement gsd-health --context utilization guard The original PR #2825 advertised a `--context` flag on gsd-health with a 60%/70% utilization threshold table but never implemented the workflow logic — CR caught it as a contract leak, the rebase deferred it. This commit closes the gap with TDD red/green/refactor. Math layer (pure): - get-shit-done/bin/lib/context-utilization.cjs classifyContextUtilization(tokensUsed, contextWindow) → { percent, state } State boundaries use the exact ratio: < 60% healthy / 60–70% warning / ≥ 70% critical (fracture point) Display percent rounded for humans. Throws TypeError on non-integer or out-of-range inputs. - STATES = Object.freeze({ HEALTHY, WARNING, CRITICAL }) exported so callers reference the names by symbol, not by literal string. SDK CLI integration: - get-shit-done/bin/gsd-tools.cjs `validate context --tokens-used N --context-window M [--json]` routes to the classifier, owns the recommendation copy (the classifier intentionally does not — keeps the renderer free to evolve without touching the math layer or its tests), and uses core.output's rawValue path for the sync-flush guarantee. - sdk/src/query/validate.ts + sdk/src/query/index.ts TypeScript validateContext handler registered at 'validate.context' and 'validate context'. Mirrors the CJS classifier inline (15 lines of arithmetic; not worth a shared cross-language module). User-facing wiring: - commands/gsd/health.md frontmatter advertises --context, body documents the three-state threshold table. - get-shit-done/workflows/health.md adds a `context_check` step that's reached only when --context is set. Step calls `gsd-sdk query validate.context` with self-reported tokensUsed and contextWindow, prints the SDK output verbatim, and ends. Includes a TEXT_MODE plain-text fallback for non-Claude runtimes per #2012. Tests: - tests/context-utilization.test.cjs (17 tests) — pure-function contract: state thresholds at every boundary, percent rounding, input validation, return-shape (no recommendation field — that's the renderer's job). - tests/validate-context.test.cjs (9 tests) — SDK CLI plumbing: arg parsing errors, JSON vs human rendering, recommendation copy pinned per state. - tests/enh-2792-namespace-skills.test.cjs (4 new tests) — markdown contract: --context advertised in argument-hint, threshold table in command body, context_check step exists in workflow, step invokes gsd-sdk query validate.context with both flags. Inventory bookkeeping: - docs/INVENTORY.md "CLI Modules" 31 → 32; new row for context-utilization.cjs. - docs/INVENTORY-MANIFEST.json mirror. 5939/5939 on `npm test`. |
||
|
|
eddb2a205b |
fix(#2801): add ingest-docs handler to gsd-tools init dispatch (#2820)
* fix(#2801): add ingest-docs handler to gsd-tools init dispatch The `/gsd-ingest-docs` workflow was broken because `workflows/ingest-docs.md` called `gsd-sdk query init.ingest-docs` but the installed binary is `gsd-tools`, and `gsd-tools init` had no `ingest-docs` case in its dispatch switch. - Added `cmdInitIngestDocs` function to `init.cjs` and exported it; returns `project_exists`, `planning_exists`, `has_git`, `project_path`, `commit_docs` - Added `case 'ingest-docs'` to the `init` switch in `gsd-tools.cjs` - Updated `workflows/ingest-docs.md` to call `gsd-tools init ingest-docs` (line 55) and `gsd-tools commit` (line 292) instead of `gsd-sdk query ...` - Regression test: `tests/bug-2801-ingest-docs-handler.test.cjs` Closes #2801 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(#2801): address CodeRabbit — commit_docs assertion, broader gsd-sdk detection, bash fence --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
dc9b712967 |
refactor(state): drop unused args + lift currentPhase in cmdStateCompletePhase (#2761)
* refactor(state): drop unused args param and lift currentPhase in cmdStateCompletePhase Two cleanup items surfaced by CodeRabbit review of PR #2759: 1. cmdStateCompletePhase(cwd, args, raw) — args is never read inside the function. All sibling state subcommands use the leaner (cwd, raw) shape. Remove the unused parameter and update the dispatch call in gsd-tools.cjs. 2. output() at line 1754 called fs.readFileSync(statePath) after readModifyWriteStateMd had already released the lock, re-extracting Current Phase via an extra fs read. The closure already computed currentPhase at line 1704; lifting resolvedPhase into outer scope and capturing it in the callback eliminates the post-lock read and closes the small race window. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test(#2761): apply CodeRabbit nitpicks with regression tests Two CodeRabbit nitpicks from PR #2761 review, each landed with a regression test so a future refactor can't unwind them. 1. tests/dispatcher.test.cjs — pin the enumerated subcommand list: the 'state unknown subcommand errors' test now also asserts that the dispatcher's error string includes 'complete-phase'. Without this, a future reformat of the available-subcommands enumeration could silently drop entries and the existing 'Unknown state subcommand' substring check would still pass. 2. get-shit-done/bin/lib/state.cjs — tighten the Phase fallback in cmdStateCompletePhase: when STATE.md is missing the canonical '**Current Phase:**' field and the only phase signal is the decorated body line under '## Current Position' (e.g. 'Phase: 01 (Foo) — EXECUTING'), the previous fallback returned the entire decorated string, producing messy downstream output: Status: Phase 01 (Foo) — EXECUTING complete Phase: 01 (Foo) — EXECUTING — COMPLETE The fallback now strips everything past the leading numeric/decimal token via /^\\s*([\\w.-]+)/ so degraded inputs produce clean output identical to the canonical path. 3. tests/state.test.cjs — two new tests in a dedicated describe block: - decorated Phase line writes clean Phase identifier - canonical Current Phase wins over Current Position decoration Both run real `gsd state complete-phase` against synthetic STATE.md fixtures and assert on the rendered Status field. --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
1405728292 |
fix: parseMustHavesBlock quoted strings + gsd state complete-phase (#2744)
* fix: parseMustHavesBlock quoted strings + gsd state complete-phase Bug #2734: parseMustHavesBlock dropped quoted truths containing ':' because fully-quoted strings like `"App-side UUIDv4: generated locally"` fell into the kv-parse branch, the regex failed (value starts with '"'), and current stayed as empty {}. Fix: detect fully-quoted strings before the ':' check and extract them directly. Two regression tests added to frontmatter.test.cjs. Bug #2735: `gsd state complete-phase` subcommand was missing — unknown subcommands fell through to cmdStateLoad. Added cmdStateCompletePhase to state.cjs (updates Status, Last Activity, and Current Position to COMPLETE), exported it, and wired it into the case 'state': dispatch in gsd-tools.cjs. Closes #2734 Closes #2735 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(state): unknown subcommand returns explicit error instead of silent fallthrough Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
e973ff4cb6 |
fix(#2630): reset STATE.md frontmatter atomically on milestone switch (#2666)
The /gsd:new-milestone workflow Step 5 rewrote STATE.md's Current Position body but never touched the YAML frontmatter, so every downstream reader (state.json, getMilestoneInfo, progress bars) kept reporting the stale milestone until the first phase advance forced a resync. Asymmetric with milestone.complete, which uses readModifyWriteStateMdFull. Add a new `state milestone-switch` handler (both SDK and CJS) that atomically: - Stomps frontmatter milestone/milestone_name with caller-supplied values - Resets status to 'planning' and progress counters to zero - Rewrites the ## Current Position section to the new-milestone template - Preserves Accumulated Context (decisions, blockers, todos) Wire the workflow Step 5 to invoke `state.milestone-switch` instead of the manual body rewrite. Note the flag is `--milestone` not `--version`: gsd-tools reserves `--version` as a globally-invalid help flag. Red vitest in sdk/src/query/state-mutation.test.ts asserts the frontmatter reset. Regression guard via node:test in tests/bug-2630-*.test.cjs runs through gsd-tools end-to-end. Fixes #2630 Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
1a3d953767 |
feat: add unified post-planning gap checker (closes #2493) (#2610)
* feat: add unified post-planning gap checker (closes #2493) Adds a unified post-planning gap checker as Step 13e of plan-phase.md. After all plans are generated and committed, scans REQUIREMENTS.md and CONTEXT.md <decisions> against every PLAN.md in the phase directory and emits a single Source | Item | Status table. Why - The existing Requirements Coverage Gate (§13) blocks/re-plans on REQ gaps but emits two separate per-source signals. Issue #2493 asks for one unified report after planning so that requirements AND discuss-phase decisions slipping through are surfaced in one place before execution starts. What - New workflow.post_planning_gaps boolean config key, default true, added to VALID_CONFIG_KEYS, CONFIG_DEFAULTS, hardcoded.workflow, and cmdConfigSet (boolean validation). - New get-shit-done/bin/lib/decisions.cjs — shared parser for CONTEXT.md <decisions> blocks (D-NN entries). Designed for reuse by the related #2492 plan/verify decision gates. - New get-shit-done/bin/lib/gap-checker.cjs — parses REQUIREMENTS.md (checkbox + traceability table forms), reads CONTEXT.md decisions, walks PHASE_DIR/*-PLAN.md, runs word-boundary coverage detection (REQ-1 must not match REQ-10), formats a sorted report. - New gsd-tools gap-analysis CLI command wired through gsd-tools.cjs. - workflows/plan-phase.md gains §13e between §13d (commit plans) and §14 (Present Final Status). Existing §13 gate preserved — §13e is additive and non-blocking. - sdk/prompts/workflows/plan-phase.md gets an equivalent post_planning_gaps step for headless mode. - Docs: CONFIGURATION.md, references/planning-config.md, INVENTORY.md, INVENTORY-MANIFEST.json all updated. Tests - tests/post-planning-gaps-2493.test.cjs: 30 test cases covering step insertion position, decisions parser, gap detector behavior (covered/not-covered, false-positive guard, missing-file resilience, malformed-input resilience, gate on/off, deterministic natural sort), and full config integration. - Full suite: 5234 / 5234 pass. Design decisions - Numbered §13e (sub-step), not §14 — §14 already exists (Present Final Status); inserting before it preserves downstream auto-advance step numbers. - Existing §13 gate kept, not replaced — §13 blocks/re-plans on REQ gaps; §13e is the unified post-hoc report. Per spec: "default behavior MUST be backward compatible." - Word-boundary ID matching avoids REQ-1 matching REQ-10 and avoids brittle semantic/substring matching. - Shared decisions.cjs parser so #2492 can reuse the same regex. - Natural-sort keys (REQ-02 before REQ-10) for deterministic output. - Boolean validation in cmdConfigSet rejects non-boolean values matches the precedent set by drift_threshold/drift_action. Closes #2493 * fix(#2493): expose post_planning_gaps in loadConfig() + sync schema example Address CodeRabbit review on PR #2610: - core.cjs loadConfig(): return post_planning_gaps from both the config.json branch and the global ~/.gsd/defaults.json fallback so callers can rely on config.post_planning_gaps regardless of whether the key is present (comment 3127977404, Major). - docs/CONFIGURATION.md: add workflow.post_planning_gaps to the Full Schema JSON example so copy/paste users see the new toggle alongside security_block_on (comment 3127977392, Minor). - tests/post-planning-gaps-2493.test.cjs: regression coverage for loadConfig() — default true when key absent, honors explicit true/false from workflow.post_planning_gaps. |
||
|
|
1a694fcac3 |
feat: auto-remap codebase after significant phase execution (closes #2003) (#2605)
* feat: auto-remap codebase after significant phase execution (#2003) Adds a post-phase structural drift detector that compares the committed tree against `.planning/codebase/STRUCTURE.md` and either warns or auto-remaps the affected subtrees when drift exceeds a configurable threshold. ## Summary - New `bin/lib/drift.cjs` — pure detector covering four drift categories: new directories outside mapped paths, new barrel exports at `(packages|apps)/*/src/index.*`, new migration files, and new route modules. Prioritizes the most-specific category per file. - New `verify codebase-drift` CLI subcommand + SDK handler, registered as `gsd-sdk query verify.codebase-drift`. - New `codebase_drift_gate` step in `execute-phase` between `schema_drift_gate` and `verify_phase_goal`. Non-blocking by contract — any error logs and the phase continues. - Two new config keys: `workflow.drift_threshold` (int, default 3) and `workflow.drift_action` (`warn` | `auto-remap`, default `warn`), with enum/integer validation in `config-set`. - `gsd-codebase-mapper` learns an optional `--paths <p1,p2,...>` scope hint for incremental remapping; agent/workflow docs updated. - `last_mapped_commit` lives in YAML frontmatter on each `.planning/codebase/*.md` file; `readMappedCommit`/`writeMappedCommit` round-trip helpers ship in `drift.cjs`. ## Tests - 55 new tests in `tests/drift-detection.test.cjs` covering: classification, threshold gating at 2/3/4 elements, warn vs. auto-remap routing, affected-path scoping, `--paths` sanitization (traversal, absolute, shell metacharacter rejection), frontmatter round-trip, defensive paths (missing STRUCTURE.md, malformed input, non-git repos), CLI JSON output, and documentation parity. - Full suite: 5044 pass / 0 fail. ## Documentation - `docs/CONFIGURATION.md` — rows for both new keys. - `docs/ARCHITECTURE.md` — section on the post-execute drift gate. - `docs/AGENTS.md` — `--paths` flag on `gsd-codebase-mapper`. - `docs/USER-GUIDE.md` — user-facing behavior note + toggle commands. - `docs/FEATURES.md` — new 27a section with REQ-DRIFT-01..06. - `docs/INVENTORY.md` + `docs/INVENTORY-MANIFEST.json` — drift.cjs listed. - `get-shit-done/workflows/execute-phase.md` — `codebase_drift_gate` step. - `get-shit-done/workflows/map-codebase.md` — `parse_paths_flag` step. - `agents/gsd-codebase-mapper.md` — `--paths` directive under parse_focus. ## Design decisions - **Frontmatter over sidecar JSON** for `last_mapped_commit`: keeps the baseline attached to the file, survives git moves, survives per-doc regeneration, no extra file lifecycle. - **Substring match against STRUCTURE.md** for `isPathMapped`: the map is free-form markdown, not a structured manifest; any mention of a path prefix counts as "mapped territory". Cheap, no parser, zero false negatives on reasonable maps. - **Category priority migration > route > barrel > new_dir** so a file matching multiple rules counts exactly once at the most specific level. - **Empty-tree SHA fallback** (`4b825dc6…`) when `last_mapped_commit` is absent — semantically correct (no baseline means everything is drift) and deterministic across repos. - **Four layers of non-blocking** — detector try/catch, CLI try/catch, SDK handler try/catch, and workflow `|| echo` shell fallback. Any single layer failing still returns a valid skipped result. - **SDK handler delegates to `gsd-tools.cjs`** rather than re-porting the detector to TypeScript, keeping drift logic in one canonical place. Closes #2003 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(mapper): tag --paths fenced block as text (CodeRabbit MD040) Comment 3127255172. * docs(config): use /gsd- dash command syntax in drift_action row (CodeRabbit) Comment 3127255180. Matches the convention used by every other command reference in docs/CONFIGURATION.md. * fix(execute-phase): initialize AGENT_SKILLS_MAPPER + tag fenced blocks Two CodeRabbit findings on the auto-remap branch of the drift gate: - 3127255186 (must-fix): the mapper Task prompt referenced ${AGENT_SKILLS_MAPPER} but only AGENT_SKILLS (for gsd-executor) is loaded at init_context (line 72). Without this fix the literal placeholder string would leak into the spawned mapper's prompt. Add an explicit gsd-sdk query agent-skills gsd-codebase-mapper step right before the Task spawn. - 3127255183: tag the warn-message and Task() fenced code blocks as text to satisfy markdownlint MD040. * docs(map-codebase): wire PATH_SCOPE_HINT through every mapper prompt CodeRabbit (review id 4158286952, comment 3127255190) flagged that the parse_paths_flag step defined incremental-remap semantics but did not inject a normalized variable into the spawn_agents and sequential_mapping mapper prompts, so incremental remap could silently regress to a whole-repo scan. - Define SCOPED_PATHS / PATH_SCOPE_HINT in parse_paths_flag. - Inject ${PATH_SCOPE_HINT} into all four spawn_agents Task prompts. - Document the same scope contract for sequential_mapping mode. * fix(drift): writeMappedCommit tolerates missing target file CodeRabbit (review id 4158286952, drift.cjs:349-355 nitpick) noted that readMappedCommit returns null on ENOENT but writeMappedCommit threw — an asymmetry that breaks first-time stamping of a freshly produced doc that the caller has not yet written. - Catch ENOENT on the read; treat absent file as empty content. - Add a regression test that calls writeMappedCommit on a non-existent path and asserts the file is created with correct frontmatter. Test was authored to fail before the fix (ENOENT) and passes after. --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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 |
||
|
|
39623fd5b8 |
docs(cli): deprecate gsd-tools.cjs header in favor of gsd-sdk (#2343) (#2343)
Single-file change: JSDoc @deprecated notice pointing to SDK query registry. No .planning or unrelated merges. |
||
|
|
5f521e0867 |
fix(settings): route /gsd-settings reads/writes through workstream-aware config path (#2285)
settings.md was reading and writing .planning/config.json directly while gsd-tools config-get/config-set route to .planning/workstreams/<slug>/config.json when GSD_WORKSTREAM is active, causing silent write-read drift (Closes #2282). - config.cjs: add cmdConfigPath() — emits the planningDir-resolved config path as plain text (always raw, no JSON wrapping) so shell substitution works correctly - gsd-tools.cjs: wire config-path subcommand - settings.md: resolve GSD_CONFIG_PATH via config-path in ensure_and_load_config; replace hardcoded cat .planning/config.json and Write to .planning/config.json with $GSD_CONFIG_PATH throughout - phase.cjs: fix renameDecimalPhases to preserve zero-padded prefix (06.3 → 06.2 not 6.2) — pre-existing test failure on main - tests/config.test.cjs: add config-path command tests (#2282) Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
7b85d9e689 |
fix(cli): audit-open crashes with ReferenceError: output is not defined (#2236) (#2238)
The audit-open case in gsd-tools.cjs called bare output() on both the --json and text paths. output is never in scope at the call site — the entire core module is imported as `const core`, so every other command uses core.output(). Two-part fix: - Replace output(...) with core.output(...) on both branches - Pass result (the raw object) on the --json path, not JSON.stringify(result) — core.output always calls JSON.stringify internally, so pre-serialising caused double-encoding and agents received a string instead of an object Adds three CLI-level regression tests to milestone-audit.test.cjs that invoke audit-open through runGsdTools (the same path the agent uses), so a recurrence at the dispatch layer is caught even if lib-level tests continue to pass. Closes #2236 Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
62b5278040 |
fix(installer): restore detect-custom-files and backup_custom_files lost in release drift (#1997) (#2233)
PR #2038 added detect-custom-files to gsd-tools.cjs and the backup_custom_files
step to update.md, but commit 7bfb11b6 is not an ancestor of v1.36.0: main was
rebuilt after the merge, orphaning the change. Users on 1.36.0 running /gsd-update
silently lose any locally-authored files inside GSD-managed directories.
Root cause: git merge-base 7bfb11b6 HEAD returns
|
||
|
|
c11ec05554 |
feat: /gsd-graphify integration — knowledge graph for planning agents (#2164)
* feat(01-01): create graphify.cjs library module with config gate, subprocess helper, presence detection, and version check - isGraphifyEnabled() gates on config.graphify.enabled in .planning/config.json - disabledResponse() returns structured disabled message with enable instructions - execGraphify() wraps spawnSync with PYTHONUNBUFFERED=1, 30s timeout, ENOENT/SIGTERM handling - checkGraphifyInstalled() detects missing binary via --help probe - checkGraphifyVersion() uses python3 importlib.metadata, validates >=0.4.0,<1.0 range * feat(01-01): register graphify.enabled in VALID_CONFIG_KEYS - Added graphify.enabled after intel.enabled in config.cjs VALID_CONFIG_KEYS Set - Enables gsd-tools config-set graphify.enabled true without key rejection * test(01-02): add comprehensive unit tests for graphify.cjs module - 23 tests covering all 5 exported functions across 5 describe blocks - Config gate tests: enabled/disabled/missing/malformed scenarios (TEST-03, FOUND-01) - Subprocess tests: success, ENOENT, timeout, env vars, timeout override (FOUND-04) - Presence tests: --help detection, install instructions (FOUND-02, TEST-04) - Version tests: compatible/incompatible/unparseable/missing (FOUND-03, TEST-04) - Fix graphify.cjs to use childProcess.spawnSync (not destructured) for testability * feat(02-01): add graphifyQuery, graphifyStatus, graphifyDiff to graphify.cjs - safeReadJson wraps JSON.parse in try/catch, returns null on failure - buildAdjacencyMap creates bidirectional adjacency map from graph nodes/edges - seedAndExpand matches on label+description (case-insensitive), BFS-expands up to maxHops - applyBudget uses chars/4 token estimation, drops AMBIGUOUS then INFERRED edges - graphifyQuery gates on config, reads graph.json, supports --budget option - graphifyStatus returns exists/last_build/counts/staleness or no-graph message - graphifyDiff compares current graph.json against .last-build-snapshot.json * feat(02-01): add case 'graphify' routing block to gsd-tools.cjs - Routes query/status/diff/build subcommands to graphify.cjs handlers - Query supports --budget flag via args.indexOf parsing - Build returns Phase 3 placeholder error message - Unknown subcommand lists all 4 available options * feat(02-01): create commands/gsd/graphify.md command definition - YAML frontmatter with name, description, argument-hint, allowed-tools - Config gate reads .planning/config.json directly (not gsd-tools config get-value) - Inline CLI calls for query/status/diff subcommands - Agent spawn placeholder for build subcommand - Anti-read warning and anti-patterns section * test(02-02): add Phase 2 test scaffolding with fixture helpers and describe blocks - Import 7 Phase 2 exports (graphifyQuery, graphifyStatus, graphifyDiff, safeReadJson, buildAdjacencyMap, seedAndExpand, applyBudget) - Add writeGraphJson and writeSnapshotJson fixture helpers - Add SAMPLE_GRAPH constant with 5 nodes, 5 edges across all confidence tiers - Scaffold 7 new describe blocks for Phase 2 functions * test(02-02): add comprehensive unit tests for all Phase 2 graphify.cjs functions - safeReadJson: valid JSON, malformed JSON, missing file (3 tests) - buildAdjacencyMap: bidirectional entries, orphan nodes, edge objects (3 tests) - seedAndExpand: label match, description match, BFS depth, empty results, maxHops (5 tests) - applyBudget: no budget passthrough, AMBIGUOUS drop, INFERRED drop, trimmed footer (4 tests) - graphifyQuery: disabled gate, no graph, valid query, confidence tiers, budget, counts (6 tests) - graphifyStatus: disabled gate, no graph, counts with graph, hyperedge count (4 tests) - graphifyDiff: disabled gate, no baseline, no graph, added/removed, changed (5 tests) - Requirements: TEST-01, QUERY-01..03, STAT-01..02, DIFF-01..02 - Full suite: 53 graphify tests pass, 3666 total tests pass (0 regressions) * feat(03-01): add graphifyBuild() pre-flight, writeSnapshot(), and build_timeout config key - Add graphifyBuild(cwd) returning spawn_agent JSON with graphs_dir, timeout, version - Add writeSnapshot(cwd) reading graph.json and writing atomic .last-build-snapshot.json - Register graphify.build_timeout in VALID_CONFIG_KEYS - Import atomicWriteFileSync from core.cjs for crash-safe snapshot writes * feat(03-01): wire build routing in gsd-tools and flesh out builder agent prompt - Replace Phase 3 placeholder with graphifyBuild() and writeSnapshot() dispatch - Route 'graphify build snapshot' to writeSnapshot(), 'graphify build' to graphifyBuild() - Expand Step 3 builder agent prompt with 5-step workflow: invoke, validate, copy, snapshot, summary - Include error handling guidance: non-zero exit preserves prior .planning/graphs/ * test(03-02): add graphifyBuild test suite with 6 tests - Disabled config returns disabled response - Missing CLI returns error with install instructions - Successful pre-flight returns spawn_agent action with correct shape - Creates .planning/graphs/ directory if missing - Reads graphify.build_timeout from config (custom 600s) - Version warning included when outside tested range * test(03-02): add writeSnapshot test suite with 6 tests - Writes snapshot from existing graph.json with correct structure - Returns error when graph.json does not exist - Returns error when graph.json is invalid JSON - Handles empty nodes and edges arrays - Handles missing nodes/edges keys gracefully - Overwrites existing snapshot on incremental rebuild * feat(04-01): add load_graph_context step to gsd-planner agent - Detects .planning/graphs/graph.json via ls check - Checks graph staleness via graphify status CLI call - Queries phase-relevant context with single --budget 2000 query - Silent no-op when graph.json absent (AGENT-01) * feat(04-01): add Step 1.3 Load Graph Context to gsd-phase-researcher agent - Detects .planning/graphs/graph.json via ls check - Checks graph staleness via graphify status CLI call - Queries 2-3 capability keywords with --budget 1500 each - Silent no-op when graph.json absent (AGENT-02) * test(04-01): add AGENT-03 graceful degradation tests - 3 AGENT-03 tests: absent-graph query, status, multi-term handling - 2 D-12 integration tests: known-graph query and status structure - All 5 tests pass with existing helpers and imports |
||
|
|
72af8cd0f7 |
fix: display relative time in intel status output (#2132)
* fix: display relative time instead of UTC in intel status output
The `updated_at` timestamps in `gsd-tools intel status` were displayed
as raw ISO/UTC strings, making them appear to show the wrong time in
non-UTC timezones. Replace with fuzzy relative times ("5 minutes ago",
"1 day ago") which are timezone-agnostic and more useful for freshness.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* test: add regression tests for timeAgo utility
Covers boundary values (seconds/minutes/hours/days/months/years),
singular vs plural formatting, and future-date edge case.
Addresses review feedback on #2132.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
||
|
|
4bf3b02bec |
fix: add phase add-batch command to prevent duplicate phase numbers on parallel invocations (#2165) (#2170)
Parallel `phase add` invocations each read disk state before any write completes, causing all processes to calculate the same next phase number and produce duplicate directories and ROADMAP entries. The new `add-batch` subcommand accepts a JSON array of phase descriptions and performs all directory creation and ROADMAP appends within a single `withPlanningLock()` call, incrementing `maxPhase` within the lock for each entry. This guarantees sequential numbering regardless of call concurrency patterns. Closes #2165 Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
f0a20e4dd7 |
feat: open artifact audit gate for milestone close and phase verify (#2157, #2158) (#2160)
* feat(2158): add audit.cjs open artifact scanner with security-hardened path handling - Scans 8 .planning/ artifact categories for unresolved state - Debug sessions, quick tasks, threads, todos, seeds, UAT gaps, verification gaps, CONTEXT open questions - requireSafePath with allowAbsolute:true on all file reads - sanitizeForDisplay on all output strings - Graceful per-category error handling, never throws - formatAuditReport returns human-readable report with emoji indicators * feat(2158): add audit-open CLI command to gsd-tools.cjs + Deferred Items to state template - Add audit-open [--json] case to switch router - Add audit-open entry to header comment block - Add Deferred Items section to state.md template for milestone carry-forward * feat(2157): add phase artifact scan step to verify-work workflow - scan_phase_artifacts step runs audit-open --json after UAT completion - Surfaces UAT gaps, VERIFICATION gaps, and CONTEXT open questions for current phase - Prompts user to confirm or decline before marking phase verified - Records acknowledged gaps in VERIFICATION.md Acknowledged Gaps section - SECURITY note: file paths validated, content truncated and sanitized before display * feat(2158): add pre-close artifact audit gate to complete-milestone workflow - pre_close_artifact_audit step runs before verify_readiness - Displays full audit report when open items exist - Three-way choice: Resolve, Acknowledge all, or Cancel - Acknowledge path writes deferred items table to STATE.md - Records deferred count in MILESTONES.md entry - Adds three new success criteria checklist items - SECURITY note on sanitizing all STATE.md writes * test(2157,2158): add milestone audit gate tests - 6 tests for audit.cjs: structured result, graceful missing dirs, open debug detection, resolved session exclusion, formatAuditReport header, all-clear message - 3 tests for complete-milestone.md: pre_close_artifact_audit step, Deferred Items, security note presence - 2 tests for verify-work.md: scan_phase_artifacts step, user prompt for gaps - 1 test for state.md template: Deferred Items section |
||
|
|
8009b67e3e |
feat: expose tdd_mode in init JSON and add --tdd flag override (#2124)
* test(2123): add failing tests for TDD init JSON exposure and --tdd flag Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat(2123): expose tdd_mode in init JSON and add --tdd flag override Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
190804fc73 |
Merge pull request #2063 from Tibsfox/feat/state-prune-1970
feat(state): add state prune command for unbounded section growth |
||
|
|
9435c4dd38 |
feat(init): add skill-manifest command to pre-compute skill discovery (#2101)
Adds `skill-manifest` command that scans a skills directory, extracts frontmatter and trigger conditions from each SKILL.md, and outputs a compact JSON manifest. This reduces per-agent skill discovery from 36 Read operations (~6,000 tokens) to a single manifest read (~1,000 tokens). Closes #1976 Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
01f0b4b540 |
feat(state): add --dry-run mode and resolved blocker pruning (#1970)
Review feedback from @trek-e — address scope gaps: 1. **--dry-run mode** — New flag that computes what would be pruned without modifying STATE.md. Returns structured output showing per-section counts so users can verify before committing. 2. **Resolved blocker pruning** — In addition to decisions and recently-completed entries, now prunes entries in the Blockers section that are marked resolved (~~strikethrough~~ or [RESOLVED] prefix) AND reference a phase older than the cutoff. Unresolved blockers are preserved regardless of age. 3. **Tests** — Added tests/state-prune.test.cjs (4 cases): - Prunes decisions older than cutoff, keeps recent - --dry-run reports changes without modifying STATE.md - Prunes resolved blockers, keeps unresolved regardless of age - Returns pruned:false when nothing exceeds cutoff Scope items still deferred (to be filed as follow-up): - Performance Metrics "By Phase" table row pruning — needs different regex handling than prose lines - Auto-prune via workflow.auto_prune_state at phase completion — needs integration into cmdPhaseComplete Also: the pre-existing test failure (2918/2919) is tests/stale-colon-refs.test.cjs:83:3 "No stale /gsd: colon references (#1748)". Verified failing on main, not introduced by this PR. |
||
|
|
f1b3702be8 |
feat(state): add state prune command for unbounded section growth (#1970)
Add `gsd-tools state prune --keep-recent N` that moves old decisions and recently-completed entries to STATE-ARCHIVE.md. Entries from phases older than (current - N) are archived; the N most recent are kept. STATE.md sections grow unboundedly in long-lived projects. A 20+ phase project accumulates hundreds of historical decisions that every agent loads into context. Pruning removes stale entries from the hot path while preserving them in a recoverable archive. Usage: gsd-tools state prune --keep-recent 3 Default: keeps 3 most recent phases Closes #1970 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
96eef85c40 |
feat(import): add /gsd-from-gsd2 reverse migration from GSD-2 to v1 (#2072)
Adds a new command and CLI subcommand that converts a GSD-2 `.gsd/` project back to GSD v1 `.planning/` format — the reverse of the forward migration GSD-2 ships. Closes #2069 Maps GSD-2's Milestone → Slice → Task hierarchy to v1's flat Milestone sections → Phase → Plan structure. Slices are numbered sequentially across all milestones; tasks become numbered plans within their phase. Completion state, research files, and summaries are preserved. New files: - `get-shit-done/bin/lib/gsd2-import.cjs` — parser, transformer, writer - `commands/gsd/from-gsd2.md` — slash command definition - `tests/gsd2-import.test.cjs` — 41 tests, 99.21% statement coverage Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
14fd090e47 |
docs(config): document missing config keys in planning-config.md (#1947)
* fix(core): resolve @file: references in gsd-tools stdout (#1891) Workflows used bash-specific `if [[ "$INIT" == @file:* ]]` to detect when large JSON was written to a temp file. This syntax breaks on PowerShell and other non-bash shells. Intercept stdout in gsd-tools.cjs to transparently resolve @file: references before they reach the caller, matching the existing --pick path behavior. The bash checks in workflow files become harmless no-ops and can be removed over time. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs(config): add missing config fields to planning-config.md (#1880) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Tibsfox <tibsfox@tibsfox.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
602b34afb7 |
feat(config): add --default flag to config-get for graceful absent-key handling (#1893) (#1920)
When --default <value> is passed, config-get returns the default value (exit 0) instead of erroring (exit 1) when the key is absent or config.json doesn't exist. When the key IS present, --default is ignored and the real value returned. This lets workflows express optional config reads without defensive `2>/dev/null || true` boilerplate that obscures intent and is fragile under `set -e`. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
f25ae33dff |
feat(tools): add global learnings store with CRUD library and CLI support (#1831)
* feat(tools): add global learnings store with CRUD library and CLI support * fix(tools): address review feedback for global learnings store - Validate learning IDs against path traversal in learningsRead, learningsDelete, and cmdLearningsDelete - Fix total invariant in learningsCopyFromProject (total = created + skipped) - Wrap cmdLearningsPrune in try/catch to handle invalid duration format - Rename raw -> content in readLearningFile to avoid variable shadowing - Add CLI integration tests for list, query, prune error, and unknown subcommand |
||
|
|
7b369d2df3 |
feat(intel): add queryable codebase intelligence system (#1728)
* feat(intel): add queryable codebase intelligence system Add persistent codebase intelligence that reduces context overhead: - lib/intel.cjs: 654-line CLI module with 13 exports (query, status, diff, snapshot, patch-meta, validate, extract-exports, and more). Reads config.json directly (not via config-get which hard-exits on missing keys). Default is DISABLED (user must set intel.enabled: true). - gsd-tools.cjs: intel case routing with 7 subcommand dispatches - /gsd-intel command: 4 modes (query, status, diff, refresh). Config gate uses Read tool. Refresh spawns gsd-intel-updater agent via Task(). - gsd-intel-updater agent: writes 5 artifacts to .planning/intel/ (files.json, apis.json, deps.json, stack.json, arch.md). Uses gsd-tools intel CLI calls. Completion markers registered in agent-contracts.md. - agent-contracts.md: updated with gsd-intel-updater registration * docs(changelog): add intel system entry for #1688 * test(intel): add comprehensive tests for intel.cjs Cover disabled gating, query (keys, values, case-insensitive, multi-file, arch.md text), status (fresh, stale, missing), diff (no baseline, added, changed), snapshot, validate (missing files, invalid JSON, complete store), patch-meta, extract-exports (CJS, ESM named, ESM block, missing file), and gsd-tools CLI routing for intel subcommands. 38 test cases across 10 describe blocks. * fix(intel): address review feedback — merge markers, redundant requires, gate docs, update route - Remove merge conflict markers from CHANGELOG.md - Replace redundant require('path')/require('fs') in isIntelEnabled with top-level bindings - Add JSDoc notes explaining why intelPatchMeta and intelExtractExports skip isIntelEnabled gate - Add 'intel update' CLI route in gsd-tools.cjs and update help text - Fix stale /gsd: colon reference in intelUpdate return message |
||
|
|
2ded61bf45 |
fix(cli): require --confirm flag before phases clear deletes directories (#1832)
phases clear now checks for phase dirs before deleting. If any exist and --confirm is absent, the command exits non-zero with a message showing the count and how to proceed. Empty phases dir (nothing to delete) succeeds without --confirm unchanged. Updates new-milestone.md workflow to pass --confirm (intentional programmatic caller). Updates existing new-milestone-clear-phases tests to match new API. Closes #1826 Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
e881c91ef1 |
fix(cli): reject help/version flags instead of silently ignoring them (#1822)
* fix(cli): reject help/version flags instead of silently ignoring them (#1818) AI agents can hallucinate --help or --version on gsd-tools invocations. Without a guard, unknown flags were silently ignored and the command proceeded — including destructive ones like `phases clear`. Add a pre-dispatch check in main() that errors immediately if any never-valid flag (-h, --help, -?, --version, -v, --usage) is present in args after global flags are stripped. Regression test covers phases clear, generate- slug, state load, and current-timestamp with both --help and -h variants. Closes #1818 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(agents): convert gsd-verifier required_reading to inline wiring The thinking-model-guidance test requires inline @-reference wiring at decision points rather than a <required_reading> block. Convert verification-overrides.md reference from the <required_reading> block to an inline reference inside <verification_process> alongside the existing thinking-models-verification.md reference. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(tests): resolve conflict between thinking-model and verification-overrides tests thinking-model-guidance.test prohibited <required_reading> entirely, but verification-overrides.test requires gsd-verifier.md to have a <required_reading> block for verification-overrides.md between </role> and <project_context>. The tests were mutually exclusive. Fix: narrow the thinking-model assertion to check that the thinking-models reference is not *inside* a <required_reading> block (using regex extraction), rather than asserting no <required_reading> block exists at all. Restore the <required_reading> block in gsd-verifier.md. Both suites now pass (2345/2345). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
f26e1e1141 |
feat(state): add programmatic gates for STATE.md consistency (#1647)
* feat(state): add programmatic gates for STATE.md consistency Adds four enforcement gates to prevent STATE.md drift: - `state validate`: detects drift between STATE.md and filesystem - `state sync`: reconstructs STATE.md from actual project state - `state planned-phase`: records state after plan-phase completes - Performance Metrics update in `phase complete` Also fixes ghost `state update-position` command reference in execute-phase.md (command didn't exist in CLI dispatcher). Closes #1627 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(state): By Phase table regex ate next section when table body was empty The lazy [\s\S]*? with a $ lookahead in byPhaseTablePattern would match past blank lines and capture the next ## section header as table body when no data rows existed. Replaced with a precise row-matching pattern ((?:[ \t]*\|[^\n]*\n)*) that only captures pipe-delimited lines. Added regression assertion to verify row placement. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
d92cd7922a |
fix: clear phases directory when creating new milestone (#1588) (#1594)
* fix: clear phases directory when creating new milestone (#1588) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * ci: re-run CI with Windows pointer lifecycle fix in main --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
5ce8183928 | fix: isolate active workstream state per session | ||
|
|
9d90c7b420 |
feat(hooks): add check-commit guard for commit_docs enforcement (#1395)
Add check-commit command to gsd-tools that acts as a pre-commit guard. When commit_docs is false, rejects commits that stage .planning/ files with an actionable error message including the unstage command. Recreated cleanly on current main — previous version carried stale shared fixes that are now upstream. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
7f11543691 |
feat: add schema drift detection to prevent false-positive verification
GSD agents silently skip database schema push — verification passes but production breaks because TypeScript types come from config, not the live database. This adds two layers of protection: 1. Plan-phase template detection (step 5.7): When the planner detects schema-relevant file patterns in the phase scope, it injects a mandatory [BLOCKING] schema push task into the plan with the appropriate push command for the detected ORM. 2. Post-execution drift detection gate: After execution completes but before verification marks success, scans for schema-relevant file changes and checks if a push command was executed. Blocks verification with actionable guidance if drift is detected. Supports Payload CMS, Prisma, Drizzle, Supabase, and TypeORM. Override with GSD_SKIP_SCHEMA_CHECK=true. Fixes #1381 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
067d411c9b |
feat: add /gsd:docs-update command for verified documentation generation (#1532)
* docs(01-02): complete gsd-doc-writer agent skeleton plan
- SUMMARY.md for plan 01-02
- STATE.md advanced to plan 2/2, progress 50%
- ROADMAP.md updated with phase 1 plan progress
- REQUIREMENTS.md marked DOCG-01 and DOCG-08 complete
* feat(01-01): create lib/docs.cjs with cmdDocsInit and detection helpers
- Add cmdDocsInit following cmdInitMapCodebase pattern
- Add hasGsdMarker(), scanExistingDocs(), detectProjectType()
- Add detectDocTooling(), detectMonorepoWorkspaces() private helpers
- GSD_MARKER constant for generated-by tracking
- Only Node.js built-ins and local lib requires used
* feat(01-01): wire docs-init into gsd-tools.cjs and register gsd-doc-writer model profile
- Add const docs = require('./lib/docs.cjs') to gsd-tools.cjs
- Add case 'docs-init' routing to docs.cmdDocsInit
- Add docs-init to help text and JSDoc header
- Register gsd-doc-writer in MODEL_PROFILES (quality:opus, balanced:sonnet, budget:haiku)
- Fix docs.cjs: inline withProjectRoot logic via checkAgentsInstalled (private in init.cjs)
* docs(01-01): complete docs-init command plan
- SUMMARY.md documenting cmdDocsInit, detection helpers, wiring
- STATE.md advanced, progress updated to 100%
- ROADMAP.md phase 1 marked Complete
- REQUIREMENTS.md INFRA-01, INFRA-02, CONS-03 marked complete
* feat(01-02): create gsd-doc-writer agent skeleton
- YAML frontmatter with name, description, tools, color: purple
- role block with doc_assignment receiving convention
- create_mode and update_mode sections
- 9 stub template sections (readme, architecture, getting_started, development, testing, api, configuration, deployment, contributing)
- Each template has Required Sections list and Phase 3 TODO
- critical_rules prohibiting GSD methodology and CHANGELOG
- success_criteria checklist
- No GSD methodology leaks in template sections
* feat(02-01): add docs-update workflow Steps 1-6 — init, classify, route, resolve, detect
- init_context step calling docs-init with @file: handling and agent-skills loading
- validate_agents step warns on missing gsd-doc-writer without halting
- classify_project step maps project_type signals to 5 primary labels plus conditional docs
- build_doc_queue step with always-on 6 docs and conditional API/CONTRIBUTING/DEPLOYMENT routing
- resolve_modes step with doc-type to canonical path mapping and create/update detection
- detect_runtime_capabilities step with Task tool detection and sequential fallback routing
* docs(02-01): complete docs-update workflow plan — 13-step orchestration for parallel doc generation
- 02-01-SUMMARY.md: plan results, decisions, file inventory
- STATE.md: advanced to last plan, progress 100%, decisions recorded
- ROADMAP.md: Phase 2 marked Complete (1/1 plans with summary)
- REQUIREMENTS.md: marked INFRA-04, DOCG-03, DOCG-04, CONS-01, CONS-02, CONS-04 complete
* docs(03-02): complete command entry point and workflow extension plan
- 03-02-SUMMARY.md: plan results, decisions, file inventory
- STATE.md: advanced to plan 2, progress 100%, decisions recorded
- ROADMAP.md: Phase 3 marked Complete (2/2 plans with summaries)
- REQUIREMENTS.md: marked INFRA-03, EXIST-01, EXIST-02, EXIST-04 complete
* feat(03-01): fill all 9 doc templates, add supplement mode and per-package README template
- Replace all 9 template stubs with full content guidance (Required Sections, Content Discovery, Format Notes)
- Add shared doc_tooling_guidance block for Docusaurus, VitePress, MkDocs, Storybook routing
- Add supplement_mode block: append-only strategy with heading comparison and safety rules
- Add template_readme_per_package for monorepo per-package README generation
- Update role block to list supplement as third mode; add rule 7 to critical_rules
- Add supplement mode check to success_criteria
- Remove all Phase 3 TODO stubs and placeholder comments
* feat(03-02): add docs-update command entry point with --force and --verify-only flags
- YAML frontmatter with name, argument-hint, allowed-tools
- objective block documents flag semantics with literal-token enforcement pattern
- execution_context references docs-update.md workflow
- context block passes $ARGUMENTS and documents flag derivation rules
- --force takes precedence over --verify-only when both present
* feat(03-02): extend docs-update workflow with preservation_check, monorepo dispatch, and verify-only
- preservation_check step between resolve_modes and detect_runtime_capabilities
- preservation_check skips on --force, --verify-only, or no hand-written docs
- per-file AskUserQuestion choice: preserve/supplement/regenerate with fallback default to preserve
- dispatch_monorepo_packages step after collect_wave_2 for per-package READMEs
- verify_only_report early-exit step with VERIFY marker count and Phase 4 deferral message
- preservation_mode field added to all doc_assignment blocks in dispatch_wave_1, dispatch_wave_2
- sequential_generation extended with monorepo per-package section
- commit_docs updated to include per-package README files pattern
- report extended with per-package README rows and preservation decisions
- success_criteria updated with preservation, --force, --verify-only, and monorepo checks
* feat(04-01): create gsd-doc-verifier agent with claim extraction and filesystem verification
- YAML frontmatter with name, description, tools, and color fields
- claim_extraction section with 5 categories: file paths, commands, API endpoints, functions, dependencies
- skip_rules section for VERIFY markers, placeholders, example prefixes, and diff blocks
- verification_process with 6 steps using filesystem tools only (no self-consistency checks)
- output_format with exact JSON shape per D-01
- critical_rules enforcing filesystem-only verification and read-only operation
* feat(04-01): add fix_mode to gsd-doc-writer with surgical correction instructions
- Add fix_mode section after supplement_mode in modes block
- Document fix mode as valid option in role block mode list
- Add failures field to doc_assignment fields (fix mode only)
- fix_mode enforces surgical precision: only correct listed failing lines
- VERIFY marker fallback when correct value cannot be determined
* test(04-03): add docs-init integration test suite
- 13 tests across 4 describe blocks covering JSON output shape, project type
detection, existing doc scanning, GSD marker detection, and doc tooling
- Tests use node:test + node:assert/strict with beforeEach/afterEach lifecycle
- All 13 tests pass with `node --test tests/docs-update.test.cjs`
* feat(04-02): add verify_docs, fix_loop, scan_for_secrets steps to docs-update workflow
- verify_docs step spawns gsd-doc-verifier per generated doc and collects structured JSON results
- fix_loop step bounded at 2 iterations with regression detection (D-05/D-06)
- scan_for_secrets step uses exact map-codebase grep pattern before commit (D-07/D-08)
- verify_only_report updated to invoke real gsd-doc-verifier instead of VERIFY marker count stub
- success_criteria updated with 4 new verification gate checklist items
* docs(04-02): complete verification gate workflow steps plan
- SUMMARY.md: verify_docs, fix_loop, scan_for_secrets, and updated verify_only_report
- STATE.md: advanced to ready_for_verification, 100% progress, decisions logged
- ROADMAP.md: phase 4 marked Complete (3/3 plans with SUMMARYs)
- REQUIREMENTS.md: VERF-01, VERF-02, VERF-03 all marked complete
* refactor(profiles): Adds 'gsd-doc-verifier' to the 'MODEL_PROFILES'
* feat(agents): Add critical rules for file creation and update install test
* docs(05): create phase plan for docs output refinement
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(05-01): make scanExistingDocs recursive into docs/ subdirectories
- Replace flat docs/ scan with recursive walkDir helper (MAX_DEPTH=4)
- Add SKIP_DIRS filtering at every level of recursive walk
- Add fallback to documentation/ or doc/ when docs/ does not exist
- Update JSDoc to reflect recursive scanning behavior
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(05-01): update gsd-doc-writer default path guidance to docs/
- Change "No tooling detected" guidance to default to docs/ directory
- Add README.md and CONTRIBUTING.md as root-level exceptions
- Add instruction to create docs/ directory if it does not exist
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(05-02): invert path table to default docs to docs/ directory
- Invert resolve_modes path table: docs/ is primary for all types except readme and contributing
- Add mkdir -p docs/ instruction before agent dispatch
- Update all downstream path references: collect_wave_1, collect_wave_2, commit_docs, report, verify tables
- Update sequential_generation wave_1_outputs and resolved path references
- Update success criteria and verify_only_report examples to use docs/ paths
* feat(05-02): add CONTRIBUTING confirmation gate and existing doc review queue
- Add CONTRIBUTING.md user confirmation prompt in build_doc_queue (skipped with --force or when file exists)
- Add review_queue for non-canonical existing docs (verification only, not rewriting)
- Add review_queue verification in verify_docs step with fix_loop exclusion
- Add existing doc accuracy review section to report step with manual correction guidance
* docs(05-02): complete path table inversion and doc queue improvements plan
- Add 05-02-SUMMARY.md with execution results
- Update STATE.md with position, decisions, and metrics
- Update ROADMAP.md with phase 05 plan progress
* fix(05): replace plain text y/n prompts with AskUserQuestion in docs-update workflow
Three prompts were using plain text (y/n) instead of GSD's standard
AskUserQuestion pattern: CONTRIBUTING.md confirmation, doc queue
proceed gate, and secrets scan confirmation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(05): structure-aware paths, non-canonical doc fixes, and gap detection
- resolve_modes now inspects existing doc directory structure and places
new docs in matching subdirectories (e.g., docs/architecture/ if that
pattern exists), instead of dumping everything flat into docs/
- Non-canonical docs with inaccuracies are now sent to gsd-doc-writer
in fix mode for surgical corrections, not just reported
- Added documentation gap detection step that scans the codebase for
undocumented areas and prompts user to create missing docs
- Added type: custom support to gsd-doc-writer with template_custom
section for gap-detected documentation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(05): smarter structure-aware path resolution for grouped doc directories
When a project uses grouped subdirectories (docs/architecture/,
docs/api/, docs/guides/), ALL canonical docs must be placed in
appropriate groups — none left flat in docs/. Added resolution
chain per doc type with fallback creation. Filenames now match
existing naming style (lowercase-kebab vs UPPERCASE). Queue
presentation shows actual resolved paths, not defaults.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(05): restore mode resolution table as primary queue presentation
The table showing resolved paths, modes, and sources for each doc
must be displayed before the proceed/abort confirmation. It was
replaced by a simple list — now restored as the canonical queue view.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(05): use table format for existing docs review queue presentation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(05): add work manifest for structured handoffs between workflow steps
Root cause from smoke test: orchestrator forgot to verify 45 non-canonical
docs because the review_queue had no structural scaffolding — it existed
only in orchestrator memory. Fix:
1. Write docs-work-manifest.json to .planning/tmp/ after resolve_modes
with all canonical_queue, review_queue, and gap_queue items
2. Every subsequent step (dispatch, collect, verify, fix_loop, report)
MUST read the manifest first — single source of truth
3. Restructured verify_docs into explicit Phase 1 (canonical) and
Phase 2 (non-canonical) with separate dispatch for each
4. Both queues now eligible for fix_loop corrections
5. Added manifest read instructions to all dispatch/collect steps
Follows the same pattern as execute-phase's phase-plan-index for
tracking work items across multi-step orchestration.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(05): update workflow purpose to reflect full command scope
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor(05): remove redundant steps from docs-update workflow
- Remove validate_agents step (if command is available, agents are installed)
- Remove agents_installed/missing_agents extraction from init_context
- Remove available_agent_types block (agent types specified in each Task call)
- Remove detect_runtime_capabilities step (runtime knows its own tools)
- Replace hardcoded flat paths in collect_wave_1/2 with manifest resolved_paths
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(05): restore available_agent_types section required by test suite
Test enforces that workflows spawning named agents must declare them
in an <available_agent_types> block. Added back with both gsd-doc-writer
and gsd-doc-verifier listed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
||
|
|
ef290664cf |
Merge pull request #1372 from gsd-build/fix/agent-install-validation-1371
fix: detect missing GSD agents to prevent silent subagent_type fallback |
||
|
|
bc352a66c0 |
fix: detect missing GSD agents and warn when subagent_type falls back to general-purpose
When GSD agents are not installed in .claude/agents/, Task(subagent_type="gsd-*") silently falls back to general-purpose, losing specialized instructions, structured outputs, and verification protocols. What changed: - Added checkAgentsInstalled() to core.cjs that validates all expected agents exist on disk - All init commands now include agents_installed and missing_agents in their output - Health check (validate health) reports W010 when agents are missing or incomplete - New validate agents subcommand for standalone agent installation diagnostics Fixes #1371 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
db3eeb8fe4 |
feat: agent skill injection via config (#1355)
Add agent_skills config section that maps agent types to skill directory paths. At spawn time, workflows load configured skills and inject them as <agent_skills> blocks in Task() prompts, giving subagents access to project-specific skill files. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
aaaa8e96fe | Harden verify-work checkpoint rendering | ||
|
|
415a094d26 |
refactor: add parseMultiwordArg helper and fix scaffold/milestone arg parsing
Add parseMultiwordArg() to collect multi-token --flag values until the next flag. Replace manual name-collection loops in milestone complete and scaffold cases. Also fixes a bug in scaffold where args.slice() would include trailing flags in the name value. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
5f95fea4d7 |
refactor: extract shared utilities to reduce duplication across codebase
- core.cjs: add filterPlanFiles, filterSummaryFiles, getPhaseFileStats, readSubdirectories helpers; use them in searchPhaseInDir and getArchivedPhaseDirs - gsd-tools.cjs: add parseNamedArgs() helper; replace ~50 repetitive indexOf/ternary patterns in state record-metric, add-decision, add-blocker, record-session, begin-phase, signal-waiting, template fill, and frontmatter subcommands - phase.cjs: decompose 250-line cmdPhaseRemove into renameDecimalPhases(), renameIntegerPhases(), and updateRoadmapAfterPhaseRemoval(); import readSubdirectories - workstream.cjs: import stateExtractField from state.cjs and shared helpers from core.cjs; replace all inline regex state parsing and readdirSync+filter+map patterns All 1062 tests pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |