Commit Graph

2813 Commits

Author SHA1 Message Date
Tom Boucher
908a19cd04 fix: harden installer migration integration 2026-05-11 14:36:14 -04:00
Tom Boucher
4e40ee8b2f fix: harden installer migration paths 2026-05-11 14:29:33 -04:00
Tom Boucher
b20b5fba06 Test(installer): cover full phase 5 runtime installs 2026-05-11 11:00:48 -04:00
Tom Boucher
7110ca8d46 Docs(changeset): set phase 5 PR number 2026-05-11 10:46:22 -04:00
Tom Boucher
a1f00a8a0c Feat(installer): add phase 5 migration guardrails 2026-05-11 10:44:57 -04:00
Tom Boucher
c046dbaacc Test(installer): cover phase 5 migration guardrails 2026-05-11 10:44:47 -04:00
Tom Boucher
f5510fe7e2 Docs(installer): reword Antigravity contract note 2026-05-11 10:04:55 -04:00
Tom Boucher
7fe75c2c3e Feat(installer): harden phase 4 migration integration 2026-05-11 10:02:02 -04:00
Tom Boucher
c29adb01c0 Add changeset for installer migration phase four 2026-05-11 09:13:16 -04:00
Tom Boucher
0b62129847 Wire installer migrations into install flow 2026-05-11 09:11:11 -04:00
Tom Boucher
7a4e5e2efd Add changeset for baseline migration 2026-05-10 23:26:45 -04:00
Tom Boucher
3084ecc2a6 Add first-time installer baseline migration 2026-05-10 23:25:11 -04:00
Tom Boucher
9889d0a9aa docs: add changeset for installer migration phase two 2026-05-10 23:10:10 -04:00
Tom Boucher
3943146484 feat: migrate legacy codex hooks cleanup 2026-05-10 23:08:35 -04:00
Tom Boucher
162935969f docs: add changeset for installer migrations 2026-05-10 22:24:47 -04:00
Tom Boucher
6d33055756 feat: add installer migration framework 2026-05-10 22:23:28 -04:00
Tom Boucher
574d1f448c fix: honor workstream in verify-work init (#3386)
* fix: honor workstream in verify-work init

* fix: define verify-work phase arg
2026-05-10 20:25:42 -04:00
Tom Boucher
570dddd1cd fix: make worktree cleanup fail closed (#3385)
* fix: make worktree cleanup fail closed

* chore: add changeset for worktree cleanup safety

* fix: address worktree cleanup review findings

* docs: label remove-workspace failure block

* fix: initialize worktree manifest before dispatch
2026-05-10 19:48:28 -04:00
Tom Boucher
a51fc86a18 feat: generate release notes from changeset slugs (#3383)
* feat: generate release notes from changeset slugs

* fix: harden release note generator inputs

* fix: address release note review nits
2026-05-10 19:23:22 -04:00
Tom Boucher
cb27c18026 fix(installer): warn on stale gsd-sdk path 2026-05-10 17:40:39 -04:00
Tom Boucher
52337a8861 fix(sdk): honor Codex model overrides in init progress 2026-05-10 17:40:11 -04:00
Tom Boucher
19295f5ab6 fix(gemini): make Windows hooks and agent tools valid 2026-05-10 17:39:06 -04:00
Tom Boucher
ab84538712 fix(phase): prevent roadmap renumber collapse 2026-05-10 17:38:40 -04:00
Tom Boucher
b55848bd7d fix(codex): block unsupported execute worktrees 2026-05-10 17:38:36 -04:00
Tom Boucher
14e47acd9c fix(codex): remove legacy hooks json update hook 2026-05-10 17:38:03 -04:00
Tom Boucher
5541ea3fb4 fix(verifier): require direct probe execution 2026-05-10 17:37:55 -04:00
Jeremy McSpadden
bead19d4da Merge pull request #3380 from gsd-build/codex/fix-roadmap-padded-phase-progress
[codex] Fix roadmap progress sync for padded phase arguments
2026-05-10 14:50:53 -05:00
Jeremy McSpadden
4bcea45108 correct changeset pr number 2026-05-10 14:44:23 -05:00
Jeremy McSpadden
4effa25a06 add changeset for padded phase roadmap fix 2026-05-10 14:43:53 -05:00
Jeremy McSpadden
6ddbb97951 fix roadmap progress padded phase matching 2026-05-10 14:43:53 -05:00
Tom Boucher
4cb5649e8a fix(gemini): drop Agent dispatcher tool (#3349) 2026-05-10 11:20:06 -04:00
Tom Boucher
0afcea0723 fix: block verifier pass on unresolved debt markers (#3343)
* fix: block verifier pass on unresolved debt markers

* chore: add changeset for verifier debt gate

* test: align verifier debt cleanup with standards

* fix: address coderabbit verifier debt findings

* fix: address follow-up coderabbit guard findings

* fix: tighten debt marker matching

* fix: ignore deleted files in debt scan

* docs: document debt scan path contract

* fix: harden debt scan path handling

* fix: tighten debt marker reference parsing

* fix: clarify debt scan failure logging

* fix: preserve verifier debt error contract
2026-05-10 11:19:50 -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
dc003610e2 fix(3323): keep human-needed verification pending (#3339)
* fix: keep human-needed verification pending

* chore: add changeset for human verification gating

* docs: align ship verification status wording
2026-05-09 23:28:25 -04:00
Tom Boucher
d49e8872b5 fix(3317): SDK detect-custom-files now scans skills/ (parity with CJS port) (#3318)
* test(3317): red — SDK detect-custom-files must scan skills/

Mirrors tests/bug-2942-detect-custom-skills.test.cjs on the SDK side.
The SDK's GSD_MANAGED_DIRS array omits 'skills', so user-added skills
under <config-dir>/skills/<name>/ are never returned and get destroyed
on /gsd-update. New vitest covers:

- detects custom skill at skills/<name>/SKILL.md
- does not flag manifest-tracked skill as custom
- still detects custom files under get-shit-done/workflows/ (regression)
- custom_count matches custom_files.length across multiple skills

Fails 2/4 against current SDK source. Will pass after fix.

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

* fix(3317): SDK detect-custom-files now scans skills/ (parity with CJS)

The SDK port of detect-custom-files declared GSD_MANAGED_DIRS without
'skills', while the canonical bin/gsd-tools.cjs port (which the SDK
docstring explicitly cites as its source) had the entry. Because
update.md prefers gsd-sdk over the CJS shim, real-world users with the
SDK installed never had their custom skills detected — the installer's
'Installed N skills to skills/' step then wiped any non-manifest skill
without backing it up to gsd-user-files-backup/. Real-world incident:
skills/gsd-roadmap/SKILL.md (fully user-owned) destroyed during the
1.40.0 → 1.41.0 update, recoverable only via Time Machine.

One-line fix adds 'skills' to the SDK's GSD_MANAGED_DIRS, matching the
CJS source the port was supposed to mirror. The 4 vitest cases added in
the prior commit now all pass.

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

* chore: correct changeset pr number

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 23:28:10 -04:00
Tom Boucher
cbc18f5e3e fix: reconcile planner action contract (#3326)
* fix: reconcile planner action contract

The deep_work_rules workflow block was stronger than the planner agent contract: it required verbatim context copies and self-sufficient action text, so planners were incentivized to inline implementation code. Bound action content to directive prose with concrete identifiers, allow behavior/test acceptance criteria, and pin the cross-file contract with a regression test. Closes #3320.

* chore: add changeset for planner contract fix
2026-05-09 19:27:36 -04:00
Tom Boucher
b5d15fe45d chore(3327): codify recent defect anti-patterns in CONTEXT.md (#3328)
Synthesizes 17 recurring failure modes observed across PRs #3306–#3325
plus sibling fixes (#3240, #3242, #3245, #3257, #3261, #3267, #3286,
#3287). Appends a new machine-oriented section using the same
backtick-keyed `KEY.SUB-KEY=value` format as the existing AI Ops Memory
and Release Notes Standard sections.

Each anti-pattern carries `symptom`, `examples`, `detect`, and
`fix-forward` sub-keys so AI agents can grep deterministically and apply
the remediation without re-deriving the analysis.

Closes #3327

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 19:26:58 -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
2e87c60afc feat(3310): wire remaining ERROR_REASON typed codes into gsd-tools (#3311)
Closes #3310

Wires `ERROR_REASON.SDK_UNKNOWN_COMMAND` and `ERROR_REASON.USAGE` into the remaining untyped error paths in `gsd-tools.cjs` (template, frontmatter, requirements, milestone, uat, todo, workstream, graphify, learnings subcommand routers and `--cwd`/missing-required-arg paths). Tests assert via `JSON.parse(stderr).reason` rather than substring matching on prose. Closure regression guard locks the canonical `{ok, reason, message}` shape for every newly-typed path.

Also moves `--json-errors` activation up to the top of `main()` so `--cwd` validation paths emit JSON rather than plain text when `GSD_JSON_ERRORS=1` is set.
2026-05-09 13:54:06 -04:00
Tom Boucher
eaf20d2cd3 chore: revert redundant CHANGELOG.md row from #3308 (use .changeset/ fragment) (#3313)
* chore: revert redundant CHANGELOG.md row from #3308

PR #3308 added a Shared scanPhasePlans helper row to CHANGELOG.md while
also dropping the canonical .changeset/3262-extract-scan-phase-plans.md
fragment. CONTRIBUTING.md (line 110) prohibits hand-editing CHANGELOG.md
since the release workflow folds .changeset/*.md fragments into the
file at release time — the manual row would duplicate at next release.

Removes only the 4-line Enhancement block added by #3308. The fragment
remains unchanged and is the single source of truth for this entry.

Refs #3262

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

* chore(changeset): add Removed fragment for redundant CHANGELOG row cleanup

Documents the deletion in PR #3313 of the 4-line ### Enhancement block
that #3308 hand-wrote into CHANGELOG.md alongside its canonical
.changeset/3262-extract-scan-phase-plans.md fragment.

Refs #3262

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

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 13:35:57 -04:00
Tom Boucher
15006936b2 ci(3314): add schedule fallback to dismiss-unauthorized-pr-approvals (#3315)
The pull_request_review event path is held in `action_required` whenever
the triggering_actor is an outside collaborator — exactly the case the
workflow exists to handle. The blocked reviewer's own action is what
gates the dismissal that would remove them, so the run never executes.

Add `schedule: */15 * * * *` and `workflow_dispatch` triggers. Scheduled
runs execute as github-actions[bot], bypassing the gate. The script
branches on context.eventName: the review event keeps the single-review
fast path; schedule/dispatch paginates open PRs and reviews, applying
the same role/blocklist check across all APPROVED reviews.

resolveRole() now caches per-login lookups so the schedule path doesn't
re-query the same reviewer once per PR. Concurrency group falls back to
'scheduled' for non-PR events so polls serialize.

Fixes #3314

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 12:04:07 -04:00
Tom Boucher
370033e907 fix(phase-dir): apply project_code prefix in plan-milestone-gaps, import, and add-backlog workflows (PRED.k015) (#3306)
* test(phase-dir): add red test for k015 prefix-drift in plan-milestone-gaps and import workflows (#3298)

Asserts that:
- plan-milestone-gaps.md step 8 does not use bare {NN}-{name} mkdir pattern
- plan-milestone-gaps.md step 8 uses phase.add or expected_phase_dir
- import.md plan_convert does not use bare {NN}-{slug} mkdir pattern
- import.md plan_convert uses expected_phase_dir from init.phase-op

These 5 tests are RED until the fix lands.

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

* fix(phase-dir): add projectCode prefix to phase-dir construction in plan-milestone-gaps and import workflows (#3298)

Both plan-milestone-gaps.md step 8 and import.md plan_convert step were
constructing phase directories using raw {NN}-{name}/{NN}-{slug} template
patterns, bypassing the project_code prefix from .planning/config.json.

Fix: both steps now call `gsd-sdk query init.phase-op <N>` and consume the
`expected_phase_dir` field (which includes the `<CODE>-<NN>-<slug>` prefix
when project_code is set), matching the pattern already established by
PR #3292 for /gsd-discuss-phase and /gsd-plan-phase.

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

* fix(phase-dir): apply project_code prefix to backlog phase dir in add-backlog workflow (k015 sibling, #3298)

Sibling k015 audit found a third drift site: add-backlog.md step 4 was
constructing the 999.x backlog phase directory using raw ${NEXT}-${SLUG}
without applying the project_code prefix from .planning/config.json.

Fix: read project_code via `gsd-sdk query config-get project_code --raw`
and prepend `${CODE}-` when set, matching the pattern used by phase.insert
(which already applies project_code to decimal phases in phase.cjs line 736).

Also extends bug-3298 regression test to cover this third site.

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

* chore(changeset): add changeset for #3298 phase-dir prefix drift fix

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

* chore(changeset): set pr: 3306 in changeset for #3298; resolve stash conflict in live-command-registry.cjs

The conflict was cosmetic (string concat → template literals) introduced by
accidental git stash during test verification. Taking the newer template-literal
form throughout.

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

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 11:47:15 -04:00
Tom Boucher
04031244b8 feat(sdk): add NON_FAMILY_COMMAND_ALIASES to manifest — 14 missing commands (#3305)
* test(3251): red — assert 14 missing commands in command-aliases.generated.cjs

Parametrized test covering all 14 commands from issue #3251. Requires the
CJS manifest and asserts structurally (never greps source). Currently fails
because NON_FAMILY_COMMAND_ALIASES is not exported and all 14 are missing.

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

* feat(3251): add 14 missing commands to command-aliases.generated.cjs

Adds NON_FAMILY_COMMAND_ALIASES export to command-aliases.generated.cjs and
extends sdk/src/query/command-manifest.non-family.ts with the 10 commands that
were registered in static catalogs but absent from the manifest source-of-truth:
- check.decision-coverage-plan / check.decision-coverage-verify
- frontmatter.get
- phase.mvp-mode
- progress.bar
- stats.json
- task.is-behavior-adding
- todo.match-phase
- uat.render-checkpoint
- workstream.list

The other 4 (frontmatter.set, learnings.copy, milestone.complete,
requirements.mark-complete) were already in non-family.ts but unexported.

Generator (sdk/scripts/gen-command-aliases.ts) now produces both the TS and CJS
artifacts including the non-family section, sorted by canonical for determinism.
Freshness check (sdk/scripts/check-command-aliases-fresh.mjs) verifies TS and CJS
non-family parity against the manifest source-of-truth.

Fixes #3251

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

* chore(3251): add changeset and CHANGELOG entry for PR #3305

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

* fix(gen-command-aliases): preserve TS type interfaces and annotations on regen (#3251)

- Add FamilyCommandAlias and NonFamilyCommandAlias interface declarations to tsBody so regen never strips them
- Replace JSON.stringify with single-line compact serialisers for TS output (matches committed file format)
- Apply typed annotations (readonly FamilyCommandAlias[] / readonly NonFamilyCommandAlias[]) to all exported TS constants
- CJS path unchanged: remains untyped pure-JS with JSON.stringify multi-line format
- Regenerate sdk/src/query/command-aliases.generated.ts to sync with updated generator

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:40 -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
b3730c979b fix(intel): gate layout-detection block on framework-repo check (#3290) (#3299)
* test: gsd-intel-updater layout-detection block must be gated or removed (#3290 RED)

Group A asserts the bare `ls -d .kilo ... || echo unknown` detection invocation
is absent or wrapped in a framework-repo gate (fails RED: currently unconditional).
Group B confirms zero downstream consumers of the verdict (passes GREEN: none exist).

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

* fix(intel): gate layout-detection block on framework-repo check (#3290)

The "Runtime layout detection" bash block in gsd-intel-updater ran
unconditionally on every project analysed, emitting a noisy:

  Layout detection returned "unknown" — this project is not a GSD-system
  installation (no `.claude/get-shit-done/` or `.kilo/` runtime root).

for every ordinary (non-GSD-framework) user project. Group B audit confirmed
zero downstream consumers of the verdict outside the file itself.

Fix (option A): wrap the detection bash block in a positive framework-repo
gate — `jq -r '.name' package.json == "get-shit-done-cc"` — so it runs
only when analysing the GSD framework's own repo. The layout table (.kilo/*
paths) is retained for kilo-layout coverage (required by bug #2351 regression
test).

Dead-code vintage: byte-identical from v1.21.0 through v1.41.1 per reporter.

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

* changeset: pr=3299 for #3290

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 11:39:15 -04:00
Tom Boucher
e14ef535aa fix(install): allow codex hooks.state.<key> as regular table (#3285) (#3289)
* test: codex hooks.state.<key> tables must validate as regular tables (#3285 RED)

Drive validateCodexConfigSchema with a fixture containing both [hooks.state]
and [[hooks.SessionStart]] entries. Expect the state tables to pass as regular
tables. Currently fails — validator over-classifies every hooks.* path as AoT.

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

* fix(install): treat codex hooks.state as regular table not AoT (#3285)

validateCodexConfigSchema was over-classifying every hooks.* section header
as an event-handler array-of-tables, rejecting the hooks.state.* namespace
that Codex CLI 0.130.0+ uses for per-hook trust persistence.

Fix:
1. Section-header check: carve out `hooks.state` and `hooks.state.*` from
   the AoT-required rule — only paths that are neither of those still
   require double-bracket form.
2. Parsed-object check: skip the `state` key when iterating Object.entries
   (parsed.hooks) so the "must be array" guard does not fire for the trust
   namespace object.

All other hooks.<EVENT> validation (SessionStart AoT, handler-field placement)
is unchanged.

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

* changeset: pr=3289 for #3285

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

* fix(install): codex hooks.state must be regular-table, reject AoT/scalar (CR finding 1)

- migrateCodexHooksMapFormat: exclude hooks.state and hooks.state.* from
  legacy-map detection so [hooks.state] is never promoted to [[hooks.state]] AoT
- validateCodexConfigSchema: reject [[hooks.state]] / [[hooks.state.*]] AoT at
  section level; reject Array/scalar values at parsed-object level
- Accept only plain-object shape for hooks.state and hooks.state.* (Codex
  CLI 0.130.0+ trust-persistence namespace)

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

* test: assert codex hooks.state trust entry preserved with original values (CR finding 2)

Strengthen post-install preservation assertion to verify the actual trust
entry key and its enabled/trusted_hash values survive — not just that
hooks.state is an object. Add two validator-reject tests for [[hooks.state]]
and [[hooks.state.foo]] AoT forms.

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

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 07:42:22 -04:00