Commit Graph

235 Commits

Author SHA1 Message Date
Tom Boucher
a3ca6ff6d6 feat(3553): Project-Root Resolution Module via generator (Phase 4 of #3524)
Phase 4 of the CJS↔SDK hard-seam migration (parent #3524).
Eliminates the `findProjectRoot` duplication that lived at
bin/lib/core.cjs:74-140 and sdk/src/query/helpers.ts:497-590,
the drift carrier behind historical bugs #1362 and #2561.

- sdk/src/project-root/index.ts — source of truth (120 lines,
  pure-with-sync-fs). Exports findProjectRoot(startDir: string)
  and FIND_PROJECT_ROOT_MAX_DEPTH constant.
- sdk/src/project-root/index.test.ts — 13 vitest pinning fixtures
  covering all four heuristics, the #1362 guard, malformed
  config fallback, empty sub_repos, deep nesting, and depth-limit
  enforcement.
- sdk/scripts/gen-project-root.mjs — generator. Captures
  function body via Function.prototype.toString() from compiled
  sdk/dist/. Emits CJS preamble for destructured node:fs /
  node:path / node:os imports.
- sdk/scripts/check-project-root-fresh.mjs — freshness check.
  Imports the generator function directly (Phase 3's cleaner
  pattern).
- get-shit-done/bin/lib/project-root.generated.cjs — generator-
  emitted CJS mirror.
- tests/project-root-generator.test.cjs — 11 parity assertions
  comparing SDK source and generated CJS for every fixture.

- sdk/src/query/helpers.ts: -127 lines. The 94-line inline
  findProjectRoot plus the FIND_PROJECT_ROOT_MAX_DEPTH constant
  (originally at line 471) replaced by a single re-export:
  `export { findProjectRoot } from '../project-root/index.js';`
  Removed unused `parse as parsePath` import.
- get-shit-done/bin/lib/core.cjs: -83 lines net. The 67-line
  inline findProjectRoot replaced by a single
  `require('./project-root.generated.cjs')`. The detectSubRepos
  helper at lines 40-56 stays (used by loadConfig migration).

- sdk/package.json: gen:project-root + check:project-root-fresh
  scripts.
- package.json: proxy for the freshness check.
- .githooks/pre-commit: drift block.
- .github/workflows/test.yml: drift check step after the
  state-document drift step.
- CONTEXT.md: Project-Root Resolution Module entry.
- docs/INVENTORY.md, docs/INVENTORY-MANIFEST.json:
  +1 module count, +1 row.

- Full suite: 9226/9226 pass (baseline 9215 + 11 new parity
  fixtures).
- SDK vitest: 1804/1804 pass.
- Reader shrink: -127 SDK + -83 CJS = 210 lines of duplication
  deleted across the two Readers. New shared Module is 120 lines.

1. Depth limit canonicalization. CJS findProjectRoot previously
   had no explicit walk-up bound (walked until dir === root or
   homedir). The new Module uses FIND_PROJECT_ROOT_MAX_DEPTH = 10,
   matching the SDK's pre-existing value. Only affects paths
   nested more than 10 levels deep from a .planning/ root — a
   pathological case in practice. None of the existing 22 CJS
   findProjectRoot tests covered this; the new parity test does.
2. platformReadSync → readFileSync. The old CJS findProjectRoot
   used the platformReadSync wrapper from
   shell-command-projection.cjs for reading .planning/config.json,
   which returns null on read failure. The Module uses raw
   readFileSync, which throws — caught by the surrounding
   try/catch that already swallowed errors. Functionally
   equivalent for the existing code path; no test exercises the
   null-return semantic.

Closes #3553.
2026-05-15 10:07:10 -04:00
Tom Boucher
eae1dc6f6b docs: keep inventory module rows sorted 2026-05-15 09:49:19 -04:00
Tom Boucher
fc4d005339 fix: satisfy inventory and changeset CI gates 2026-05-15 09:44:45 -04:00
Tom Boucher
ed8f4c9a31 feat(3544): Workstream Inventory Builder/Reader split (Phase 3 of #3524)
Phase 3 of the CJS↔SDK hard-seam migration (parent #3524).
Introduces the Builder/Reader pattern for paired Modules with
mixed pure-and-I/O concerns — the template for Phase 4 and
follow-up enhancements that migrate other paired Modules.

Phase 1 and Phase 2 migrated Modules where both sides used
character-equivalent logic. Phase 3 introduces the case where
the pure logic is shareable but the I/O is legitimately per-side.
The Builder/Reader split resolves this:

- The Builder is pure — accepts pre-collected data
  (BuilderInputs struct), returns the typed projection. One
  source of truth; one generator-emitted CJS mirror. Drift
  is structurally impossible.
- The Readers are per-side hand-authored Adapters that do the
  fs reads in their native idiom (currently both sync; either
  side can go async later without touching the Builder), then
  delegate to the Builder.

- sdk/src/workstream-inventory/builder.ts — Builder source.
  170 lines. Pure. Exports buildWorkstreamInventory(inputs),
  isCompletedInventory(status), plus the three typed inventory
  interfaces (WorkstreamPhaseInventory, WorkstreamInventory,
  WorkstreamInventoryList).
- sdk/src/workstream-inventory/builder.test.ts — 18 vitest
  pinning fixtures across all status branches, progress-percent
  clamping, active-marker projection, and isCompletedInventory
  classifier.
- sdk/scripts/gen-workstream-inventory-builder.mjs — generator.
  Captures function bodies via Function.prototype.toString();
  emits with the standard GENERATED FILE banner. Includes a
  small `const relative = path.relative;` preamble in the
  output to handle ESM destructured imports in the compiled
  source.
- sdk/scripts/check-workstream-inventory-builder-fresh.mjs —
  freshness check. Imports the generator function directly
  (rather than duplicating logic) — a cleaner pattern than
  Phase 1/2's approach.
- get-shit-done/bin/lib/workstream-inventory-builder.generated.cjs —
  generator-emitted CJS mirror.
- tests/workstream-inventory-builder-generator.test.cjs — 16
  parity assertions confirming CJS-generated output ==
  SDK source output for every fixture.

- bin/lib/workstream-inventory.cjs: 159 → 132 lines.
  Projection logic gone. `inspectWorkstream` and
  `listWorkstreamInventories` collect BuilderInputs via the
  existing sync fs functions and delegate to the Builder.
  `isCompletedInventory` re-exported from the Builder (its
  signature changed from object→string, but no external
  callers exist so the change is safe).
- sdk/src/query/workstream-inventory.ts: 196 → 143 lines.
  Same shape, sync fs (the SDK was already sync — surprise from
  recon). Types re-exported from the Builder.

- sdk/package.json: gen:workstream-inventory-builder and
  check:workstream-inventory-builder-fresh scripts.
- package.json: proxy for the freshness check.
- .githooks/pre-commit: drift block.
- .github/workflows/test.yml: drift check step.
- CONTEXT.md: amended "Workstream Inventory Module" entry
  to document the Builder/Reader split.
- docs/INVENTORY.md, docs/INVENTORY-MANIFEST.json:
  +1 module count, +1 row for the generated builder.

- Full suite: 9229/9229 pass (baseline 9215 + 14 net new from
  the parity assertions).
- Vitest: 18 Builder fixtures pass.
- Reader shrink: -27 lines on CJS, -53 lines on SDK.
- Net diff (modified files only): +68 / -133 = 65-line
  reduction. New files (Builder, generator, freshness check,
  parity test) add ~600 lines of new structured code.

1. `isCompletedInventory` signature changed from
   isCompletedInventory(inventory: object) to
   isCompletedInventory(status: string). Original CJS exported
   the object form but no external caller passed an object —
   they all passed inventory.status. Verified by grep before
   committing.
2. Generator preamble. The compiled ESM uses
   `import { relative } from 'node:path'`, making `relative`
   a free variable in `buildWorkstreamInventory`. The generator
   emits `const relative = path.relative;` so the captured
   function body works in CJS.
3. Freshness check imports the generator. The freshness check
   imports the generator's buildWorkstreamInventoryBuilderCjs()
   function directly rather than duplicating generation logic.
   Cleaner than Phase 1/2; future generators should follow this.

Shareable via the Builder/Reader pattern in future enhancements:
- frontmatter (pure YAML/markdown parsing)
- plan-scan (pure PLAN.md structure parsing)
- decisions (pure decision-record parsing)
- secrets (regex-based detection in text)
- uat (UAT-criteria parsing)

Structural divergence — different approach needed:
- state — sync vs async file ops; mutation paths differ.
- workstream — lifecycle ops; per-side API surface differs.
- phase, roadmap, init, profile-output, template — large
  surfaces; each its own potential enhancement.

None of these is in scope for Phase 3.

Closes #3544.
2026-05-15 09:35:02 -04:00
Tom Boucher
2de2d185fa feat(3536): Configuration Module via shared manifests + generator (Phase 2 of #3524)
Phase 2 of the CJS↔SDK hard-seam migration (parent #3524).
Eliminates the structural drift surface that produced bug class

After this phase, neither bin/lib/ nor sdk/src/ defines
CONFIG_DEFAULTS, VALID_CONFIG_KEYS, DYNAMIC_KEY_PATTERNS, or the
four legacy-key normalizations inline. All come from one canonical
source: the Configuration Module (sdk/src/configuration/index.ts)
+ two JSON manifests (sdk/shared/config-{defaults,schema}.manifest.json).
The CJS mirror is generator-emitted (get-shit-done/bin/lib/configuration.generated.cjs)
with a CI freshness check (sdk/scripts/check-configuration-fresh.mjs).

- sdk/shared/config-defaults.manifest.json — canonical nested defaults,
  union of CJS + SDK keys (includes security_*, post_planning_gaps,
  agent_skills, mode, every git/workflow/hooks sub-section).
- sdk/shared/config-schema.manifest.json — VALID_CONFIG_KEYS array,
  RUNTIME_STATE_KEYS array, DYNAMIC_KEY_PATTERNS array with source
  strings (regex reconstructed at runtime).
- sdk/src/configuration/index.ts — source of truth. Exports
  loadConfig (pure read), normalizeLegacyKeys (pure, idempotent,
  returns Normalization[]), mergeDefaults (deep-merge), migrateOnDisk
  (explicit opt-in disk writeback), plus CONFIG_DEFAULTS,
  VALID_CONFIG_KEYS, RUNTIME_STATE_KEYS, DYNAMIC_KEY_PATTERNS.
- sdk/src/configuration/index.test.ts — 29 vitest pinning tests.
- sdk/scripts/gen-configuration.mjs — generator (Function.prototype.toString()
  inspection of compiled SDK dist, plus brace-balanced text scan for
  internal helpers, matching the Phase 1 pattern).
- sdk/scripts/check-configuration-fresh.mjs — CI freshness gate.
- tests/configuration-generator.test.cjs — 27 parity assertions
  (CJS-generated == SDK source).
- tests/configuration-migrate-config.test.cjs — 3 cases for the new
  gsd-tools migrate-config subcommand.

- bin/lib/core.cjs: CONFIG_DEFAULTS literal now sources values from
  CANONICAL_CONFIG_DEFAULTS (the manifest), with a thin flat
  projection at the load boundary to preserve the existing
  flat-shape return contract for the ~21 CJS test files and 100+
  consumers. All four legacy-key migration blocks (branching_strategy,
  sub_repos, multiRepo, depth — historically lines 351-358, 388-397,
  401-408, 416-423) collapse to a single normalizeLegacyKeys call
  in each code path. The inline platformWriteSync writeback stays
  for now to preserve sync loadConfig semantics; the new async
  migrateOnDisk is reachable via gsd-tools migrate-config.
- bin/lib/config-schema.cjs: 135 → 31 lines. Re-exports from the
  generated Module.
- bin/lib/config.cjs: adds cmdMigrateConfig handler (calls
  migrateOnDisk on the explicit user-driven path).
- bin/gsd-tools.cjs: wires migrate-config into command dispatch.

- sdk/src/config.ts: re-exports CONFIG_DEFAULTS and mergeDefaults
  from the Module. loadConfig now calls normalizeLegacyKeys before
  mergeDefaults (replaces the inline branching_strategy graft).
- sdk/src/query/config-schema.ts: 160 → 36 lines. Re-exports from
  the Module.

- tests/config-schema-sdk-parity.test.cjs: refactored from
  "CJS Set equals SDK Set" (trivially true post-migration) to
  "both sides source from the manifest" — structural plus runtime
  invariant.
- Four other tests that text-grepped source files for valid keys
  (plan-review-convergence, bug-3212, bug-2492, feat-3210) are
  updated to use runtime VALID_CONFIG_KEYS.has() or manifest JSON
  lookups.

- CONTEXT.md: new Configuration Module entry with full Interface
  contract.
- Root package.json: check:configuration-fresh proxy script.
- sdk/package.json: gen:configuration + check:configuration-fresh.
- .githooks/pre-commit: configuration drift block.
- .github/workflows/test.yml: configuration drift step after the
  alias drift check.

- 9201 CJS tests pass (baseline pre-cycle: 9195; +6 net new tests
  across migrate-config + parity refactor)
- 1872 SDK vitest tests pass
- 29 Configuration Module vitest fixtures
- 27 CJS/SDK parity fixtures
- Net diff: +388 / −519 = 131-line reduction across the seven cycles,
  despite adding the new Module, manifests, generator, freshness
  check, and two new test files.

1. SDK CONFIG_DEFAULTS now includes manifest-canonical keys
   (resolve_model_ids: false, context_window: 200000, phase_naming,
   claude_md_path, git.create_tag, workflow.security_*,
   workflow.code_review_*, planning.*, hooks.workflow_guard, ship.*).
   Consumers accessing via [key: string]: unknown index get
   the manifest default instead of undefined.
2. SDK mergeDefaults is now proper recursive deep-merge instead of
   spread-per-section. Overlay { workflow: { research: false } }
   now preserves sibling workflow keys; previously it replaced
   the entire workflow section with only research + the section's
   defaults. Semantically identical for the common case;
   strictly better for partial nested overrides.
3. New gsd-tools migrate-config CLI subcommand for the explicit,
   opt-in on-disk migration path.

Closes #3536.
2026-05-15 00:02:56 -04:00
Tom Boucher
bfd7ddbad3 feat(3530): STATE.md Document Module via generator (Phase 1 of #3524) (#3531)
* feat(3530): STATE.md Document Module via generator (Phase 1 of #3524)

Phase 1 of the CJS↔SDK hard-seam migration (parent #3524).
Converts the hand-synced state-document.cjs/state-document.ts pair
into a generator-driven seam, modeled on the existing
command-aliases.generated.* precedent.

What landed:
- sdk/src/query/state-document.ts is the source of truth.
- sdk/scripts/gen-state-document.ts emits
  get-shit-done/bin/lib/state-document.generated.cjs from the
  compiled SDK dist via Function.prototype.toString() inspection
  for the 7 public exports and 3 internal helpers.
- sdk/scripts/check-state-document-fresh.mjs is the CI freshness
  gate; pre-commit hook also runs it when relevant files change.
- get-shit-done/bin/lib/state-document.cjs is reduced to a one-line
  re-export from state-document.generated.cjs so existing callers
  (state.cjs, workstream-inventory.cjs, init.cjs) need no changes.
- New CI step in .github/workflows/test.yml after the existing alias
  drift check.
- sdk/package.json: gen:state-document, check:state-document-fresh
  scripts. tsx added as devDep.
- Root package.json: proxy script for the freshness check.
- CONTEXT.md: one-sentence amendment on STATE.md Document Module
  recording the source-of-truth file path.

Tests:
- sdk/src/query/state-document.test.ts: 34 vitest fixtures across
  the 7 public exports (TDD pinning safety net).
- tests/state-document-generator.test.cjs: 31 node:test parity
  assertions comparing SDK source vs generated CJS for every
  fixture.
- Full suite: 9177/9177 pass (baseline was 9146; +31 new tests).

One subtle behavior change worth flagging: the old hand-written
state-document.cjs used String(str) coercion inside escapeRegex,
which the SDK source does not. The generator faithfully matches
the SDK (the source of truth per ADR-3524), so the new CJS no
longer coerces non-string input to string before regex-escaping.
No current caller passes non-string input, so no observable
regression in the test suite. Flagged in the PR body for
reviewers.

Closes #3530.

* fix(3530): address state-document review findings
2026-05-14 22:17:20 -04:00
Tom Boucher
e437ded6fc docs(3524): CJS↔SDK hard-seam ADR + phased PRD (#3529)
* docs(3524): propose CJS↔SDK hard-seam ADR + phased PRD

Adds docs/adr/3524-cjs-sdk-hard-seam.md (Proposed) and
docs/prd/3524-cjs-sdk-hard-seam.md (Reference) tracking #3524.
Updates the ADR and PRD index READMEs.

The ADR defines one canonical owner per responsibility across the
CJS (bin/lib/*.cjs) and SDK (sdk/src/**/*.ts) sides, eliminating the
recurring drift bug class (#1535, #1542, #2047, #2638, #2653, #2687,
#2798, #3055, #3523). Three layers: shared data (sdk/shared/*.json),
shared core logic (sdk/src/core/ → dual CJS+ESM build), thin adapters.
Enforcement is layered: build-time grep, type-level contract test,
mutation parity test, CODEOWNERS gate, in-file banner.

The PRD phases the migration in five independently shippable steps —
shared data first (closes constant drift), then config consolidation
(closes #3523 class), then project-root + path projection, then state
and verify handlers, then enforcement hardening + retrospective.

* docs(3524): revise seam ADR + PRD after architecture review

Architecture-review pass (via /improve-codebase-architecture) found
seven deepening opportunities; this commit applies all of them.

1. Re-anchor on the existing generator precedent. The repo already
   has sdk/scripts/gen-command-aliases.ts emitting both
   .generated.ts and .generated.cjs from one TS source, with
   sdk/scripts/check-command-aliases-fresh.mjs as the CI freshness
   gate. The ADR's invented dual CJS+ESM bundler pipeline is
   dropped. Each Shared Module gets one generator script and one
   freshness check, modeled on that precedent.

2. Drop the generic sdk/src/core/ container. The canonical-owner
   table is now indexed by Module, using the CONTEXT.md domain
   vocabulary (STATE.md Document Module, Configuration Module,
   etc.) rather than file-path-based pseudo-modules.

3. Split the coarse "State management" row into three: the pure
   STATE.md Document Module (already a character-identical
   hand-synced pair — perfect Phase 1 target), the Planning
   Workspace Module (defer to ADR-0004), and per-side state I/O
   Adapters (legitimately differ sync vs async).

4. Defer to existing ADRs. Planning Path Projection (ADR-0006),
   Model Catalog (ADR-0003), Planning Workspace (ADR-0004),
   Dispatch Policy (ADR-0001), Shell Command Projection (ADR-0009
   post-Phase 3-4 expansion which absorbed superseded ADR-0010).
   The stale ADR-0010 reference is fixed.

5. Define a Configuration Module entry in CONTEXT.md as a Phase 2
   deliverable, with explicit Interface contract for loadConfig,
   normalizeLegacyKeys, mergeDefaults, migrateOnDisk.

6. Split the Workstream Inventory Module into a pure Builder
   (generated, shared) and per-side Reader Adapters (hand-authored,
   sync vs async). Same pattern generalizes to other paired Modules.

7. Match enforcement to existing scripts. Per-Module freshness
   checks (precedent: check-command-aliases-fresh.mjs), per-Module
   drift lints (precedent: lint-shell-command-projection-drift.cjs),
   and one hand-sync pair lint that blocks the #3523 anti-pattern
   at PR time.

PRD phases reordered: STATE.md Document Module ships first as a
proof of pattern (two identical files become one source plus one
generated artifact). Configuration Module ships second, closing
the #3523 class. Workstream Inventory Builder split third.
Project-Root Resolution fourth. Enforcement and retrospective
fifth.

* docs(3524): expand scope — CJS router delegates to SDK runtime bridge

User flagged that the original "Out of scope" list was my unilateral
scoping call, not theirs. After review, the CJS router consolidation
(formerly out-of-scope item #1) is brought into scope.

ADR additions:
- CJS Command Router Adapter Module row added to canonical-owner
  table. Existing Module (per CONTEXT.md) is amended so the
  per-family `handlers` map delegates to `QueryRuntimeBridge.execute()`
  in-process. Per-side CJS handler files for canonical families
  (state.cjs, verify.cjs, init.cjs, phase.cjs, etc.) shrink to
  delegates or are deleted.
- Per-side I/O Adapter consequence updated to clarify the bridge
  preserves the in-process model. No subprocess hop is added.
- "Out of scope" stripped of router item; CJS-only seam migration
  and verify-Module-first work remain out of scope.

PRD additions:
- New Phase 5: CJS Command Router Adapter delegates to SDK runtime
  bridge, family-by-family, with golden parity matrix per family
  gating each PR.
- Old Phase 5 (enforcement) renumbered to Phase 6, expanded to cover
  Phase 5's parity matrix and runtime-bridge CODEOWNERS.
- Open question #4 added for the synchronous-bridging mechanism
  (`deasync` vs `Atomics.wait` vs sync-handler refactor) — resolved
  in the Phase 5 spike before any family migration begins.
- Open question #5 added for family migration order (recommended:
  smallest read-only family first).
- Risks table expanded with three Phase 5 rows: bridging-mechanism
  uncertainty, observable-output regression, startup-time impact.
- Done-when updated for six phases and five enforcement layers.

Non-goals updated: CJS-only Module migration and verify-Module
deepening remain out of scope. CJS CLI removal explicitly stays
off the table — the external `gsd-tools` contract is preserved.

* docs(3524): address CodeRabbit review

* docs(3524): fix PRD issue reference markdown
2026-05-14 22:08:33 -04:00
Tom Boucher
55c72f47ff Docs: align v1.42.1 release notes format
Closes #3534

Docs-only follow-up to align v1.42.1 release notes with prior stable release format.
2026-05-14 20:49:01 -04:00
Tom Boucher
5c202372ed docs: update v1.42.1 release documentation 2026-05-14 20:42:35 -04:00
Tom Boucher
d4d4178603 Merge pull request #3483 from radioflyer28/feat/agent-launch-reasoning-transport-3474
feat: transport resolved reasoning effort to agent launches
2026-05-14 20:01:32 -04:00
Tom Boucher
585e417f9e fix: harden respect-staged pathspec handling 2026-05-14 19:44:04 -04:00
Tom Boucher
017abd9236 feat(sdk): add --respect-staged opt-in to gsd-sdk query commit --files (#3522)
Closes #3522. When --respect-staged is passed the git add loop is skipped
entirely so per-hunk staging from git add -p is preserved. Default behavior
(full re-stage) is unchanged. The #3061 pathspec invariant holds under both
modes. Nothing-staged within scope returns { committed: false, reason:
'nothing staged' } without error.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 19:08:08 -04:00
Tom Boucher
e0adba7e08 feat(statusline): add opt-in context_position config for narrow terminals (#2937)
Extract composeStatusline() helper from duplicated inline template logic in
runStatusline() and renderStatusline(). Both call sites now route through the
helper, which accepts a position param ('end' | 'front', default 'end').

- 'end' (default) preserves byte-identical output to v1.38.x and earlier
- 'front' renders ctx immediately after model name, before the first │
- Invalid values silently coerce to 'end' at runtime (belt-and-suspenders;
  config-set rejects invalid values upfront via enum validator)

Adds statusline.context_position to VALID_CONFIG_KEYS in both CJS and TS
schemas, enum validator in config.cjs, docs row in CONFIGURATION.md,
and a changeset. Closes #2937.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 15:45:41 -04:00
Tom Boucher
da21edfb59 feat(workflow): add git.create_tag config to disable milestone tagging
Adds boolean config key `git.create_tag` (default: true, fully backcompat)
so projects with their own release flow can disable GSD's automatic
`git tag -a v[X.Y]` on milestone completion. Also adds tag-collision
pre-check to prevent silent failure on re-run. Closes #3086

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 12:06:36 -04:00
Tom Boucher
49e7c48007 feat(execute-phase): classify quota/rate-limit failures across runtimes (#3095) (#3490)
* feat(execute-phase): classify quota/rate-limit failures across runtimes (#3095)

Dispatched executor subagents that die from provider quota or rate-limit
errors currently look identical to a crashed agent to the orchestrator —
so step 7's recovery prompt offers "retry now" when the right action is
"wait for reset and resume". This adds a runtime-agnostic classifier and
wires execute-phase step 7 to it.

- `agent.classify-failure` SDK query returns
  `{class: 'quota-exceeded' | 'classify-handoff-bug' | 'unknown-failure',
    sentinel?, retryAfterSeconds?}`. Sentinels cover Claude Code
  (`usage limit`, `429`), Copilot CLI (`rate_limit`,
  `user_weekly_rate_limited`), Codex (`usage_limit_reached`,
  `too many requests`), and Gemini (`RESOURCE_EXHAUSTED`,
  `exceeded your`).
- `execute-phase.md` step 7 now branches on the class. Quota-exceeded
  presents a wait-for-reset prompt and points at the safe-resume gate
  landing in #3212 instead of re-dispatching a fresh executor.
- `docs/research/provider-rate-limit-signals.md` records the proactive
  (header / SDK event) signals each provider exposes and the upstream
  Claude Code / Copilot / Codex issues blocking hook-side detection —
  the forward path once host runtimes surface them.

Resume-from-partial-worktree and context-load metrics from the original
report are deliberately out of scope; they overlap #3212's
`state.verify-against-disk` work already in flight.

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

* fix(execute): render quota retry hint and refresh alias artifacts

* fix(workflow): restore slash namespace and execute-phase size budget

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 07:46:56 -04:00
radioflyer28
810778e137 fix(sdk): gate reasoning effort by runtime allowlist 2026-05-13 22:27:15 -04:00
Tom Boucher
8b679959cc docs: adopt issue#-prefix naming for ADRs/PRDs to eliminate parallel-developer collisions (#3487)
* docs: adopt issue#-prefix naming for ADRs/PRDs (#3485)

The repo's sequential ADR/PRD numbering convention has produced
recurring collisions when developers compute "next number" locally
and ship in parallel — currently visible on disk as duplicate
docs/adr/0010-*.md and triplicate docs/adr/0011-*.md, plus a stack
of "resolve ADR conflict" commits in git history.

Replace the local-compute convention with issue#-prefix slug naming:

  docs/adr/<issue#>-<slug>.md     (new ADRs)
  docs/prd/<issue#>-<slug>.md     (new PRDs — directory introduced)

GitHub issue numbers are server-assigned and atomic, so the
reservation step the CONTRIBUTING.md issue-first rule already enforces
also produces the artifact ID. One issue = one ADR-or-PRD = one PR.
Same shape as the existing changeset random-name pattern (#2975) for
CHANGELOG.md fragments, applied to a different artifact class.

Migration policy: legacy ADRs 0001-* through 0011-* are preserved
as immutable historical record. The new convention applies only to
ADRs/PRDs created on or after this merge.

Files updated:
- docs/adr/README.md        — naming convention + legacy note + link
- docs/prd/README.md (new)  — seeds the new directory + same convention
- CONTRIBUTING.md           — new "Proposing an ADR or PRD" section
- docs/contributor-standards.md — formalize as contributor requirement

No code surface — docs-only.

Closes #3485

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

* docs(changeset): add Changed fragment for ADR/PRD naming convention (#3487)

Per CONTRIBUTING.md "When unsure whether a change is user-facing, add
the fragment" — the contributor process IS user-facing for the
contributor user class. Drop the no-changelog opt-out, surface the
naming-convention change in the next CHANGELOG so contributors see
it before they hit it as a PR rejection.

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

* docs: address CodeRabbit findings on #3487

- CONTRIBUTING.md: rename heading to "Proposing an ADR or PRD" so its
  GitHub-anchor slug matches the #proposing-an-adr-or-prd link target
  used from docs/adr/README.md, docs/prd/README.md, and
  docs/contributor-standards.md (broken anchors)
- docs/adr/README.md, docs/prd/README.md, docs/contributor-standards.md:
  add `text` language tag to the new naming-convention fenced blocks
  to satisfy markdownlint MD040

Pre-existing untyped fences elsewhere in the touched files are left
alone per CONTRIBUTING.md "no drive-by formatting".

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

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 21:20:08 -04:00
Tom Boucher
75d5ca5875 feat(code-review): integrate fallow structural pre-pass for /gsd-code-review (#3424)
* feat(code-review): add optional fallow structural pre-pass

* fix(ci): sync lockfile for fallow optional binaries

* fix(test): make fallow integration tests cross-platform

* fix(review): require executable fallow binary paths

* docs(review): clarify structural findings usage and size guard

* fix(fallow): preserve line:0, prefer node_modules/.bin, sync SDK twin (H1, M2, N1 from #3424 review)

* fix(workflow): harden fallow pre-pass — exit check, timeout, atomic write, size-guard order (B1, H2-H4, M1, M3 from #3424 review)

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

* fix(deps): pin fallow floor to ^2.70.0 matching lockfile (H7 from #3424 review)

* fix(config): enum-validate fallow.scope/profile + group code_quality.* contiguously (H5, N3 from #3424 review)

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

* docs(fallow): label mcp gate reserved, version-pin install, expand context schema (B3, H8, M4, M8, L1 from #3424 review)

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

* test(fallow): replace source-grep with behavioral tests, expand fixtures, fail-loud tmpdir (B4, H6, L2, L3, M5, M6, N2 from #3424 review)

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

* fix(workflow): escape closing structural_findings tag in JSON payload (CR #3424 inline finding)

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 21:19:47 -04:00
Tom Boucher
1e091d2bcb refactor(shell-projection): remove deprecated wrappers + finalize ADRs (Phase 4, #3468) (#3484)
* refactor(shell-projection): remove deprecated wrappers + finalize ADRs (Phase 4, #3468)

Final phase of the shell-command-projection expansion. Removes the legacy
core.cjs wrappers (`atomicWriteFileSync`, `safeReadFile`, `normalizeMd`)
now that every call site lives behind the seam, plus three Phase-3
stragglers (`graphify.cjs`, `template.cjs`, dead import in
`profile-pipeline.cjs`).

Documentation:
- ADR-0009: addendum noting Phase 1–4 scope expansion (subprocess +
  file I/O ownership), supersession of "does not execute" constraint,
  and resolution of open Q4.
- ADR-0010: status changed to Superseded by ADR-0009 with explanation.
- CONTEXT.md "Shell Command Projection Module" entry already current
  from Phase 1 — no edit needed.

Tests:
- `tests/atomic-write.test.cjs` deleted — wrapper it tested is gone;
  `atomic-write-coverage.test.cjs` (Phase 3) covers platformWriteSync.
- `tests/core.test.cjs::safeReadFile` + `::normalizeMd` describes
  deleted — wrappers are gone.
- `tests/concurrency-safety.test.cjs` normalizeMd suite (behavioral /
  perf / snapshot) repointed via 2-line shim at the seam's
  `normalizeContent` — full regression coverage preserved.

Test result: 9059/9041/18 — exact pre-Phase-4 baseline. All 18
failures are pre-existing path-with-spaces local-env issues.

Closes #3468

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

* refactor(shell-projection): migrate remaining raw fs.writeFileSync sites (Phase 4, #3468)

Sweeps the 7 raw fs.writeFileSync call sites that bypassed the seam through Phase 3,
folding them into platformWriteSync. Net -14 lines: deletes the local writeFileAtomicSync
helper in installer-migrations.cjs and collapses surface.cjs's manual tmp+rename into a
single seam call.

Sites migrated:
- drift.cjs (1) — frontmatter write
- learnings.cjs (1) — learning record JSON write
- install-profiles.cjs (1) — profile marker write (collapsed redundant mkdir)
- gsd2-import.cjs (1) — imported file write (collapsed redundant mkdir)
- surface.cjs (1) — surface state write (replaced manual tmp+rename block)
- installer-migrations.cjs (3) — journal init/finalize + rewrite-json action;
  deleted private writeFileAtomicSync helper and its three call sites

Two sites intentionally retained outside the seam:
- planning-workspace.cjs:241 — workspace lock (wx-flag atomic-create; previously excluded by Phase 3)
- installer-migrations.cjs:220 — install migration lock (fd write into wx-opened handle)
- writeInstallState (installer-migrations.cjs) — strict atomic contract for install state;
  the seam's fallback-to-direct-write on rename failure would silently violate the
  invariant that install state must never be left half-written. Inline tmp+rename with
  rethrow keeps the original guarantee.

Tests: 9059 / 9041 / 18 — exactly the pre-Phase-4 baseline; 18 failures are the
pre-existing path-with-spaces local-env issues, identical files as before.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix(installer-migrations): use strict atomic write for rollback install-state restore

The rollback path was restoring INSTALL_STATE via platformWriteSync, which falls
back to a direct write on rename failure and would silently violate the
half-written invariant that the install-state contract guarantees elsewhere.

Extracts the strict tmp+rename logic from writeInstallState into a shared
atomicWriteInstallState(configDir, content) helper and routes both
writeInstallState and rollbackAppliedMigrationResult through it. Preserves the
existing null-handling (rmSync when previousInstallStateBytes === null) and
existing failure-collection (failures.push on caught errors).

Byte-faithful restore: previousInstallStateBytes is written as-is (no JSON
parse round-trip), preserving the exact prior file contents on restore.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 20:46:02 -04:00
radioflyer28
c20f714d68 docs: document reasoning effort transport 2026-05-13 19:43:42 -04:00
Tom Boucher
ba625c0978 feat(shell-projection): add exec* dispatch and platform* file I/O seam (#3465) (#3470)
* feat(shell-projection): add exec* dispatch and platform* file I/O seam (Phase 1, #3465)

Extends shell-command-projection.cjs with two new sections:

Subprocess dispatch:
- execGit(args, opts) → { exitCode, stdout, stderr }
- execNpm(args, opts) → same; owns shell:true on Windows (npm.cmd)
- execTool(program, args, opts) → same; ENOENT → exitCode 127, no throw
- probeTty(opts) → string | null; returns null on Windows and non-tty

Platform file I/O:
- normalizeContent(filePath, content) → { content, encoding }; pure function;
  .md → full normalizeMd pass; other → CRLF→LF + trailing newline
- platformWriteSync(filePath, content, opts) → ensureDir + normalizeContent + atomic write
- platformReadSync(filePath, opts) → null on ENOENT; throws when required:true
- platformEnsureDir(dirPath) → mkdirSync recursive, idempotent

Absorbs normalizeMd fence-tracking logic from core.cjs (no circular dep).
Existing rendering exports untouched. core.cjs compat exports unchanged until Phase 4.

Updates CONTEXT.md with Shell Command Projection Module canonical definition.
31 new behavioral tests; full suite green.

Closes #3465

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

* docs(context): record shell-projection expansion session learnings

* chore(changeset): add entry for shell-projection I/O seam (#3465)

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

* docs(adr): add ADR-0010 skill-surface budget module and ADR-0011 review default reviewers (Phase 1, #3465)

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

* docs(context): record phase 1 rebase and PR session learnings (#3465)

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

* test(shell-projection): drop substring match on stderr — assert typed shape only

The lint-no-source-grep rule prohibits substring matching on stderr (or any
test-output text). The exitCode === 127 assertion already proves the ENOENT
path; the stderr content was implementation-detail of the OS.

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

* fix(pr3470): address CodeRabbit findings and minimal-core drift

* docs(adr0010): align profile interface with phase-1 scope

* docs(adr): index newly added 0010/0011 ADR drafts in README

enh-3271 invariant requires every file in docs/adr/ to be linked from
the README. Adds entries for the three ADR drafts committed earlier
in this PR.

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

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 17:12:53 -04:00
Tom Boucher
245d5f66a1 feat: add review.default_reviewers config for /gsd-review defaults (#3464)
* feat(review): add review.default_reviewers selection policy

* docs(review): explain default reviewer config and precedence

* chore(changeset): add feature entry for review.default_reviewers

* chore(changeset): set pr field for #3464

* test(review): cover unavailable default-reviewer failure path

* fix(review): sync sdk and inventory parity for default reviewers

* fix(review): use canonical /gsd:review namespace in source
2026-05-13 14:10:15 -04:00
Tom Boucher
d0f916728b feat(skill-surface): install-time profiles + runtime /gsd:surface (#3408) (#3456)
* feat(skill-deps): add requires: frontmatter to all 51 skills with cross-skill references

Mechanical migration from docs/research/data/2026-05-12-skill-audit.json.
Every skill whose body references another GSD skill now declares those
dependencies in `requires:` YAML frontmatter (flow-style array).

Notable: discuss-phase, plan-phase, and execute-phase all reference `phase`,
which confirms the latent gap in MINIMAL_SKILL_ALLOWLIST — `phase` is pulled
by the core loop but was never in the allowlist. The profile closure model
(ADR-0010 Phase 1) resolves this automatically.

Closes part of #3408.

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

* feat(skill-surface-budget): add PROFILES map, resolveProfile, loadSkillsManifest, staging, marker IO

Implements the Skill Surface Budget Module core (ADR-0010, Phase 1):

- PROFILES Object.freeze map: core (6 skills), standard (~13), full ('*')
- loadSkillsManifest: parses requires: frontmatter from commands/gsd/*.md
  into a Map<stem, string[]> without external YAML dep
- resolveProfile({modes, manifest}): computes transitive closure over the
  requires: graph; composable (modes=['core','audit'] unions closures)
- stageSkillsForProfile / stageAgentsForProfile: filesystem staging with
  same exit-cleanup machinery as the legacy stageSkillsForMode
- readActiveProfile / writeActiveProfile: .gsd-profile marker round-trip
- Back-compat shims preserved: MINIMAL_SKILL_ALLOWLIST, isMinimalMode,
  shouldInstallSkill (overloaded), stageSkillsForMode — all legacy tests pass

The phase latent bug is now resolved by closure: discuss-phase, plan-phase,
and execute-phase all require phase, so any profile including any of them
automatically includes phase via transitive closure.

Tests: 22 manifest+resolve, 9 stage, 10 marker (41 new tests, all green).
Back-compat anchor: 80/80 passing.

Closes part of #3408.

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

* feat(skill-surface-budget): add lint-skill-deps.cjs CI gate and fix 19 missed requires: entries

Two lint checks (scripts/lint-skill-deps.cjs):
  a) Frontmatter-body consistency: skill body references must appear in requires:
  b) Profile closure: every requires: dep of any profile skill must be in closure

Running the lint revealed 19 body references missed by the audit JSON (the
audit used static analysis; some bodies have conditional references). Fixed:
  complete-milestone: +audit-milestone, discuss-phase, plan-phase, execute-phase, new-milestone
  fast: +quick
  health: +thread
  map-codebase: +new-project, plan-phase
  new-milestone, new-project, review, ultraplan-phase: +plan-phase
  ship: +verify-work
  sketch, spike: +new-project
  verify-work: +execute-phase
  workstreams: +new-milestone, resume-work

Wired into package.json as lint:skill-deps and added to pretest.
8 fixture-based tests: all green.

Closes part of #3408.

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

* feat(skill-surface-budget): wire --profile= arg, profile marker write/read in bin/install.js

- Add --profile=<name> / --profile=<n1>,<n2> arg parsing (composable).
  Mutually exclusive with --minimal / --core-only (aliases for --profile=core).
  Default (no flag): full.
- Import readActiveProfile / writeActiveProfile from install-profiles.cjs.
- After writeManifest: persist active profile to .gsd-profile marker.
- gsd update path: if no --profile flag given, read existing .gsd-profile
  marker so non-full profiles are not silently re-expanded to full (ADR-0010).
- Update --help block to document --profile= with per-tier token costs.

New test: install-minimal-backcompat.test.cjs (6 tests):
  - PROFILES.core === MINIMAL_SKILL_ALLOWLIST (contract)
  - --minimal writes .gsd-profile marker "core"
  - --profile=core, --profile=standard write correct markers
  - default install writes marker "full"

Closes part of #3408.

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

* chore(changeset): add feat-3408-skill-profiles changelog fragment

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

* feat(install-profiles): derive agents from skill body refs and wire into resolveProfile

Deviation 1 of ADR-0010 phase 1b: tiered profiles (core, standard) now produce
a non-empty agents Set instead of always returning empty. resolveProfile() scans
each skill body for gsd-* agent name references (via new parseCallsAgents()),
stores them in _calls_agents_<stem> manifest entries, and unions them across the
resolved skill closure. stageAgentsForProfile() already checked resolvedProfile.agents
— it now gets real data so tiered profiles install the correct subset of agents
instead of zero.

Closes #3408 (partial — Deviation 1 only)

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

* feat(install): honor .gsd-profile marker on update, add resolveEffectiveProfile/mostRestrictiveProfile

Deviation 2 of ADR-0010 phase 1b: the marker written during installation is now
actually honored when re-running without explicit flags (e.g. gsd update). The
dead-end logging block is replaced by resolveEffectiveProfile(), which picks the
marker profile over 'full' when no explicit --profile= flag was given. The resolved
profile is piped through to all 13 stageSkillsForMode dispatch sites (now _stageSkills)
so updates install only the previously-chosen skill subset.

--minimal retains its back-compat behavior (strict 6-skill allowlist, no closure)
while writing 'core' to the marker. mostRestrictiveProfile() is exported for callers
that need to reconcile disagreeing markers across runtimes (smallest skill set wins).

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

* feat(surface): add CLUSTERS data + state IO module

Add clusters.cjs with 10 named skill groups covering all 66 skills
(verified by surface-clusters.test.cjs). Add surface.cjs with readSurface/
writeSurface atomic IO, resolveSurface, applySurface, and listSurface.
Tests: 17 passing (11 state IO + 6 cluster integrity).

Closes #3408

* docs(adr): add ADR-0011 Skill Surface Budget Module (Phase 1 accepted, Phase 2 amendment)

Records the install-time profile staging decision (Phase 1, landed) and the
runtime /gsd:surface cluster-toggle decision (Phase 2, in flight) as an
amendment. Updates the ADR README index.

Closes #3408

* docs(install-profiles): update module docblock for Phase 2 and ADR-0011

Corrects the ADR reference from 0010 to 0011, documents the three-profile
model and back-compat aliases, adds resolveEffectiveProfile precedence rule,
and notes the companion surface.cjs Phase 2 engine.

* docs(context): add Skill Surface Budget Module canonical entry

Adds the Domain terms entry for the Skill Surface Budget Module covering
both Phase 1 (install-time profiles, .gsd-profile marker) and Phase 2
(runtime /gsd:surface cluster toggles, clusters.cjs, .gsd-surface.json),
per ADR-0011 Consequences requirement.

* feat(surface): add resolveSurface and applySurface engine + tests

Tests cover: profile → surface equivalence, cluster disable/enable,
explicitAdds transitive closure, applySurface file sync (add missing,
remove superseded, preserve non-gsd files), listSurface token cost.
16 new tests passing.

* docs(readme): document --profile= flag and /gsd:surface command

Brief user-facing mention of install profiles (core/standard/full) and the
/gsd:surface slash command in the Commands table. Points to ADR-0011 for details.

* feat(surface): add /gsd:surface slash command runbook

New skill: gsd:surface — runtime profile/cluster toggle without reinstall.
Sub-commands: list, status, profile <name>, disable/enable <cluster>, reset.
Persists state to .gsd-surface.json (independent of .gsd-profile).
Description 96 chars (≤100 limit). lint:descriptions + lint:skill-deps: 0 violations.

* feat(surface): add changeset fragment for /gsd:surface runtime toggle

* feat(surface): add surface skill stem to utility cluster

surface.md is a new skill; add it to the utility cluster so the
surface-clusters.test.cjs coverage invariant stays satisfied.

* docs(adr): fix ADR references to 0011 and record Phase 2 as shipped

ADR-0010 number was already claimed by the file-operation-engine ADR; this
ADR landed as 0011-skill-surface-budget-module.md. Update inline ADR
references in clusters.cjs, surface.cjs, install-profiles.cjs, and the
Phase 2 changeset to ADR-0011. Update the ADR Status section to record
Phase 2 artifacts as shipped on this branch rather than "in progress".

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

* docs(research): port skill-surface-budget memo and audit data

ADR-0011 references docs/research/2026-05-12-skill-surface-budget.md and
docs/research/data/2026-05-12-skill-audit.json, which only existed in the
research worktree. Port both onto this branch so the ADR's References
section resolves and reviewers can read the cluster taxonomy (§3.2),
dependency topology (§3.1), and option grading (§4) that justify Phase 1
and Phase 2 decisions.

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

* fix(registration): register surface/clusters in INVENTORY, COMMANDS, and help.md

- surface.md: convert allowed-tools from inline YAML array to block style
  (was parsed as a single tool name "[Read, Write, Bash]" by test harness)
- docs/INVENTORY.md: add CLI module rows for clusters.cjs and surface.cjs;
  add Commands row for /gsd-surface; bump CLI Modules count 55→57, Commands 66→67
- docs/INVENTORY-MANIFEST.json: add entries for clusters.cjs, surface.cjs,
  and /gsd-surface (filename-based command key)
- docs/COMMANDS.md: add ### `/gsd-surface` heading in Configuration Commands
- get-shit-done/workflows/help.md: add /gsd:surface entry in Configuration section

Fixes registration failures introduced by Phase 2 of #3408.

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

* fix(surface,docs): scrub .claude leakage and escape hypothetical slash tokens

Two PR regressions introduced earlier on this branch:

1. surface.cjs JSDoc comments contained the canonical paths
   (~/.claude/commands/gsd, ~/.claude/agents) as example values, which the
   cline-install leak regex (~\/\.claude\/(?:get-shit-done|commands|agents
   |hooks)) flagged as install-time path leaks. Reworded the docblocks to
   describe runtime-resolved paths without literal ~/.claude tokens.

2. The ported research memo proposed hypothetical Option C dispatchers
   using slash syntax (/gsd:milestone, /gsd:research). The
   docs-parity-live-registry test enforces that every slash-command token
   in docs/ resolves to a real command. Rewrote the Option C sketch
   without the slash prefix and added a clarifying note that the
   dispatchers are illustrative, not shipped.

Targeted tests now pass: tests/cline-install.test.cjs and
tests/docs-parity-live-registry.test.cjs both green.

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

* test: remove raw output/source grep in lint tests

* fix: close coderabbit profile and requires issues

* test: align surface token-cost assertion wording

* fix(install): align core profile alias and defer profile marker write

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 12:45:16 -04:00
Tom Boucher
bf3c736029 feat(shell-projection): centralize managed hook command policy (#3450)
* feat(shell-projection): route persistent PATH hints through projection seam

* refactor(shell-projection): unify managed hook command policy

* fix(install): guard malformed settings hooks during uninstall

* chore(changeset): add fragment for pr 3450

* fix(install): guard malformed settings hook entries
2026-05-12 20:15:43 -04:00
Tom Boucher
7e91a861ee feat: deepen shell command projection seam (#3445)
* feat: deepen shell command projection seam

* chore: add changeset for shell projection seam

* feat: centralize local and portable hook path projection

* docs: avoid prompt-scan false positive in installer migrations

* docs(adr): fix path-style token punctuation
2026-05-12 19:02:18 -04:00
Tom Boucher
c8efbe5382 docs(adr): add shell command projection module ADR 2026-05-12 18:45:35 -04:00
Tom Boucher
98cc1a84c0 fix: scope Windows hook syntax to Gemini runtime (#3438)
* test: cover Windows hook shell drift for Claude (#3413)

* fix: scope Windows hook syntax to Gemini runtime (#3413)

* docs: add changeset for #3413

* docs: set changeset pr for #3413

* fix: route Windows hook formatting through runtime-aware projection seam

* test: cover runtime projection edge cases for Windows hooks

* fix(docs): add shell-command-projection to inventory parity

* docs: align CLI module shipped count after rebase
2026-05-12 17:32:50 -04:00
Tom Boucher
8cd874969c feat(plan-phase): add ADR ingest express path for approved enhancement #3209 (#3421)
* feat(plan-phase): add ADR ingest express path for approved enhancement #3209

* fix(review): address coderabbit doc note and brittle section-number assertion
2026-05-11 23:01:34 -04:00
Tom Boucher
e79c472d7b Feat(ship): add configurable PR body sections (#3391)
* feat: add configurable ship PR body sections

* chore: add changeset for ship PR sections

* docs: avoid prompt scanner trigger in PR body guide

* docs: escape pr body source separator
2026-05-11 15:27:40 -04:00
Tom Boucher
7a0a7f1300 Merge main into phase 5 installer migrations 2026-05-11 15:07:50 -04:00
Tom Boucher
d40c576dd0 Merge main into phase 4 installer migrations 2026-05-11 15:02:10 -04:00
Tom Boucher
b15514dac1 Merge pull request #3400 from gsd-build/codex/installer-migrations-phase-three
Feat(installer): Phase 3 first-time baseline scanner
2026-05-11 15:00:12 -04:00
Tom Boucher
5002d51d92 Docs(installer): reword Antigravity migration contract note 2026-05-11 14:59:33 -04:00
Tom Boucher
908a19cd04 fix: harden installer migration integration 2026-05-11 14:36:14 -04:00
Tom Boucher
a1f00a8a0c Feat(installer): add phase 5 migration guardrails 2026-05-11 10:44:57 -04:00
Tom Boucher
f5510fe7e2 Docs(installer): reword Antigravity contract note 2026-05-11 10:04:55 -04:00
Tom Boucher
0b62129847 Wire installer migrations into install flow 2026-05-11 09:11:11 -04:00
Tom Boucher
3084ecc2a6 Add first-time installer baseline migration 2026-05-10 23:25:11 -04:00
Tom Boucher
3943146484 feat: migrate legacy codex hooks cleanup 2026-05-10 23:08:35 -04:00
Tom Boucher
6d33055756 feat: add installer migration framework 2026-05-10 22:23:28 -04:00
Tom Boucher
19295f5ab6 fix(gemini): make Windows hooks and agent tools valid 2026-05-10 17:39:06 -04:00
Tom Boucher
25fb81d01e feat(3309): workflow.human_verify_mode = end-of-phase (new default; mid-flight opt-back-in) (#3325)
* test(3309): red — workflow.human_verify_mode contract

New behavioral test file covers:
- workflow.human_verify_mode is a recognized config key (VALID_CONFIG_KEYS)
- defaults to 'mid-flight' (preserves current behavior)
- config-set / config-get round-trips for both values
- persists in config.json as string
- planner agent file references the flag with canonical wording, couples
  end-of-phase mode with the rule that checkpoint:human-verify is not
  emitted, and documents the <verify><human-check> deferred-item shape
- verifier agent file references harvesting <verify><human-check> blocks
- references/checkpoints.md documents the cost-control alternative

Source-text assertions on agent .md files are exempted via
allow-test-rule: source-text-is-the-product — those files ARE the
runtime contract loaded by AI runtimes, so asserting their wording is
the only way to verify the agents will respect the flag.

Fails 10/11 against current source. Will pass after the fix.

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

* feat(3309): add workflow.human_verify_mode = end-of-phase opt-out

Each mid-flight checkpoint:human-verify halt costs a full executor
cold-start (CLAUDE.md, MEMORY.md, STATE.md, plan re-read on every
respawn) because subagent context is discarded across the pause. A plan
with N human-verify checkpoints pays the cold-start cost N+1 times. The
reporter (rentanything-nb) measured this at "tens of thousands of tokens"
per round-trip and "hundreds of thousands per week."

This adds workflow.human_verify_mode (default 'mid-flight') with an
'end-of-phase' value that:
- instructs gsd-planner to NOT emit <task type="checkpoint:human-verify">
  tasks; verification details go into a <verify><human-check> sub-block
  on the relevant auto task instead
- instructs gsd-verifier (Step 8) to harvest those <verify><human-check>
  blocks at end-of-phase and merge them into its own human-verification
  list
- the existing human_needed → HUMAN-UAT.md flow in execute-phase.md is
  the single sink — no new file/writer is created

checkpoint:decision and checkpoint:human-action are unaffected — those
gate the work itself, not post-hoc verification.

Surfaces touched:
- bin/lib/config-schema.cjs, bin/lib/config.cjs — register key + default
- sdk/src/config.ts, sdk/src/query/config-schema.ts — SDK parity
- agents/gsd-planner.md — slim Detection section + reference link
- agents/gsd-verifier.md — Step 8 harvest instruction
- get-shit-done/references/planner-human-verify-mode.md — full rules,
  loaded conditionally to keep planner.md under its size budget
- get-shit-done/references/checkpoints.md — surface the alternative
- docs/CONFIGURATION.md — config table row
- docs/INVENTORY.md, docs/INVENTORY-MANIFEST.json — track new reference

Tag name <human-check> chosen instead of <human> to avoid the
prompt-injection scan pattern that flags <system|assistant|human> tags.

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

* chore(3309): align changeset pr: to actual PR number

The pr: field was authored as 3319 (a guess at the next number) before
the PR was opened. Actual PR is #3325.

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

* feat(3309): flip workflow.human_verify_mode default to end-of-phase

Per maintainer direction on PR #3325, end-of-phase is the new project
default. Mid-flight checkpoint:human-verify halts cost a full executor
cold-start (CLAUDE.md, MEMORY.md, STATE.md, plan re-read on respawn) per
round-trip — reported at "tens of thousands of tokens" per round-trip,
"hundreds of thousands per week" on real projects. The cost-control
mode is what new projects should get out of the box.

mid-flight remains a one-line opt-back-in via:

    gsd config-set workflow.human_verify_mode mid-flight

Behavior change for existing projects: the new default takes effect
when .planning/config.json is rewritten (config-set, fresh project).
Existing in-flight PLAN.md files with checkpoint:human-verify tasks
continue to work in either mode — the flag only changes what the
planner emits next time it runs.

Surfaces updated:
- bin/lib/config.cjs, sdk/src/config.ts — default flipped
- sdk/src/config.ts docstring — describes new default + opt-back-in
- agents/gsd-planner.md — Detection section explains new default
- references/planner-human-verify-mode.md — reordered modes; added
  guidance on when to opt back into mid-flight
- references/checkpoints.md — surface the default flip and the why
- docs/CONFIGURATION.md — table row reflects new default + reason
- tests/feat-3309-human-verify-mode.test.cjs — default test asserts
  end-of-phase
- .changeset/fierce-geese-march.md — describes the default flip and
  the migration semantics

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

* fix: address human verify mode review

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 23:29:11 -04:00
Tom Boucher
e7942c21b3 fix: add executor stall recovery contract (#3329)
* fix: add executor stall recovery contract

* chore: add changeset for executor recovery

* chore: keep execute phase within size budget
2026-05-09 23:28:52 -04:00
Tom Boucher
26dcdb1ad0 Refactor SDK-first architecture seams (#3316)
* refactor: tighten sdk-first architecture seams

Refs #3312

* refactor: finish state document seam cleanup

Refs #3312

* test: harden minimal install cleanup assertion

* ci: support sdk-scoped package lock

* fix(3316): restore root package-lock.json and align changeset pr ref

Reverts dec57a83 ("ci: support sdk-scoped package lock") and restores
the root package-lock.json that c249d34d deleted. The deletion was the
wrong direction:

- The root package.json declares its own runtime and dev deps
  (@anthropic-ai/claude-agent-sdk, ws, c8). Without a root lockfile,
  `npm install --no-package-lock` resolves whatever satisfies semver at
  install time — CI today and CI in six months can install different
  transitive trees, defeating reproducibility.
- The lockfile has been part of every release on this repo (long
  history on main); removing it loses the npm audit / Dependabot
  target without compensating benefit.
- The CI workaround pattern (cache-dependency-path: sdk/package-lock.json
  + `npm install --no-package-lock`) papered over the symptom rather
  than fix the cause.

Also fix the changeset pr: from 3312 (issue) to 3316 (PR). CONTEXT.md
flags this exact failure mode as a recurring CodeRabbit finding.

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

* fix: address coderabbit review findings

* fix: close remaining coderabbit threads

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 14:21:42 -04:00
Tom Boucher
31e2c22309 feat(3255): add --json-errors structured error mode to gsd-tools (#3304)
* test(3255): add red/green tests for --json-errors structured error mode

Ten tests covering the --json-errors mode contract:
- Unknown command → sdk_unknown_command
- Dotted unknown command → sdk_unknown_command
- Missing --pick value → usage
- Config key not found → config_key_not_found
- Unknown subcommand → sdk_unknown_command
- GSD_JSON_ERRORS=1 env var activation
- Successful command unaffected
- Stable error shape ({ok, reason, message})
- Single error line per invocation
- Unknown flag → usage

All assertions use JSON.parse on stderr captures, never .includes() on
text (#2974 / CONTRIBUTING.md "Prohibited: Raw Text Matching" rule).

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

* feat(3255): add typed ERROR_REASON codes and GSD_JSON_ERRORS env var support

- Destructure ERROR_REASON from core in gsd-tools.cjs
- Add GSD_JSON_ERRORS=1 env var as alternative to --json-errors CLI flag
- Pass ERROR_REASON.SDK_UNKNOWN_COMMAND to unknown top-level command default path
- Pass ERROR_REASON.SDK_UNKNOWN_COMMAND to unknown intel subcommand path
- Pass ERROR_REASON.USAGE to --pick missing value error path
- Pass ERROR_REASON.USAGE to --version flag rejection path

All ten tests in feat-3255-json-errors-mode.test.cjs pass.

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

* docs(3255): add json-errors taxonomy doc, changeset, and CHANGELOG entry

- docs/json-errors.md: full error code taxonomy, wire format spec, and
  test-authoring guidelines for the --json-errors mode
- .changeset/gentle-tigers-roar.md: changeset fragment (pr will be updated
  after PR is opened)
- CHANGELOG.md: Unreleased → Added entry for the new structured error mode

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

* chore: update changeset PR number to 3304

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

* fix(gsd-tools): document --json-errors in usage/help text (#3255)

Add [--json-errors] to the TOP_LEVEL_USAGE synopsis line and introduce a
"Global flags:" section describing all four global flags (--raw, --pick,
--cwd, --ws) plus --json-errors with its GSD_JSON_ERRORS=1 env-var
alternative, so operators can discover the flag via `gsd-tools --help`.

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

* chore: drop redundant CHANGELOG.md edit (use .changeset/ fragment per CONTRIBUTING.md)

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 11:46:34 -04:00
Tom Boucher
706ddb5ea5 docs(adr): add docs/adr/README.md index and structural ADR test (#3302)
* docs(adr): add docs/adr/README.md index and structural ADR test (#3271)

- Add docs/adr/README.md as an indexed entry point linking all 7 ADRs
- Add tests/enh-3271-sdk-adr-structure.test.cjs: structural assertions that
  ADR 0005 and 0006 exist, have required headings and Status/Date metadata,
  and that README links every ADR file by filename
- Update CHANGELOG.md with Enhancement entry
- Add .changeset/3271-sdk-adr-structure.md

ADRs 0005 (SDK architecture seam-map) and 0006 (planning-path projection
module) already landed on main. This PR completes issue #3271 by adding the
README index and the structural test gate that enforces ADR completeness
going forward.

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

* chore: set changeset pr: 3302

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

* fix(test): exclude self-reference from ADR 0005 cross-ref count (#3271)

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

* chore: drop redundant CHANGELOG.md edit (use .changeset/ fragment per CONTRIBUTING.md)

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 11:46:28 -04:00
Tom Boucher
1a49d2fcfc feat(phase-plans): extract shared scanPhasePlans helper (k014) (#3308)
* test(phase-plans): red — shared scanPhasePlans contract + parity across call sites (#3262)

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

* feat(phase-plans): extract shared scanPhasePlans helper (k014) (#3262)

Eliminates four divergent copies of the plan-scan algorithm:
- roadmap.cjs:countPhasePlansAndSummaries (root call site)
- state.cjs:buildStateFrontmatter (1 of 3)
- state.cjs:cmdStateValidate (2 of 3)
- state.cjs:cmdStateSync (3 of 3)
- init.cjs:listPhasePlanFiles / listPhaseSummaryFiles

New bin/lib/plan-scan.cjs exports scanPhasePlans(phaseDir) → {
  planCount, summaryCount, completed, hasNestedPlans,
  planFiles, summaryFiles
}

Divergences resolved:
- roadmap.cjs used a broad isPlanFile (any .md containing PLAN in name,
  matching the extended layout 5-PLAN-01-setup.md); canonical helper
  adopts this wider pattern as the reference implementation.
- state.cjs used a strict endsWith(-PLAN.md) filter, missing extended-
  layout root files; now unified with roadmap.cjs semantics.
- init.cjs listPhasePlanFiles used ^PLAN-\d+ for nested, missing
  the -PLAN-\d+ variant state.cjs also matched; helper includes both.
- pre-bounce exclusion broadened to /.pre-bounce.md$/i (any pre-bounce
  file), not just -PLAN.*\.pre-bounce\.md (roadmap form) or flat
  .pre-bounce.md (state form).
- OUTLINE exclusion broadened to /-OUTLINE\.md$/i to catch both
  flat (-PLAN-OUTLINE.md) and nested (PLAN-01-OUTLINE.md) forms.

Sibling audit: no 5th call site found. phase.cjs:looksLikePlanFile is
a diagnostic probe for non-canonical naming (not a counter) — left
in place per its distinct purpose.

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

* chore(changelog): add entry for #3262 scanPhasePlans extraction

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

* chore(changeset): add changeset fragment for #3262

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

* docs(inventory): add plan-scan.cjs row to INVENTORY.md CLI Modules table (#3262)

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

* fix(3262): update bug-3128 test + INVENTORY counts for plan-scan.cjs

- Update tests/bug-3128-roadmap-plan-count-slug-layout.test.cjs to verify
  that roadmap.cjs delegates to plan-scan.cjs (require check) and that the
  extended filter lives in plan-scan.cjs as isRootPlanFile with /PLAN/i
- Bump docs/INVENTORY.md CLI Modules headline from 46 to 47 (plan-scan.cjs)
- Regenerate docs/INVENTORY-MANIFEST.json to include cli_modules/plan-scan.cjs

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

* fix(3262): migrate two missed call sites to scanPhasePlans (k014)

- init.cjs cmdInitExecutePhase: replace inline /-PLAN\.md$/i filter
  with listPhasePlanFiles(path) to honour nested, extended-layout, OUTLINE
  and pre-bounce exclusions (CR finding)
- state.cjs cmdStateUpdateProgress: replace dual /-PLAN\.md$/i and
  /-SUMMARY\.md$/i filters with scanPhasePlans() so the progress-bar
  body field uses the same counts as buildStateFrontmatter frontmatter

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

* fix(3262): correct INVENTORY-MANIFEST.json to tracked files only

Remove 3 untracked local entries from cli_modules so the manifest matches
what CI sees (47 tracked .cjs files, not 50 local). Previous regeneration
ran against the local filesystem which included cjs-command-router-adapter.cjs,
state-document.cjs, and workstream-inventory.cjs (all untracked on this branch).

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

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 11:39:31 -04:00
Tom Boucher
2436da0486 docs(3232): codify contributor standards (CONTEXT.md, ADRs, AI-agent work) (#3301)
* docs(3232): add contributor-standards.md (CONTEXT.md + ADR + AI-agent pillars)

Codifies contributor expectations around the three pillars called out in
issue #3232: CONTEXT.md format and governance, ADR naming/status/amendment
conventions, and AI-agent-assisted work requirements (worktree isolation,
TDD discipline, adversarial review, CR-loop). Updates CONTRIBUTING.md to
link the new doc and adds an AI-agent bullet to the architecture-standards
summary. Structural test asserts all three pillars and the CONTRIBUTING.md
cross-link exist.

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

* chore: add changeset for PR #3301 (contributor-standards)

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

* docs: fix worktree example to use generic branch name placeholder

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

* fix(docs): add lang tags to fenced code blocks (MD040) (#3232)

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

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 11:39:24 -04:00
Tom Boucher
3aaed8f5d7 test: replace deny-list parity tests with polarity-inverted live-registry (#3049) (#3284)
* test: reproduce Windows SDK not found after fresh npx install (#3211)

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

* test: red — docs-parity live-registry tests fail against stub helper (#3049)

Adds:
- tests/helpers/live-command-registry.cjs (stub: returns empty Set)
- tests/docs-parity-live-registry.test.cjs (new polarity-inverted test)
- tests/fixtures/live-command-registry/ (fixture .md files)

All parity and helper-contract tests fail because the stub returns an
empty registry. This is the intentional RED state before GREEN
implementation.

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

* feat(test-helpers): live-command-registry derives canonical tokens from commands/gsd/*.md (#3049)

Implements GREEN phase:
- tests/helpers/live-command-registry.cjs: walks commands/gsd/*.md, parses
  YAML frontmatter name: field, emits /gsd-slug, /gsd:slug, $gsd-slug per
  command. Memoized per process. Fails loud on malformed frontmatter (k302).
- tests/docs-parity-live-registry.test.cjs: updated with INTERNAL_COMPONENT_SLUGS
  exemption for path-component and placeholder tokens (gsd-build from GitHub
  org URLs, gsd-workspaces from ~/gsd-workspaces/ paths, gsd-tools from
  bin/gsd-tools.cjs paths, etc.)

Docs drift caught and fixed:
- ns-* rename: /gsd-ns-workflow→/gsd-workflow etc. in COMMANDS, FEATURES,
  INVENTORY, USER-GUIDE (6 commands across 4 English files)
- /gsd-scan → /gsd-map-codebase --fast (FEATURES, INVENTORY, USER-GUIDE)
- /gsd-note → /gsd-capture (FEATURES, issue-driven-orchestration, ja-JP, ko-KR)
- /gsd-do → /gsd-fast (FEATURES, ja-JP, ko-KR)
- /gsd-from-gsd2 → /gsd-import --from-gsd2 (CLI-TOOLS, FEATURES, INVENTORY)
- /gsd-verify-phase → /gsd-validate-phase (STATE-MD-LIFECYCLE)
- /gsd-settings-integrations → /gsd-settings or /gsd-config --integrations (CLI-TOOLS)
- /gsd-dev-preferences removed from profile-user artifact lists (AGENTS, COMMANDS,
  FEATURES in English, ja-JP, ko-KR)
- /gsd-select-framework removed from gsd-framework-selector spawner list
  (AGENTS, INVENTORY)

All 28 new tests pass.

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

* refactor(test): replace deny-list parity tests with polarity-inverted live-registry approach (#3049)

- Delete bug-3010-reapply-patches-references.test.cjs (hardcoded deny-list)
- Delete bug-3029-3034-stale-command-routes.test.cjs (hardcoded deny-list)
- Delete bug-3042-3044-research-flag-and-stale-refs.test.cjs (deny-list + frontmatter checks)
- Add tests/skill-frontmatter-contract.test.cjs (frontmatter structural checks extracted from deleted file)
- Update tests/commands-doc-parity.test.cjs to derive slug from name: frontmatter field
  instead of filename, so ns-* commands resolve to their actual deployed tokens

Closes #3049

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

* test: annotate commands-doc-parity with source-text-is-the-product exemption (#3049 lint fix)

The readFileSync on commands/gsd/*.md reads product markdown whose deployed
text IS what the user sees — content.startsWith('---') detects YAML frontmatter
in those files, not source-code structure. Add the allow-test-rule exemption
matching the same rationale used in docs-parity-live-registry.test.cjs.

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

* test: walk docs/** recursively to cover nested locale trees (CR finding 7)

Replaced the non-recursive listMdFiles() with a hand-rolled DFS walker
compatible with Node 20+. Surfaces unreadable-directory errors as stderr
warnings (PRED.k302) rather than silently skipping.

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

* test: annotate live-command-registry helper and commands-doc-parity with source-text exemptions (CR findings 6, 8)

Adds allow-test-rule comments to suppress lint-no-source-grep false
positives on YAML frontmatter structure checks in both files.

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

* test: anchor --research-phase assertions to arg-parsing section and verify combined refresh (CR findings 9, 10)

Finding 9: scopes --research-phase check to within 1200 chars of the flag
description section header, preventing false positives from prose mentions.

Finding 10: tightens the force-refresh assertion to require BOTH --research
and force/refresh semantics within the --research-phase description section,
verifying the combined-mode contract rather than standalone --research presence.

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

* test: fix execSync mock to accept opts parameter, forward to saved implementation (CR finding 5)

The mock at line 212 dropped the options parameter when delegating to
savedExecSync. Updated to (cmd, opts) signature and pass opts through.

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

* docs: correct routing entrypoint, --fast default, /gsd-review collision, verifying-stage mapping (CR findings 1-4)

Finding 1: Change Freeform Routing command from /gsd-fast to /gsd-progress --do.
/gsd-fast is the inline trivial-task executor, not the routing entrypoint.

Finding 2: Clarify that /gsd-map-codebase --fast REQ-SCAN-02 default (tech+arch)
runs as a single combined-focus agent, resolving the contradiction with REQ-SCAN-01.

Finding 3: Rename the namespace router /gsd-review to /gsd-quality across all docs,
command file, and help.md to eliminate the naming collision with the concrete
cross-AI peer-review command (review.md, name: gsd:review).

Finding 4: Replace /gsd-validate-phase with /gsd-verify-work in the STATE-MD-LIFECYCLE.md
verifying-stage table. /gsd-validate-phase is the retroactive Nyquist-validation
flow, not the normal phase-verification step.

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

* docs+test: fix locale doc drift surfaced by recursive walker (CR finding 7 follow-up)

The recursive listMdFiles() walker newly covered docs/**/*.md subdirs.
Stale command references in locale docs are now caught and fixed:

- docs/zh-CN/references/model-profiles.md: remove /gsd-set-profile (deleted command);
  config.json is the current mechanism
- docs/zh-CN/references/ui-brand.md: remove /gsd-alternative-1/2 template placeholders
- docs/{ja-JP,ko-KR,pt-BR}/superpowers/specs/2026-03-20-*: replace
  /gsd-new-workspace, /gsd-list-workspaces, /gsd-remove-workspace with
  /gsd-workspace --new / --list / --remove (consolidated in #2790)

Also adds smoke- and alternative-{1,2} to INTERNAL_COMPONENT_SLUGS (filesystem
path and template placeholder patterns, not slash commands) and introduces
listEnglishMdFiles() to scope the English parity check to docs/ excluding
locale subdirectories (which have their own per-locale describe blocks).

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

* docs: add bash language tag to fenced code blocks in ja-JP and ko-KR workspace specs (CR round 2)

Satisfies MD040 fenced-code-language requirement. These blocks contain
shell commands and were missing the language specifier.

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

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 02:49:19 -04:00
Tom Boucher
3ce6a12f30 docs: add docs/RELEASE-v1.42.0-rc.1.md (new features only) (#3280)
Companion docs page for the v1.42.0-rc.1 release tag, scoped to the new
features in 1.42.0:

- Security: package legitimacy gate against slopsquatting (#3215) — three
  layers across researcher, planner, executor; plus npx --yes hardening
  and graceful degradation when slopcheck is unavailable
- Architecture: SDK package seam deepened; runtime-global skills policy
  converged into a single Module (#3238)
- Architecture: phase lifecycle seams deepened — extracts Phase Numbering
  Policy, Phase Filesystem Adapter, and Phase Roadmap Mutation modules
  from phase-lifecycle.ts (#3267)

Fix list is intentionally omitted — those fixes are rolled up from
v1.41.1 and listed on the v1.41.1 release page; this doc links out to
both v1.41.1 and v1.41.0 instead of restating them.

Format follows the established docs/RELEASE-v*.md pattern (compact
one-paragraph intro, categorized sections, install footer, link-out to
prior train).

Closes #3279
2026-05-09 01:10:31 -04:00