diff --git a/.changeset/1000-intel-updater-canonical-filenames.md b/.changeset/1000-intel-updater-canonical-filenames.md deleted file mode 100644 index e3f6de178..000000000 --- a/.changeset/1000-intel-updater-canonical-filenames.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1037 ---- -**`gsd-intel-updater` now writes the canonical intel filenames the `gsd-tools intel` CLI actually reads** — the agent was instructed to emit short names (`files.json`, `apis.json`, `deps.json`) and a markdown `arch.md`, but the intel library reads only `file-roles.json`, `api-map.json`, `dependency-graph.json`, and `arch-decisions.json` (JSON). After `/gsd:map-codebase --query refresh` the output was orphaned, so `intel status`/`validate` reported the files missing and `intel query` returned nothing. The agent now emits the canonical long names and structured `arch-decisions.json`. (#1000) diff --git a/.changeset/1004-installer-http-hook-presence.md b/.changeset/1004-installer-http-hook-presence.md deleted file mode 100644 index 3a763f4a9..000000000 --- a/.changeset/1004-installer-http-hook-presence.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1032 ---- -**Installer no longer appends a duplicate managed hook when it is registered via an HTTP route** — a hook re-registered as a `type:"http"` entry (local hook-server routing) carries its identity only in `url`, which the installer's presence check ignored, so a stock command duplicate was appended on every install/update and the hook ran twice per event. The presence check now also inspects `h.url`. (#1004) diff --git a/.changeset/1012-fallow-real-cli-and-schema.md b/.changeset/1012-fallow-real-cli-and-schema.md deleted file mode 100644 index 267e154b9..000000000 --- a/.changeset/1012-fallow-real-cli-and-schema.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1044 ---- -**`/gsd-code-review`'s fallow structural pre-pass now actually runs and delivers findings** — it invoked fallow with flags no published fallow version accepts (`--json`, `--profile`, `--stdin-files`), so the pre-pass failed on every run and silently degraded (the structural-findings feature never delivered on any fallow version). It now uses fallow's real CLI (`audit --format json --quiet`, `--changed-since` for phase scope, and `--max-crap` mapped from the `code_quality.fallow.profile` preset: minimal→50, standard→30, strict→15), treats fallow's exit code 1 ("issues found") as a successful run instead of a crash (gating on a valid JSON report, not the exit code), and normalizes fallow's real `audit --format json` schema (`dead_code.*`, `duplication.clone_groups`) into the reviewer's `` contract. The report normalizer — previously dead code parsing a schema fallow never shipped — is wired to the real schema and exercised against real fallow output. (#1012) diff --git a/.changeset/1013-worktree-baseref-user-global-cascade.md b/.changeset/1013-worktree-baseref-user-global-cascade.md deleted file mode 100644 index ad0ce36c2..000000000 --- a/.changeset/1013-worktree-baseref-user-global-cascade.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1038 ---- -**`worktree base-check` now honors a user/global `worktree.baseRef:"head"` (and `CLAUDE_CONFIG_DIR`)** — base-check resolved `baseRef` from the project checkout's `.claude/` only, so a machine-wide `head` set via `/config` (the layer the harness itself honors) was invisible. On any phase/feature lane it returned `shouldDegrade:true` and `execute-phase` silently forced sequential execution, losing the parallel worktree execution the user configured. Resolution now falls back to the user/global `settings.json` (via `getGlobalConfigDir('claude')`, honoring `CLAUDE_CONFIG_DIR`) below the existing project-local and project-shared layers. (#1013) diff --git a/.changeset/1014-anthropic-fable-model-config.md b/.changeset/1014-anthropic-fable-model-config.md deleted file mode 100644 index fbc39da13..000000000 --- a/.changeset/1014-anthropic-fable-model-config.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Changed -pr: 1015 ---- -Added an opt-in `anthropic-fable` model policy provider preset for Claude Fable 5 high-budget routing while preserving the existing Anthropic Opus 4.8 defaults and `anthropic` provider preset. (#1014) diff --git a/.changeset/1041-agents-runtime-resolver-all-cli.md b/.changeset/1041-agents-runtime-resolver-all-cli.md deleted file mode 100644 index 6310097f6..000000000 --- a/.changeset/1041-agents-runtime-resolver-all-cli.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1045 ---- -**Agent SDK/state/commit steps now resolve `gsd-tools` on shim-only installs for every runtime** — source `agents/*.md` (`gsd-planner`, `gsd-executor`, `gsd-verifier`, `gsd-plan-checker`, …) invoked bare `gsd-tools …`, which fails with `command not found` on shim-only installs where the binary is only reachable as `/gsd-core/bin/gsd-tools.cjs` and is not on `PATH`. The agent then silently skipped init/state/validate/commit ceremony. #725 fixed only Codex's conversion layer; the source agents were never migrated, so the bug persisted on Claude Code and every other runtime that consumes the source agents directly. All 12 `gsd-tools`-calling agents now carry the canonical multi-runtime `gsd_run` resolver (the same preamble the workflow launchers use — covering claude/codex/cursor/gemini/copilot/windsurf/augment/trae/qwen/cline/opencode/kilo/hermes/antigravity homes), `gsd-phase-researcher`'s stale claude-only resolver is upgraded to the canonical one, and the launcher-parity + bare-call regression guards are extended to `agents/` so no runtime can silently regress. (#1041) diff --git a/.changeset/1085-devin-skills-workspace.md b/.changeset/1085-devin-skills-workspace.md deleted file mode 100644 index a3e7f7a1d..000000000 --- a/.changeset/1085-devin-skills-workspace.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Changed -pr: 1093 ---- -**Windsurf/Devin workspace skills now install to the canonical `.devin/skills/` directory** — fresh workspace installs write skills under `.devin/skills/` (Devin Desktop's documented preferred location) instead of `.windsurf/skills/`; the legacy `.windsurf/skills/` layout is still recognized. The global `~/.codeium/windsurf/skills/` path is unchanged. (#1093) diff --git a/.changeset/1098-generate-claude-md-guard-redirect.md b/.changeset/1098-generate-claude-md-guard-redirect.md deleted file mode 100644 index 8b1788896..000000000 --- a/.changeset/1098-generate-claude-md-guard-redirect.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1118 ---- -**`gsd-tools generate-claude-md` no longer clobbers a hand-crafted `CLAUDE.md`, and defaults the Claude-runtime output to `./.claude/CLAUDE.md`** — `/gsd-new-project` wrote a repo-root `CLAUDE.md` full of broad project documentation, overwriting/diluting an existing hand-authored instruction file. Now: (1) an existing instruction file that contains no GSD section markers (a hand-crafted file) is left untouched and the command reports `action: "skipped"` — pass `--force` to overwrite intentionally (the flag was already parsed but ignored); (2) the default output for Claude-family runtimes is `./.claude/CLAUDE.md` (a valid project-scoped memory location) instead of repo-root `./CLAUDE.md`, so generated content does not pollute a repo-root file. The config default (`claude_md_path`), the project config template, and the new-project workflow are aligned to the new location. Codex projects still write `AGENTS.md`. (#1098) diff --git a/.changeset/1101-record-session-session-continuity-heading.md b/.changeset/1101-record-session-session-continuity-heading.md deleted file mode 100644 index 28e478f9c..000000000 --- a/.changeset/1101-record-session-session-continuity-heading.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1113 ---- -**`state record-session` updates an existing `## Session Continuity` section in place instead of appending a duplicate `## Session` block** — on a freshly bootstrapped project (workstream / gsd2-import / new-project templates all emit `## Session Continuity`), the auto-create path recognised only the normalized `## Session` heading, so it appended a second session block. It now inserts only the missing canonical fields after the `## Session Continuity` heading, preserving the heading and any existing prose, and the snapshot / frontmatter readers recognise that heading. (The originally reported `recorded:false`-yet-mutated symptom was already resolved by #944/#948.) (#1101) diff --git a/.changeset/1103-annotate-deps-missing-newline.md b/.changeset/1103-annotate-deps-missing-newline.md deleted file mode 100644 index 0c99610f9..000000000 --- a/.changeset/1103-annotate-deps-missing-newline.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1111 ---- -**`roadmap annotate-dependencies` no longer fuses the preceding summary line onto the `Plans:` header** — when the match regex's `(?:^|\n)` anchor consumed a leading newline (mid-string match), the replacement dropped it, producing corrupted output like `**Plans:** 3 plansPlans:`. The replacement now re-emits the leading newline when present. (#1103) diff --git a/.changeset/1107-progress-verification-status-routing.md b/.changeset/1107-progress-verification-status-routing.md deleted file mode 100644 index 0b844027b..000000000 --- a/.changeset/1107-progress-verification-status-routing.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1116 ---- -**`/gsd-progress` no longer reports a phase as complete (and routes to the next phase) when its verification ended `human_needed` or `gaps_found`** — routing derived completeness from plan/summary counts only and never consulted the `verification.status` query (the seam built in #651). A new Step 1.7 consults it for the current phase, and the routing table sends `gaps_found` to `/gsd:plan-phase {phase} --gaps` (Route V.gaps) and `human_needed` to `/gsd:verify-work {phase}` (Route V.human) before the generic complete row. `passed`, `missing` (unverified), and `unknown` still route as complete, so unverified phases are not falsely blocked. (#1107) diff --git a/.changeset/1114-write-profile-runtime-home.md b/.changeset/1114-write-profile-runtime-home.md deleted file mode 100644 index 0c12716bc..000000000 --- a/.changeset/1114-write-profile-runtime-home.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1119 ---- -**`write-profile` now writes `USER-PROFILE.md` to the active runtime's config home instead of always `~/.claude`** — under Codex, `gsd-tools query write-profile` wrote `~/.claude/gsd-core/USER-PROFILE.md` while Codex `discuss-phase` advisor-mode (installed under `~/.codex`) checked the Codex home and never found it, so advisor-mode silently stayed disabled. The default output path is now resolved via the runtime-aware `getGlobalConfigDir` (`GSD_RUNTIME` / `config.runtime` → e.g. `~/.codex` for Codex), matching how the runtime's own workflows resolve it — mirroring `generate-dev-preferences`. Claude is unchanged (`~/.claude`); an explicit `--output` still wins. (#1114) diff --git a/.changeset/1115-review-codex-flag-capability-probe.md b/.changeset/1115-review-codex-flag-capability-probe.md deleted file mode 100644 index f289486c2..000000000 --- a/.changeset/1115-review-codex-flag-capability-probe.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1122 ---- -**`/gsd:review` no longer produces a silent empty Codex review on codex-cli < 0.137** — the `codex exec` invocation passed `--dangerously-bypass-hook-trust` (added in codex 0.137.0) unconditionally and discarded stderr, so on older CLIs codex exited with `unexpected argument` before reading the prompt and the empty output was treated as a completed review. The flag is now capability-probed (`codex exec --help | grep`) and applied via `$CODEX_BYPASS_FLAG` only when supported, codex stderr is captured to a `.err` file instead of `/dev/null`, and an empty Codex output is replaced with a diagnostic so a broken reviewer is surfaced rather than silently skipped. (#1115) diff --git a/.changeset/1123-capability-registry-duplicate-producer-invariant.md b/.changeset/1123-capability-registry-duplicate-producer-invariant.md deleted file mode 100644 index 06c13864a..000000000 --- a/.changeset/1123-capability-registry-duplicate-producer-invariant.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Added -pr: 1131 ---- -**`gen-capability-registry` now rejects duplicate artifact producers at the same Loop Extension Point** — if two capability `steps` declare `produces: []` at the same point, the generator throws at gen time naming the artifact, the point, and the producing capability ids, instead of letting the topological sort pick a winner silently (which left ADR-857 Decision #6's data-flow contract undefined). The check counts distinct `(capId, stepIdx)` producer steps, so a single step listing an artifact twice does not false-positive. ADR-894 §4's enumerated cross-capability invariant list gains the artifact-production-uniqueness rule. (#1123) diff --git a/.changeset/1124-capability-registry-loadcentralconfigkeys-parse-error.md b/.changeset/1124-capability-registry-loadcentralconfigkeys-parse-error.md deleted file mode 100644 index 714474192..000000000 --- a/.changeset/1124-capability-registry-loadcentralconfigkeys-parse-error.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -type: Changed -pr: 1131 ---- - -**`loadCentralConfigKeys` now fails loud on a malformed central config-schema instead of silently returning an empty Set** — `ENOENT` (the schema legitimately absent) still returns an empty Set silently, but a JSON parse error or any other read failure now writes a prominent `stderr` warning naming the schema file and throws `ExitError(1)`. Previously a single `catch (_)` swallowed parse errors too, so a merge-conflict marker or truncated write in `config-schema.manifest.json` made every capability config key look non-central — the config-key collision / `pending-migration` gate fired zero warnings and `--check` passed clean, defeating the gate invisibly. (#1124) diff --git a/.changeset/1136-capability-state-consumption.md b/.changeset/1136-capability-state-consumption.md deleted file mode 100644 index 86758ae38..000000000 --- a/.changeset/1136-capability-state-consumption.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Changed -pr: 1153 ---- -**Capability hook rendering now consumes resolved Capability State** — `gsd-tools loop render-hooks` uses the same installed/surfaced/configured state reported by `gsd-tools capability state`, so disabling a migrated capability at the runtime surface removes its workflow hooks even when config defaults are enabled. Migrated capability config keys remain accepted through the generated capability registry/federated config path instead of duplicated central `VALID_CONFIG_KEYS` entries. (#1136) diff --git a/.changeset/1139-phase6-capstone-conformance.md b/.changeset/1139-phase6-capstone-conformance.md deleted file mode 100644 index 27bc53be6..000000000 --- a/.changeset/1139-phase6-capstone-conformance.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"@opengsd/gsd-core": patch -type: Changed -issue: 1139 -pr: 1158 ---- - -Added ADR-857 Phase 6 capstone conformance coverage so migrated Capability activation keys cannot be read directly from host loop workflows, Capability-owned config keys stay out of the central schema, and the host loop workflow size budgets remain documented. The verify-work UI automation preflight now resolves UI activation through the Capability hook registry instead of reading `workflow.ui_phase` directly. diff --git a/.changeset/1151-sandbox-tier-load-bearing.md b/.changeset/1151-sandbox-tier-load-bearing.md deleted file mode 100644 index 4a3bae65b..000000000 --- a/.changeset/1151-sandbox-tier-load-bearing.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1152 ---- -**`sandbox_mode` emission in Codex TOML is now gated on the runtime descriptor's `sandboxTier` axis** — previously `installCodexConfig` emitted `sandbox_mode` unconditionally from a hardcoded policy map regardless of whether the runtime descriptor declared a sandbox tier, making the descriptor field cosmetic. `resolveInstallPlan` now projects `sandboxTier` from the capability registry, and `generateCodexAgentToml` / `installCodexConfig` gate emission on `sandboxTier !== 'none'`. The per-agent mode table `CODEX_AGENT_SANDBOX` remains GSD agent policy (not a runtime-descriptor property). For codex (`sandboxTier === 'codex-agent-sandbox'`) output is byte-identical to before; for all other runtimes (`sandboxTier === 'none'`) `sandbox_mode` is correctly omitted. `resolveInstallPlan` now fails loud (throws `TypeError`) on a missing or invalid `sandboxTier` descriptor axis rather than silently coercing garbage to `'none'`, preventing a corrupt/stale registry from silently dropping sandbox enforcement. Full removal of the per-agent registration-tax map remains tracked under #1138. (#1151) diff --git a/.changeset/1160-installed-runtime-capability-surface.md b/.changeset/1160-installed-runtime-capability-surface.md deleted file mode 100644 index 34be4e9d4..000000000 --- a/.changeset/1160-installed-runtime-capability-surface.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1206 ---- -**Installed runtimes no longer silently disable `verify:post` gates** — in a global skills-runtime install (e.g. Codex at `~/.codex`), the `commands/gsd` source tree is absent, so capability-state resolved an empty skill manifest. The full-profile `*` sentinel then materialized to an empty surfaced set, marking every capability `surfaced=false` → `enabled=false`. The result: `gsd-tools loop render-hooks verify:post` returned `activeHooks: []` even with `security_enforcement` and `nyquist_validation` enabled, so the security and Nyquist gates never fired. Capability-state now falls back to the installed `/skills/gsd-*/SKILL.md` layout when the source tree is unreachable, so `verify:post` again includes `security -> secure-phase` and `nyquist -> validate-phase`. (#1206) diff --git a/.changeset/1169-phase6-capstone-completion.md b/.changeset/1169-phase6-capstone-completion.md deleted file mode 100644 index eaa4e5d7b..000000000 --- a/.changeset/1169-phase6-capstone-completion.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Changed -pr: 1183 ---- -**ADR-857 phase 6 complete: optional features are now Capabilities, not inline loop branches.** `tdd`, `schema-gate`, `drift`, `gap-analysis`, and `profile-pipeline` are migrated out of the five-step host loop into declarative Capabilities (loop hooks + a command family); their config keys are federated to capability ownership; and the `plan-phase`/`execute-phase` workflow bodies shrink accordingly. Two previously-declared-but-dead capability gates now actually fire — the security ship-time gate (`ship:pre`) and the UI safety gate (`execute:wave:post`) — and the phase-6 conformance gate is hardened to be un-gameable (rejects empty stubs, requires loop-body shrink, verifies hook dispatch and gate-result contracts). Behavior is preserved, verified across five adversarial review passes. (#1139, #1167, #1168, #1169) diff --git a/.changeset/1190-adr22-drift-guard-seam.md b/.changeset/1190-adr22-drift-guard-seam.md deleted file mode 100644 index f05578ce8..000000000 --- a/.changeset/1190-adr22-drift-guard-seam.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -type: Added -pr: 1242 ---- -**`gsd-tools drift-guard` — deterministic plan-drift severity/authority decisions (ADR-22).** The plan-review source-grounding pass now classifies cited-symbol drift through a tested seam (5-rung authority ladder, `grep`→`intel` auto-upgrade, severity mapping, rung≥3 hard-block) instead of re-deriving the rules from workflow prose on each run. (#1190) - - diff --git a/.changeset/1190-progress-converge-surface.md b/.changeset/1190-progress-converge-surface.md deleted file mode 100644 index 90599f1c2..000000000 --- a/.changeset/1190-progress-converge-surface.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Added -pr: 1237 ---- -**`/gsd-progress --next --auto --converge` now routes planning through plan-review convergence.** ADR-15's designated *primary* convergence surface is wired into the progress/next workflow (previously only `/gsd-autonomous --converge` honored it; on `/gsd-progress` the flag was silently dropped). Accepts `--cross-ai` as an alias plus reviewer flags and `--max-cycles N`, and is gated on `workflow.plan_review_convergence`. (#1190) diff --git a/.changeset/1191-install-null-settings.md b/.changeset/1191-install-null-settings.md deleted file mode 100644 index 68a8c533e..000000000 --- a/.changeset/1191-install-null-settings.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1233 ---- -**`gsd install` no longer warns that `settings.local.json` "may be malformed" when the file contains a valid JSON `null`.** `readSettings` now treats a successfully-parsed `null` as empty settings (`{}`) instead of collapsing it into the parse-failure path, so a literal-`null` settings file is preserved silently; genuinely unparseable files still emit the warning. (#1191) diff --git a/.changeset/1223-installer-fix-slash-commands-missing.md b/.changeset/1223-installer-fix-slash-commands-missing.md deleted file mode 100644 index 9203eb428..000000000 --- a/.changeset/1223-installer-fix-slash-commands-missing.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1240 ---- -**gsd-tools no longer crashes at load on a fresh install** — the installer omitted `scripts/fix-slash-commands.cjs`, which `command-roster` requires at module load, so every `gsd-tools` command failed with MODULE_NOT_FOUND. The installer now ships it (with a smoke assertion), and `readCmdNames()` tolerates a missing commands directory. (#1240) diff --git a/.changeset/1255-state-status-pipe-table.md b/.changeset/1255-state-status-pipe-table.md deleted file mode 100644 index 778d24356..000000000 --- a/.changeset/1255-state-status-pipe-table.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1256 ---- -**`state begin-phase` / `complete-phase` now advance the frontmatter `status` for pipe-table `STATE.md`, not only inline `Status:` files.** The status update matched the YAML frontmatter `status:` line first and never updated a body `| Status | … |` cell, so the frontmatter `status` froze (e.g. stuck at `planning`); it now transitions correctly (`planning → executing → completed`) regardless of whether the body `Status` is inline or pipe-table. (#1255) diff --git a/.changeset/1257-state-pipe-table-planned-begin.md b/.changeset/1257-state-pipe-table-planned-begin.md deleted file mode 100644 index a15e59fe8..000000000 --- a/.changeset/1257-state-pipe-table-planned-begin.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1260 ---- -**`state planned-phase` now advances the pipe-table `Status` cell (and frontmatter `status`), and `state begin-phase` now updates the Current Position `| Phase |` / `| Plan |` cells instead of prepending stray inline lines.** Systemic follow-up to #1255: `planned-phase` ran its body-field replacements on the full file content, so the YAML frontmatter `status:` line was matched before the body `| Status | … |` cell and the status never reached `Ready to execute`; and `begin-phase` had pipe-table branches only for `Status`/`Last activity`, so for pipe-table `STATE.md` the `Phase`/`Plan` rows were left stale while a spurious inline `Phase: N — EXECUTING` line was prepended. Both handlers now strip frontmatter before body-field replacement and update pipe-table cells in place, matching the inline-format behaviour. (#1257) diff --git a/.changeset/1259-test-tier-enforcement.md b/.changeset/1259-test-tier-enforcement.md deleted file mode 100644 index b9ef51535..000000000 --- a/.changeset/1259-test-tier-enforcement.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -type: Changed -pr: 1273 ---- - -**Test-tier prohibitions are now a real, provable gate instead of a permanent, unsatisfiable `gaps_found`** — the deferred ENFORCEMENT half of ADR-550 Decision 5d (the "heavy half" that #644 / PR #1149 deferred) has landed. A new deterministic `check prohibition-enforcement` sub-command (authored as `src/prohibition-enforcement.cts`, compiled by `build:lib` to the gitignored `gsd-core/bin/lib/prohibition-enforcement.cjs`) is the missing PRODUCER: it locates the wired mechanical check, runs it for a genuine **non-vacuous** pass, builds `enforcementEvidence`, and emits the `dispositionForProhibition()` verdict. The previously-unreachable green branch in `dispositionForProhibition()` is now reachable from the live pipeline — a test-tier prohibition with a genuinely-passing wired check disposes `green` and can reach `passed`, while a missing, non-attested, or non-passing check hard-gates (flagged, never green → `gaps_found`) in BOTH interactive and autonomous modes (ADR-550 D4 / D3). `verify-phase.md` wires the consumer; the green/fail-closed policy in `src/probe-core.cts` is untouched. Both wired-check kinds are accepted (ADR-550 D2): a `node --test` negative test (requiring a real reported test — an empty file, which `node --test` counts as one passing "test", does NOT green) AND a lint/AST rule run as `eslint --format json` filtered by `ruleId` (so plugin rules like `local/*` load — bare `--rule` cannot), anchored on the in-tree `local/no-source-grep` rule (dogfooding, ADR-550 D4). This enforcement seam is the concrete instance of ADR-857 open-question §147 and lands on the core verify rail, never in `capabilities/` (D6). (#1259) - -**Honest scope — `failFirst` is caller-attested, not yet machine-proven.** This lands the *execution + non-vacuous-pass* half: the producer requires the caller to attest `failFirst: true` and the check to genuinely run and pass. It does NOT yet independently prove the check *fails-on-violation* (the literal `regression-must-fail-first` property) — cheap proof of that at verify time needs running the check against a known violation fixture, which is a **tracked follow-up (#1279)**. The red-first property currently rests on caller attestation, surfaced transparently in the evidence record. - -**Correction to the issue body (#1259):** the issue's "96 invalid/error negative-proof cases" figure is wrong. For the `no-source-grep` anchor specifically, the genuine `regression-must-fail-first` proofs are its **two `invalid` cases** (the `.includes()` and `.match()` blocks) in `tests/eslint-rules.test.cjs` — not 96. The anchor argument is unaffected (those two cases ARE real fail-first proofs); only the count was off. diff --git a/.changeset/1278-prohibition-check-descriptor.md b/.changeset/1278-prohibition-check-descriptor.md deleted file mode 100644 index d380cb9b7..000000000 --- a/.changeset/1278-prohibition-check-descriptor.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Changed -pr: 1301 ---- -**The test-tier prohibition gate now has a deterministic SOURCE for its wired check** — a resolved `test`-tier `must_haves.prohibitions` item MAY carry an optional `check` descriptor authored at spec-phase: the flat-scalar keys `check_kind` (`node-test` | `lint-rule`), `check_target`, and `check_rule` (lint-rule only). `projectProhibitions` projects these scalars deterministically and verify-phase reads them back (via `descriptorFromProjection`) to locate the check handed to `check prohibition-enforcement` — so a wired, passing test closes the gap with **zero manual descriptor authoring** (previously the verify-phase LLM had to invent `{kind, target, rule}` each run, #1259). This extends the ADR-550 Decision 3 prohibition-item shape (ratified in a dated 2026-06-15 ADR-550 addendum). The descriptor is **optional and fully backward-compatible** — a prohibition with no descriptor parses and disposes byte-identically to today — and **fail-closed**: a partial, invalid, or absent descriptor falls through to the producer's existing fail-closed locate, never a silent green. The descriptor is represented as flat scalars (not a nested `check:{}` object) to keep the shared `parseMustHavesBlock` round-trip regression-free. Out of scope: machine-proven fail-first (#1279) and the `dispositionForProhibition` policy stay unchanged. (#1278) diff --git a/.changeset/1279-machine-proven-fail-first.md b/.changeset/1279-machine-proven-fail-first.md deleted file mode 100644 index 3459c44f7..000000000 --- a/.changeset/1279-machine-proven-fail-first.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -type: Changed -pr: 1314 ---- - -**Test-tier prohibition fail-first is now MACHINE-PROVEN, not caller-attested** — the deferred literal `regression-must-fail-first` property of ADR-550 Decision 4 (the gap #1259 / PR #1273 left as a tracked follow-up) has landed. The `check prohibition-enforcement` producer (`src/prohibition-enforcement.cts`, compiled by `build:lib` to the gitignored `gsd-core/bin/lib/prohibition-enforcement.cjs`) no longer trusts the caller's `failFirst` attestation: before a clean, non-vacuous pass can dispose a `test`-tier prohibition green, the new `defaultProveFailFirst` prover independently RUNS the wired check against a KNOWN VIOLATION and confirms it goes RED. Attestation is gone from the green AND (`passed = proof.provenFailFirst === true && run.passed === true`); any other outcome — passes-on-violation, can't-prove, throws, times out, or no violation source — **hard-gates in BOTH interactive and autonomous modes** (ADR-550 D4 / D3). The evidence record gains a `failFirstProof` field recording HOW fail-first was proven (FF-07). A caller can no longer green a toothless check. - -The violation is sourced from a new descriptor field, **`CheckDescriptor.violationFixture`** — an author-supplied path to a known-bad subject. For a `lint-rule` the prover lints that fixture and requires the rule id to appear in the JSON report (the rule must have teeth); for a `node-test` the prover spawns the negative test with the subject injected through the **`GSD_PROHIB_SUBJECT`** env convention and requires a NON-VACUOUS red — `# fail >= 1` AND a failing test named distinctly from the file (`isNonVacuousNodeTestRed`), so a violation fixture that merely CRASHES the test at load is not mistaken for the negative assertion firing red (symmetric with the clean-pass non-vacuity guard). The node-test prover also requires the `violationFixture` to EXIST (resolved against `cwd`) before spawning — a missing/typo'd path fail-CLOSES rather than letting an honest test's ENOENT crash forge a green (symmetric with the lint path's file-result guard). The deterministic spec→verify path composes end-to-end: a fourth flat scalar **`check_violation_fixture`** is projected by `projectProhibitions` and read back by `descriptorFromProjection` (rides both kinds), so a prohibition authored with all four `check_*` scalars machine-proves fail-first and greens through the projection alone — zero hand-authoring at verify time (#1278 + #1279 + #1346; round-trip pinned by a fast-check property + CHK-03(D) + an end-to-end COMPOSE capstone). One documented residual remains under **#1346**: the node-test proof confirms the fixture exists and the check reds, but cannot generically prove the red was *caused by* the subject's content rather than by the env merely being set. The `lint-rule` path is fully shippable now and is dogfooded against the in-tree `local/no-source-grep` rule; the `node-test` path ships its mechanism (a fixture-bearing descriptor IS machine-proven) and is exercised by SYNTHETIC temp fixtures — there is no live in-tree `node --test` prohibition to dogfood. `CheckDescriptor.failFirst` is **DEMOTED, not removed** (FF-08): it is kept as a non-authoritative hint so the #1259 route-JSON shape and the `CheckDescriptor` type stay backward-compatible mid-migration, but no path greens on it alone. The green/fail-closed policy in `src/probe-core.cts` (`dispositionForProhibition`, reads only `evidence.length > 0`) is untouched; the evidence array shape is additive. This closes ADR-550's D5d follow-up — see the dated 2026-06-15 ADR-550 addendum. (#1279) - -**PR-review flag — `GSD_PROHIB_SUBJECT` + `violationFixture` are PROPOSED, renamable conventions.** Both are net-new surface with ZERO live in-tree consumers (no in-tree node-test prohibition yet; node-test proof runs only on synthetic test fixtures, the real dogfood stays the lint-rule). They are forward-looking scaffolding, so a later rename — or replacing the env var with an argv — is a mechanical, zero-migration find/replace. Surfacing them here so the maintainer can **ratify, rename, or replace them at PR review** with no migration cost, exactly as #1278's ADR addendum was reviewed at PR time. The `failFirst` demotion is likewise open to weighing outright removal; the keep-as-hint rationale is recorded in the ADR addendum. diff --git a/.changeset/1297-worktree-metadata.md b/.changeset/1297-worktree-metadata.md deleted file mode 100644 index c4cb0c5ae..000000000 --- a/.changeset/1297-worktree-metadata.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -type: Fixed -pr: 1349 ---- - -**Parallel worktree execution now has executor-authored cleanup metadata** — executor agents capture their worktree path, branch, and expected base before task commits and return a parseable metadata block for execute-phase to prefer over runtime harness metadata. (#1297) diff --git a/.changeset/1300-uat-paused-checkpoint.md b/.changeset/1300-uat-paused-checkpoint.md deleted file mode 100644 index 95c316e56..000000000 --- a/.changeset/1300-uat-paused-checkpoint.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -type: Fixed -pr: 1350 ---- - -**UAT resume now accepts paused checkpoints** — `uat render-checkpoint` treats a non-structured paused `Current Test` placeholder as a resume signal and derives the checkpoint from the first pending UAT test instead of failing as malformed. (#1300) diff --git a/.changeset/1316-state-prose-phase-name.md b/.changeset/1316-state-prose-phase-name.md deleted file mode 100644 index 1757416e1..000000000 --- a/.changeset/1316-state-prose-phase-name.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -type: Fixed -pr: 1351 ---- - -**`phase complete` now preserves prose-block STATE phase names** — template-shaped `Current Position` prose now advances with the next phase name, avoids missing-field warnings, and keeps `Last activity:` on the template em-dash delimiter. (#1316) diff --git a/.changeset/1319-claude-skill-effort-max.md b/.changeset/1319-claude-skill-effort-max.md deleted file mode 100644 index ff4aa71ed..000000000 --- a/.changeset/1319-claude-skill-effort-max.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -type: Fixed -pr: 1352 ---- - -**Claude skill installs now avoid rejected `xhigh` effort frontmatter** — heavyweight GSD skills now ship with portable `effort: max`, and the Claude skill converter normalizes any remaining `xhigh` source effort before writing `SKILL.md`. (#1319) diff --git a/.changeset/1324-glued-phase-token.md b/.changeset/1324-glued-phase-token.md deleted file mode 100644 index 3548bb0d7..000000000 --- a/.changeset/1324-glued-phase-token.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -type: Fixed -pr: 1353 ---- - -**Glued letter-prefix phase directories now resolve correctly** -- phase lookup now recognizes tokens like `P0.3` and `M1-2` from directory names, so phase commands can find their plans instead of reporting none found. (#1324) diff --git a/.changeset/1325-update-backup-scope.md b/.changeset/1325-update-backup-scope.md deleted file mode 100644 index 8cf877a9a..000000000 --- a/.changeset/1325-update-backup-scope.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -type: Fixed -pr: 1354 ---- - -**Update backups now ignore preserved shared skills and hooks** -- `/gsd-update` custom-file detection now mirrors installer cleanup scope for shared runtime roots, so non-`gsd-*` skills and hooks are not copied into backup folders unnecessarily. (#1325) diff --git a/.changeset/1326-codex-sidecar-cleanup.md b/.changeset/1326-codex-sidecar-cleanup.md deleted file mode 100644 index 6627f0a8e..000000000 --- a/.changeset/1326-codex-sidecar-cleanup.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -type: Fixed -pr: 1360 ---- - -**Codex skills no longer show up twice in autocomplete** — GSD's Codex install wrote an `agents/openai.yaml` sidecar under every managed `gsd-*` skill directory, and recent Codex builds index both `SKILL.md` and the sidecar, so each skill appeared twice (once as `gsd-foo`, once as a humanized `foo` display name). The installer now stops emitting these sidecars and removes stale ones left by prior installs (pruning the empty `agents/` directory), while preserving user-owned skill directories. Codex discovers GSD skills via `SKILL.md` alone. (#1326) diff --git a/.changeset/1342-worktree-guard-gsd-gate.md b/.changeset/1342-worktree-guard-gsd-gate.md deleted file mode 100644 index 9e593f101..000000000 --- a/.changeset/1342-worktree-guard-gsd-gate.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -type: Fixed -pr: 1361 ---- - -**The worktree path guard no longer blocks ordinary writes in non-GSD git worktrees** — the `gsd-worktree-path-guard` PreToolUse hook fired for every `Write`/`Edit` in any linked git worktree, so Claude Code plan-mode writing its plan to `~/.claude/plans/.md` from a manually-created worktree was hard-blocked. The hook now only enforces inside a GSD isolated-executor worktree (branch `worktree-agent-*`) and fails open when a target resolves to no git repository, while still blocking writes that escape to a different git root (the #260 protection) or into a repository's `.git` internals. (#1342) diff --git a/.changeset/1343-decision-coverage-false-pass.md b/.changeset/1343-decision-coverage-false-pass.md deleted file mode 100644 index 5f43d049f..000000000 --- a/.changeset/1343-decision-coverage-false-pass.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -type: Fixed -pr: 1358 ---- - -**`check.decision-coverage-plan` no longer reports a false pass when a `D-NN` decision header has text before the colon** — `parseDecisions` previously dropped any `- **D-NN …:**` bullet whose header contained a `(parenthetical)`, em-dash, or other prose before the `:**`, silently narrowing the trackable set so the blocking coverage gate green-lit a phase whose dropped decisions were never checked. The parser now tolerates a freeform run before the colon (preserving `[bracket]` tags) and warns on any `D-NN` bullet it still cannot parse instead of dropping it. (#1343) diff --git a/.changeset/1348-codex-hooks-json-canonical.md b/.changeset/1348-codex-hooks-json-canonical.md deleted file mode 100644 index f42285f54..000000000 --- a/.changeset/1348-codex-hooks-json-canonical.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -type: Fixed -pr: 1363 ---- - -**Codex `hooks.json` is now always written in the nested `{ "hooks": { … } }` shape Codex expects** — the writer previously echoed back whatever shape it read, so an empty, absent, or legacy top-level `hooks.json` (`{ "SessionStart": [...] }`) stayed in the legacy shape that current Codex can reject or warn on. Every write now canonicalizes to the nested form, lifting any legacy top-level event entries (including mixed nested+top-level files) under `hooks` without dropping user-owned entries. Managed-hook dedup/removal is unchanged. (#1348) diff --git a/.changeset/1355-teams-detect-guard.md b/.changeset/1355-teams-detect-guard.md deleted file mode 100644 index 454f24ba2..000000000 --- a/.changeset/1355-teams-detect-guard.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -type: Added -pr: 1371 ---- - -**`gsd-tools query teams-status` + a plan-phase warning detect claude-code agent-teams** — GSD's multi-agent orchestration can stall under claude-code's experimental agent-teams (a subagent's completion can fail to route back to the orchestrator). A new read-only `query teams-status` command reports `{ active, runtime, env_present, source }` (and `--active` for a clean shell guard), and `/gsd:plan-phase` now emits a single non-fatal warning when agent-teams is detected, recommending you disable it for GSD workflows. The detector only activates on the `claude` runtime with `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS` strictly truthy — every other runtime and the teams-off path are completely unaffected. (#1355) diff --git a/.changeset/1356-cursor-bare-claude-paths.md b/.changeset/1356-cursor-bare-claude-paths.md deleted file mode 100644 index 6fe8ffbe9..000000000 --- a/.changeset/1356-cursor-bare-claude-paths.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -type: Fixed -pr: 1368 ---- - -**`gsd install --cursor` no longer leaves bare `~/.claude` paths in installed artifacts** — the Cursor install branch only rewrote the trailing-slash `.claude` forms, so bare `~/.claude` / `$HOME/.claude` references survived into installed skills and workflows (e.g. `gsd-surface`, `gsd-graphify`, `plan-phase`, `autonomous`) and tripped the post-install "unreplaced .claude path reference(s)" warning, pointing at a directory that doesn't exist on a Cursor-only install. The Cursor branch now rewrites bare forms too (mirroring the Trae/Augment/Copilot branches), using a `(?![\w-])` lookahead so `.claude-plugin` / `.claudeignore` are not corrupted. (#1356) diff --git a/.changeset/222-synthesizer-summary-self-heal.md b/.changeset/222-synthesizer-summary-self-heal.md deleted file mode 100644 index 20d71e6ef..000000000 --- a/.changeset/222-synthesizer-summary-self-heal.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1042 ---- -**`/gsd-new-project` and `/gsd-new-milestone` now self-heal when the research synthesizer returns `SUMMARY.md` inline instead of writing it** — under some context loads the `gsd-research-synthesizer` agent hits an LLM false-refusal (fabricating a non-existent write restriction) and returns the SUMMARY.md content in its reply rather than writing `.planning/research/SUMMARY.md`. Prompt hardening (#240) reduced but did not eliminate this. Both workflows now verify the file exists after the synthesizer returns and, if it is missing but content came back inline, the orchestrator persists it before spawning `gsd-roadmapper` — so the roadmapper never fails with "SUMMARY.md not found". (#222) diff --git a/.changeset/644-prohibition-probe.md b/.changeset/644-prohibition-probe.md deleted file mode 100644 index aab3a6502..000000000 --- a/.changeset/644-prohibition-probe.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Added -pr: 1149 ---- -spec-phase: prohibition probe — a prose-orchestrated Step 5.6 that surfaces the unwritten *must-NOT* constraints (values/safety/ethics) a feature could silently become but the spec never forbids. Two stages per requirement: an adversarial recall question ("what could this silently become that the author would NOT want?") then a one-pass precision classifier that drops routine engineering and keeps genuine prohibitions. Confirmed prohibitions become NEGATIVE SPEC acceptance criteria carrying a `test`/`judgment` verification tier, which plan-phase lifts into the `must_haves.prohibitions` sibling block (`truths` untouched). Judgment-tier items soft-gate at verify time (never silent, never hard-halt); unwired test-tier items fail closed. The recall stage is model-driven (no compiled engine); canon-bound concerns (OWASP/GDPR/fairness) are referred to `/gsd:secure-phase`. Additive and optional: existing SPECs without a Prohibitions section remain valid. Second adapter of the `probe-core` resolution model (ADR-550 Decision 7). diff --git a/.changeset/72-project-business-context.md b/.changeset/72-project-business-context.md deleted file mode 100644 index cfa52862d..000000000 --- a/.changeset/72-project-business-context.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Added -pr: 756 ---- -**Optional `## Business Context` section in the PROJECT.md template** — a four-field block (Customer, Revenue model, Success metric, Strategy notes) for monetized or customer-facing projects, positioned between Core Value and Requirements. Optional by default (an HTML comment tells non-business projects to delete it), capped at four one-line fields to stay a constraint reference rather than a business plan, and reviewed at each milestone by `/gsd-complete-milestone` when present. (#72) diff --git a/.changeset/767-disallowed-tools-readonly-agents.md b/.changeset/767-disallowed-tools-readonly-agents.md deleted file mode 100644 index 8951f695a..000000000 --- a/.changeset/767-disallowed-tools-readonly-agents.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Changed -pr: 1081 ---- -**Read-only verifier/auditor agents now ship a Claude-Code `disallowedTools` deny-list** — the installer injects a framework-level write-tool deny-list into the Claude copies of the read-only verifier/auditor agents (gsd-verifier, gsd-plan-checker, gsd-integration-checker, gsd-doc-verifier, gsd-eval-auditor, gsd-ui-auditor, gsd-ui-checker) so write actions are blocked even if a tool grant is inherited. Injected for Claude only; other runtimes are unaffected. (#1081) diff --git a/.changeset/791-antigravity-agents-dir.md b/.changeset/791-antigravity-agents-dir.md deleted file mode 100644 index b6917e902..000000000 --- a/.changeset/791-antigravity-agents-dir.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -type: Changed -pr: 1090 ---- - -**Antigravity workspace skills now install to the canonical `.agents/` directory** — fresh installs write workspace artifacts under `.agents/` (the Google-Codelabs-documented base) instead of `.agent/`; the legacy `.agent/` layout is still recognized so existing installs keep working. The global `~/.gemini/antigravity/` path is unchanged. (#1090) diff --git a/.changeset/792-devin-desktop-alias.md b/.changeset/792-devin-desktop-alias.md deleted file mode 100644 index 080f28f84..000000000 --- a/.changeset/792-devin-desktop-alias.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -type: Changed -pr: 1086 ---- - -**`devin-desktop` runtime alias for the Windsurf→Devin Desktop rebrand** — the `windsurf` runtime now also answers to `devin-desktop` (CLI `--devin-desktop`), aiding discoverability after Cognition rebranded Windsurf as Devin Desktop. All paths are unchanged — global skills still install to `~/.codeium/windsurf/skills/`. (#1086) diff --git a/.changeset/838-codex-agent-model-effort-consistency.md b/.changeset/838-codex-agent-model-effort-consistency.md deleted file mode 100644 index d9d962f62..000000000 --- a/.changeset/838-codex-agent-model-effort-consistency.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 842 ---- -Codex agent TOML generation no longer pins `model_reasoning_effort` when the agent is intentionally inheriting the active Codex chat model. GSD still emits both `model` and `model_reasoning_effort` when a per-agent model override or `runtime: "codex"` resolver pins the model, avoiding the confusing partial state where the model followed Codex UI selection while effort followed GSD catalog defaults. (#838) diff --git a/.changeset/866-profile-pipeline-temp-root.md b/.changeset/866-profile-pipeline-temp-root.md deleted file mode 100644 index 59584d4f7..000000000 --- a/.changeset/866-profile-pipeline-temp-root.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 879 ---- -**profile-pipeline temp output now lands under the reaped GSD temp root.** `cmdExtractMessages` and `cmdProfileSample` previously created their output directories directly in `os.tmpdir()` root (`gsd-pipeline-*` / `gsd-profile-*`), which `reapStaleTempFiles` never scans (it only scans `GSD_TEMP_DIR = os.tmpdir()/gsd`). The directories accumulated forever. Both sites now call `ensureGsdTempDir()` and create under `GSD_TEMP_DIR`. Also adds missing `after`/`afterEach` teardown to four test fixtures that leaked `gsd-*` temp dirs on every `npm test` run. (#866) diff --git a/.changeset/875-getmilestonephasefilter-fence-aware.md b/.changeset/875-getmilestonephasefilter-fence-aware.md deleted file mode 100644 index b95fb8fe5..000000000 --- a/.changeset/875-getmilestonephasefilter-fence-aware.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 880 ---- -`getMilestonePhaseFilter` now excludes phase headings inside fenced code blocks (``` ``` ``` or `~~~`) — consistent with the fence-aware behavior of `extractCurrentMilestone`. Previously, a `### Phase N:` line inside a fenced block was wrongly counted as a real phase. (#875) diff --git a/.changeset/891-launcher-non-claude-runtime-homes.md b/.changeset/891-launcher-non-claude-runtime-homes.md deleted file mode 100644 index d297a598b..000000000 --- a/.changeset/891-launcher-non-claude-runtime-homes.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 903 ---- -**`gsd_run` launcher shim now probes all non-Claude runtime homes before failing.** The shim's last-resort detection previously stopped at `$HOME/.claude`, causing a false-positive fatal error on every non-Claude runtime (Hermes, Cursor, Codex, Copilot, Windsurf, Augment, Trae, Qwen, CodeBuddy, Cline, Grok, Antigravity, OpenCode, Kilo) when `RUNTIME_DIR` was unset and `gsd-tools` was not on `PATH`. The snippet now probes each runtime's config directory (respecting `HERMES_HOME`, `CURSOR_CONFIG_DIR`, `CODEX_HOME`, etc. with sensible `$HOME`-relative defaults) before emitting the install error. diff --git a/.changeset/892-validate-checklist-roadmap-phases.md b/.changeset/892-validate-checklist-roadmap-phases.md deleted file mode 100644 index 0b1c62292..000000000 --- a/.changeset/892-validate-checklist-roadmap-phases.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 893 ---- -**`validate health` and `validate consistency` no longer emit false-positive W007 warnings for projects using checklist-style ROADMAP.md phases.** `buildRoadmapPhaseVariants()` in `src/validate.cts` previously used only a heading-style regex (`## Phase N: name`), silently ignoring the supported checklist format (`- [x] **Phase N: name**`). This caused every on-disk phase directory to trigger W007 ("exists on disk but not in ROADMAP.md") when the project's ROADMAP used checklist-only notation. The fix adds a second regex pass mirroring the existing `buildNotStartedPhaseVariants()` approach. Additionally, `cmdValidateConsistency()` in `src/verify.cts` had a duplicate inline heading-only regex with the same gap — refactored to delegate to `buildRoadmapPhaseVariants()` (DRY). (#892) diff --git a/.changeset/893-remove-dead-loadconfig-from-configuration.md b/.changeset/893-remove-dead-loadconfig-from-configuration.md deleted file mode 100644 index 6a4280650..000000000 --- a/.changeset/893-remove-dead-loadconfig-from-configuration.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -type: Changed -pr: 893 ---- -Remove dead `loadConfig` export from `configuration.cts` — superseded by `config-loader.cts` (ADR-857 phase 2e, #885). All live callers already import `loadConfig` from `config-loader.cjs` or the `core.cjs` back-compat re-export; exhaustive grep confirms zero callers importing it from `configuration.cjs`. `configuration.cjs` now provides only the pure normalization and defaults primitives (`normalizeLegacyKeys`, `mergeDefaults`, `migrateOnDisk`, `CONFIG_DEFAULTS`) that `config-loader.cjs` depends on. (#893) - - diff --git a/.changeset/904-init-execute-phase-normalize-branch.md b/.changeset/904-init-execute-phase-normalize-branch.md deleted file mode 100644 index 3e1a3dd6c..000000000 --- a/.changeset/904-init-execute-phase-normalize-branch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 904 ---- -**`init execute-phase` and `cmdCommit` now produce correct `branch_name` when `project_code` is set** — the `{phase}` substitution in `phase_branch_template` now calls `normalizePhaseName()`, stripping the project-code prefix and zero-padding the number, so the generated branch is e.g. `gsd/phase-01-foundation` instead of `gsd/phase-CK-01-foundation`. Both the execute-phase output path (`src/init.cts`) and the pre-execution commit path (`src/commands.cts`) are fixed. (#904) diff --git a/.changeset/905-syncstatefrontmatter-preserve-scalars.md b/.changeset/905-syncstatefrontmatter-preserve-scalars.md deleted file mode 100644 index d4b50642d..000000000 --- a/.changeset/905-syncstatefrontmatter-preserve-scalars.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 905 ---- -**`syncStateFrontmatter` no longer strips `current_phase`, `current_phase_name`, `current_plan`, and `progress` from `STATE.md`** — when body annotations are absent (e.g. after an agent rewrites the body), the existing frontmatter values for those scalars are now preserved, mirroring the fallback already applied in `cmdStateJson`. (#905) diff --git a/.changeset/913-plan-phase-toplevel-spawn-guard.md b/.changeset/913-plan-phase-toplevel-spawn-guard.md deleted file mode 100644 index 3a4b1ade8..000000000 --- a/.changeset/913-plan-phase-toplevel-spawn-guard.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 913 ---- -**Top-level Claude Code `/gsd-plan-phase` now always spawns the researcher/planner/plan-checker agents instead of collapsing them inline** — a `` block after `` makes the Agent-availability requirement explicit and documents that the workflow fails-closed (stops with a clear log message) in genuinely Agent-less contexts; seven "ORCHESTRATOR RULE — CODEX RUNTIME" labels are renamed to "ALL RUNTIMES" so the guard applies universally; `execute-phase.md` scopes its existing "Other runtimes" inline-fallback prose to non-Claude contexts, preserving the #853 backgrounded-agent behaviour. (#913) diff --git a/.changeset/921-922-orchestrators-no-fork.md b/.changeset/921-922-orchestrators-no-fork.md deleted file mode 100644 index 92e481ef7..000000000 --- a/.changeset/921-922-orchestrators-no-fork.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 921 ---- -**`/gsd-plan-phase`, `/gsd-execute-phase`, `/gsd-autonomous` no longer carry `context: fork`** — these are spawning orchestrators; a forked subagent context has no `Agent` tool, preventing them from spawning the subagents they require. `effort: xhigh` is preserved. Fixes `/gsd:autonomous` halting with "running as a forked subagent" on 1.4.1 (#921). Also replaces the introspection-based Agent-availability check in `plan-phase`'s `` block with an attempt-based gate: the workflow now always attempts the `Agent()` call and only stops if a real tool-unavailable error is returned, eliminating false-negative aborts in top-level sessions (#922). diff --git a/.changeset/924-claude-flat-skill-layout.md b/.changeset/924-claude-flat-skill-layout.md deleted file mode 100644 index 2fcfb9d7b..000000000 --- a/.changeset/924-claude-flat-skill-layout.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 924 ---- -**Claude global install reverted to flat skill layout so concrete skills are discoverable.** PR #883 introduced nested skill layout for Claude (`~/.claude/skills/gsd-ns-/skills//SKILL.md`), but Claude Code's skill discovery scans only one level under `~/.claude/skills/` — nested concrete skills were never listed in the Skill-tool available-skills list and direct `Skill(skill="gsd-plan-phase")` calls stopped working. This fix reverts Claude to the flat layout (`~/.claude/skills/gsd-/SKILL.md`) so all ~61 concrete skills are top-level and immediately discoverable. The 6 other runtimes that confirmed non-recursive scanning (cline, qwen, hermes, augment, trae, antigravity) retain their nested layout. (#924) diff --git a/.changeset/925-context-monitor-hook-event-name.md b/.changeset/925-context-monitor-hook-event-name.md deleted file mode 100644 index 8a3dd76d3..000000000 --- a/.changeset/925-context-monitor-hook-event-name.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 926 ---- -**`gsd-context-monitor.js` now echoes the actual invoking hook event name** — instead of hardcoding `hookEventName: "PostToolUse"` (or `"AfterTool"` for Gemini), the hook reads `data.hook_event_name` from the stdin payload and falls back to the runtime heuristic only when the field is absent or blank; this fixes Claude Code rejecting hook output with `"expected Stop but got PostToolUse"` when the monitor is invoked by the Stop, SubagentStop, or PreCompact hooks registered in PR #821. (#925) diff --git a/.changeset/934-reapply-pristine-baseline.md b/.changeset/934-reapply-pristine-baseline.md deleted file mode 100644 index 9b86100a7..000000000 --- a/.changeset/934-reapply-pristine-baseline.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -type: Fixed -pr: 935 ---- -Fix `--reapply` verifier false-positives on post-#604-rename installs caused by two gaps in pristine-baseline handling: - -**Gap 1** (`verify-reapply-patches.cjs`): when `backup-meta.json` records a `pristine_hash` for a file but `gsd-pristine/` has no corresponding snapshot on disk, the verifier fell to over-broad mode (every upstream-changed line treated as a user-added requirement) and produced `FAIL_USER_LINES_MISSING` false positives. Fix: return advisory `OK_NO_BASELINE` reason (non-blocking, exit 0) when a recorded hash is present but the pristine file is absent — the verifier cannot reason correctly without a baseline and must not block. - -**Gap 2** (new migration `004-prune-stale-pristine-get-shit-done`): migration 003 removed legacy `get-shit-done/` runtime files but left `gsd-pristine/get-shit-done/` orphan snapshots in place. Those stale snapshots referenced `get-shit-done/...` key paths that no longer match the active `gsd-core/...` layout, contributing to `FAIL_INSTALLED_MISSING` false reports. Fix: add a new migration (not editing 003, to preserve its checksum) that removes all files under `gsd-pristine/get-shit-done/`. (#934) diff --git a/.changeset/935-changeset-cli-install.md b/.changeset/935-changeset-cli-install.md deleted file mode 100644 index d18850c8a..000000000 --- a/.changeset/935-changeset-cli-install.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 935 ---- -**`/gsd-update` changelog preview no longer silently fails** — the installer now copies `scripts/changeset/` and `scripts/lib/` into the runtime config dir so `$GSD_DIR/scripts/changeset/cli.cjs` resolves at runtime; `update.md` was updated to use the correct installed path and to surface an explicit error if the CLI is missing rather than swallowing it. diff --git a/.changeset/936-convergence-inline-plan-phase.md b/.changeset/936-convergence-inline-plan-phase.md deleted file mode 100644 index 6577aeb0d..000000000 --- a/.changeset/936-convergence-inline-plan-phase.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 939 ---- -**`plan-review-convergence` now runs `gsd-plan-phase` inline instead of inside `Agent()`** — both sites that previously wrapped `gsd-plan-phase` in `Agent()` (initial planning + replan loop) have been changed to bare `Skill()` calls at depth 0. On Claude Code, a depth-1 Agent has no Agent tool, so a wrapped `plan-phase` could never spawn `gsd-planner` or `gsd-plan-checker` — the replan loop silently failed to produce a revised plan whenever HIGH concerns were found. Running plan-phase inline from the depth-0 orchestrator (which retains the Agent tool) restores the full planner→checker sub-agent chain. A new structural guard test (`bug-936-no-nested-spawner-wrap.test.cjs`) statically scans all workflow files and fails if any workflow wraps a spawner orchestrator in `Agent()` without a `RUNTIME != claude` carve-out, preventing regression. (#936) diff --git a/.changeset/965-json-errors-unexpected-throw.md b/.changeset/965-json-errors-unexpected-throw.md deleted file mode 100644 index 35db58e9a..000000000 --- a/.changeset/965-json-errors-unexpected-throw.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 987 ---- -**`--json-errors` now emits a structured error even when a handler throws unexpectedly** — an unexpected (non-`ExitError`) throw fell through to a raw stack trace on stderr, breaking SDK structured-error parsing. (#965) diff --git a/.changeset/967-verify-key-links-author-strict-docs.md b/.changeset/967-verify-key-links-author-strict-docs.md deleted file mode 100644 index 990e6f745..000000000 --- a/.changeset/967-verify-key-links-author-strict-docs.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 990 ---- -**`verify key-links` docs now correctly state `from:`/`to:` are relative file paths** — the reference implied component/endpoint values the verifier never supported, so locator-style links failed with a misleading 'Source file not found' and the author's `pattern:` was never evaluated. (#967) diff --git a/.changeset/969-hermetic-bug969-tests-and-tsbuildinfo-relocation.md b/.changeset/969-hermetic-bug969-tests-and-tsbuildinfo-relocation.md deleted file mode 100644 index 318fb663a..000000000 --- a/.changeset/969-hermetic-bug969-tests-and-tsbuildinfo-relocation.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1002 ---- -**Fixed a test-infrastructure regression (#996) where bug-969 hardening tests deleted the shared `gsd-core/bin/lib/core.cjs` during concurrent runs and the build tsbuildinfo lived inside the copied install tree, intermittently failing CI with MODULE_NOT_FOUND/ENOENT.** The destructive tests now run hermetically against a temp project, and the tsbuildinfo moved out of `gsd-core/bin/`. (#969) diff --git a/.changeset/973-gsd-planner-edit-tool.md b/.changeset/973-gsd-planner-edit-tool.md deleted file mode 100644 index 852c99c59..000000000 --- a/.changeset/973-gsd-planner-edit-tool.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 989 ---- -**`gsd-planner` now ships the `Edit` tool, so it can no longer destroy `ROADMAP.md` via a whole-file `Write`** — the planner had `Write` but not `Edit` (the #571/#581 writer-agent gap), so an in-place ROADMAP edit fell back to a full overwrite that truncated committed milestone history. The `update_roadmap` step now directs scoped `Edit` calls and explicitly forbids passing the full file to `Write`. (#973) diff --git a/.changeset/974-graphify-budget-missing-value.md b/.changeset/974-graphify-budget-missing-value.md deleted file mode 100644 index 2fbc4cefb..000000000 --- a/.changeset/974-graphify-budget-missing-value.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 986 ---- -**`graphify query --budget` with no value now errors instead of silently ignoring the budget** — a trailing `--budget` parsed as `NaN` and was treated as 'no budget', so the query ran unbounded with no warning. (#974) diff --git a/.changeset/977-fnm-multishell-node-path.md b/.changeset/977-fnm-multishell-node-path.md deleted file mode 100644 index e183c250f..000000000 --- a/.changeset/977-fnm-multishell-node-path.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 992 ---- -**The installer now resolves a stable fnm node path instead of the ephemeral multishell shim on Windows** — managed `.js` hooks were pinned to `fnm_multishells//node.exe`, a per-shell-session path fnm later deletes, breaking every managed hook until reinstall. (#977) diff --git a/.changeset/978-milestone-complete-force-flag.md b/.changeset/978-milestone-complete-force-flag.md deleted file mode 100644 index be3117f51..000000000 --- a/.changeset/978-milestone-complete-force-flag.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 982 ---- -**`gsd-tools milestone complete --force` now actually overrides the unstarted-phase guard** — the dispatcher never parsed `--force`, so the guard's own documented escape hatch was inert. (#978) diff --git a/.changeset/983-trae-windsurf-bare-claude-path-leak.md b/.changeset/983-trae-windsurf-bare-claude-path-leak.md deleted file mode 100644 index b16b31532..000000000 --- a/.changeset/983-trae-windsurf-bare-claude-path-leak.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -type: Fixed -pr: 995 ---- - -**Trae and Windsurf installs no longer leak unreplaced `~/.claude` / `$HOME/.claude` paths** — both converters only rewrote trailing-slash `.claude/` forms, so bare home-path references survived conversion and pointed users at the wrong config dir; bare forms are now rewritten (Codex/Cline #570/#782 parity) and `CLAUDE_CONFIG_DIR` maps to the runtime's own var, with `.claude-plugin` preserved. (#983) diff --git a/.changeset/997-plugin-canonical-path-hook.md b/.changeset/997-plugin-canonical-path-hook.md deleted file mode 100644 index e60c876ee..000000000 --- a/.changeset/997-plugin-canonical-path-hook.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1207 ---- -**Claude Code plugin installs no longer fail with empty `@~/.claude/gsd-core/...` includes** — agents, commands, and templates `@`-include the canonical `~/.claude/gsd-core/` path, but a marketplace plugin install (`claude plugin install`) never creates that directory, so every include resolved to nothing and agents (e.g. the executor) failed. A new `SessionStart` hook (`gsd-ensure-canonical-path.js`) symlinks the canonical path's immutable subdirs (`bin`, `contexts`, `references`, `templates`, `workflows`) to the plugin's bundled tree. It is a no-op in classic `bin/install.js` installs, preserves user-generated files (e.g. `USER-PROFILE.md`), prunes stale links so it self-heals after `claude plugin update`, and uses Windows junctions. (#1207) diff --git a/.changeset/agile-goats-roam.md b/.changeset/agile-goats-roam.md deleted file mode 100644 index dd080012d..000000000 --- a/.changeset/agile-goats-roam.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1005 ---- -**`/gsd-code-review`, `/gsd-code-review --fix`, and `/gsd-eval-review` now inject configured `agent_skills` into their subagents** — these review-family workflows previously spawned their reviewer/fixer/auditor agents (including the `--auto` re-review/re-fix loops) without the project-configured skill and rule context, so any `agent_skills` set for `gsd-code-reviewer`, `gsd-code-fixer`, or `gsd-eval-auditor` were silently ignored. They now query and inject those skills like the ~20 sibling workflows. diff --git a/.changeset/async-external-job-waiting-1165.md b/.changeset/async-external-job-waiting-1165.md deleted file mode 100644 index 8e88fa55d..000000000 --- a/.changeset/async-external-job-waiting-1165.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Added -pr: 1221 ---- -**Async external jobs can now defer an Execute step legally (`external_job_waiting`).** An Execute step that dispatches a long-running external job and commits a `.planning/async-jobs/.json` manifest — deferring `SUMMARY.md` — is now recognized as a *legal deferred state*, not an illegal partial-plan state. `execute-phase` safe-resume, `resume-project`, and `pause-work` reconcile against the manifest instead of re-dispatching (which would duplicate the external compute). This defines the versioned, scheduler-agnostic manifest **stability contract** consumed by the core loop; the scheduler adapter that *produces* manifests is the capability half (#1164). (#1165) diff --git a/.changeset/audit-779-model-catalog-ids.md b/.changeset/audit-779-model-catalog-ids.md deleted file mode 100644 index 54bb0bdf3..000000000 --- a/.changeset/audit-779-model-catalog-ids.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Changed -pr: 1047 ---- -audit(#779): correct stale model-catalog IDs verified against live provider sources. The gemini opus default `gemini-3-pro` → `gemini-3.1-pro-preview` (the bare `gemini-3-pro` ID is undefined in gemini-cli source — only `gemini-3-pro-preview`/`gemini-3.1-pro-preview` exist) and the codex sonnet default `gpt-5.3-codex` → `gpt-5.4` (deprecated per OpenAI's Codex models page); the same two IDs are also updated in the `google`/`openai` provider-preset entries. `qwen3-coder-next` was verified valid (callable on Alibaba Model Studio) and left unchanged. Adds a regression guard against the retired IDs and a sourcing/verification note in CONFIGURATION.md. Catalog IDs are internal defaults; users who pinned the old IDs must update their config. diff --git a/.changeset/bold-otters-travel.md b/.changeset/bold-otters-travel.md deleted file mode 100644 index af08fc307..000000000 --- a/.changeset/bold-otters-travel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1177 ---- -**`phase complete` no longer rewrites an existing roadmap completion date** — repeat runs on an already-`Complete` phase preserve the recorded `YYYY-MM-DD` date (4- and 5-column layouts); empty/`-`/non-date cells are still stamped with the current date. diff --git a/.changeset/brave-cats-leap.md b/.changeset/brave-cats-leap.md deleted file mode 100644 index 29401c9dc..000000000 --- a/.changeset/brave-cats-leap.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1218 ---- -**Legacy ROADMAP projects no longer get deprecation-warning spam** — the free-form ROADMAP warning fired on every command regardless of phase_id_convention; it now only warns when the milestone-prefixed convention is explicitly set and unmet. (#1218) diff --git a/.changeset/brave-foxes-leap.md b/.changeset/brave-foxes-leap.md deleted file mode 100644 index c76d53be6..000000000 --- a/.changeset/brave-foxes-leap.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1198 ---- -**Forking workflows target wrong base branch on `master` repos when `origin/HEAD` is unset** — `execute-phase`, `quick`, `ship`, `complete-milestone`, and `pr-branch` detection bash fell through to a hardcoded `main` fallback whenever `origin/HEAD` was absent (common in `git init` + `remote add` + `fetch` without `set-head`, CI checkouts, and worktrees), causing GSD to fork phase branches off a non-existent `main` on `master` repos. Replaced with a single `gsd_run query git.base-branch` resolver that walks the full precedence ladder: config override → `origin/HEAD` symref → `git remote show origin` → local branch presence → `"main"`. (#1198) diff --git a/.changeset/brave-lions-revolt.md b/.changeset/brave-lions-revolt.md deleted file mode 100644 index 6ba37539d..000000000 --- a/.changeset/brave-lions-revolt.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1193 ---- -**`query user-story.validate` now works** — `mvp-phase` and `verify-work` workflows both invoked this command to validate "As a / I want to / so that" user stories, but no CJS handler existed; every call errored with "Unknown command: user-story". (#1193) diff --git a/.changeset/brave-otters-fix-statusline.md b/.changeset/brave-otters-fix-statusline.md deleted file mode 100644 index 0e0b146a7..000000000 --- a/.changeset/brave-otters-fix-statusline.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1211 ---- -**Context meter no longer sticks at 100%** — the statusline reserved-buffer math was inverted, pinning usage at 100% whenever CLAUDE_CODE_AUTO_COMPACT_WINDOW equalled the total window. (#1194) diff --git a/.changeset/brave-otters-leap.md b/.changeset/brave-otters-leap.md deleted file mode 100644 index 236d268eb..000000000 --- a/.changeset/brave-otters-leap.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1215 ---- -**Roadmapper honors phase_id_convention** — new-project roadmaps now use milestone-prefixed phase IDs when phase_id_convention is set, instead of ignoring the default. (#1205) diff --git a/.changeset/calm-phase-complete-warnings.md b/.changeset/calm-phase-complete-warnings.md deleted file mode 100644 index e3dd21c66..000000000 --- a/.changeset/calm-phase-complete-warnings.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -type: Fixed -pr: 1197 ---- - -**`phase complete` no longer emits false warnings from historical verification metadata or deferred requirement IDs** — two distinct false-positive warning bugs: (A) the verification-status check used a full-text regex that matched `previous_status: gaps_found` in the file body, triggering an "unresolved gaps" warning even when the current frontmatter `status: passed`; the check now reads only the frontmatter `status` key via `extractFrontmatter`. (B) requirement IDs under explicitly deferred/backlog/future/v2 section headings in `REQUIREMENTS.md` were flagged as missing from the Traceability table; the check now skips any section whose heading matches those terms. (#1197) diff --git a/.changeset/calm-rivers-bloom.md b/.changeset/calm-rivers-bloom.md deleted file mode 100644 index 43edc9117..000000000 --- a/.changeset/calm-rivers-bloom.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Added -pr: 1201 ---- -**MemPalace memory capability (opt-in)** — adds cross-session/cross-project recall and verbatim+temporal-KG capture at GSD loop boundaries via the MemPalace MCP server and CLI; disabled by default, skip-on-error. (#1201) diff --git a/.changeset/calm-seals-glide.md b/.changeset/calm-seals-glide.md deleted file mode 100644 index c74ef2370..000000000 --- a/.changeset/calm-seals-glide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1219 ---- -**verify key-links no longer fails on planned future files** — a from: link whose file is declared in a current/upcoming wave plan’s files_modified is now reported pending instead of a hard missing-file failure. (#1202) diff --git a/.changeset/clever-eagles-jump.md b/.changeset/clever-eagles-jump.md deleted file mode 100644 index 07b9f0f20..000000000 --- a/.changeset/clever-eagles-jump.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Added -pr: 584 ---- -spec-phase: spec-completeness edge-probe — a taxonomy-driven Step 5.5 that walks each SPEC requirement against a closed 8-category edge taxonomy (boundary, adjacency, empty/degenerate, encoding, ordering, precision, idempotency, concurrency), proposes concrete candidate edges, and resolves each to covered/dismissed/backstop/unresolved. covered edges add acceptance criteria the planner lifts into must_haves.truths; a soft gate flags unresolved edges. Additive and optional: existing SPECs without an Edge Coverage section remain valid. diff --git a/.changeset/clever-otters-forage.md b/.changeset/clever-otters-forage.md deleted file mode 100644 index 1807a73ee..000000000 --- a/.changeset/clever-otters-forage.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Changed -pr: 1179 ---- -**INVENTORY.md no longer carries `(N shipped)` count scalars** — the hand-maintained absolute counts collided silently on merge (two branches each bumping the same integer to N+1 while the merged tree held N+2), red-flagging CI on the merge commit across all platforms. The manifest's name-set is now the sole registry, anchors are count-free and stable, and a guard test blocks re-adding a count. (#1179) diff --git a/.changeset/clever-yaks-sprint.md b/.changeset/clever-yaks-sprint.md deleted file mode 100644 index 322b609e8..000000000 --- a/.changeset/clever-yaks-sprint.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 952 ---- -**`state patch` and `state record-session` no longer corrupt STATE.md** — a no-match patch no longer rewrites the file (was resetting `milestone_name` and resurrecting a stale `stopped_at`), and `record-session` now persists `--stopped-at`/`--resume-file` even when the body lacks the exact labels. diff --git a/.changeset/eager-goats-forage.md b/.changeset/eager-goats-forage.md deleted file mode 100644 index 000e13bd0..000000000 --- a/.changeset/eager-goats-forage.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 953 ---- -**`/gsd-update` no longer flags `managed-hooks-registry.cjs` as a custom file** — the shipped hook is now recorded in the file manifest, eliminating a perpetual false-positive custom-file warning. diff --git a/.changeset/eager-newts-purr.md b/.changeset/eager-newts-purr.md deleted file mode 100644 index 0021a5a35..000000000 --- a/.changeset/eager-newts-purr.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1009 ---- -**`gsd-tools` no longer throws `EAGAIN` or truncates output under heavy load** — the CLI's stdout/stderr writes now retry the transient `EAGAIN`/`EINTR` errnos and handle short writes when the output stream is a full non-blocking pipe (e.g. the parallel test runner), instead of throwing or silently dropping bytes. diff --git a/.changeset/eager-ravens-dart.md b/.changeset/eager-ravens-dart.md deleted file mode 100644 index 50003fc19..000000000 --- a/.changeset/eager-ravens-dart.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1347 ---- -**Quick worktree execution now accepts parent-or-plan bases for pre-dispatch plan commits** — quick mode records the parent and plan commit around the pre-dispatch PLAN.md commit, lets the worktree guard accept either approved base, materializes the plan from git objects when a runtime forks from the parent, and teaches cleanup to validate the same allowed-base set. (#1265) diff --git a/.changeset/eager-voles-howl.md b/.changeset/eager-voles-howl.md deleted file mode 100644 index 45acc4e6a..000000000 --- a/.changeset/eager-voles-howl.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1249 ---- -**`phase add` no longer reuses an existing phase number when that phase exists only as a roadmap bullet** — the next-number scan now counts phases listed only as `- [ ] **Phase N: ...**` bullets (all checkbox variants, with or without a title), in addition to `### Phase N:` section headers and on-disk phase directories, so a bullet-only phase is no longer shadowed and `phase add` appends after the highest used number. diff --git a/.changeset/fair-lions-patch.md b/.changeset/fair-lions-patch.md deleted file mode 100644 index 127c21c62..000000000 --- a/.changeset/fair-lions-patch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1345 ---- -Preserve curated STATE.md progress frontmatter when `state patch` updates non-progress fields, while still allowing progress-related fields to resync from disk-derived project state. diff --git a/.changeset/fancy-book-path.md b/.changeset/fancy-book-path.md deleted file mode 100644 index 6d047967f..000000000 --- a/.changeset/fancy-book-path.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 994 ---- -**The installer no longer re-adds a duplicate managed hook when the user registered it in `command`+`args` (wrapped) form** — the presence checks only inspected `h.command`, so an args-form wrapper (a common Windows windowless-launcher mitigation) was invisible and a stock entry was appended on every install/update, running the hook twice. (#976) diff --git a/.changeset/gallant-lemurs-roar.md b/.changeset/gallant-lemurs-roar.md deleted file mode 100644 index 5e5380a22..000000000 --- a/.changeset/gallant-lemurs-roar.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 929 ---- -`cmdSkillManifest` now discovers concrete skills nested under `gsd-ns-*` routers (`/gsd-ns-/skills//SKILL.md`), so `gsd-health` and `gsd-settings` report the correct count on nested-layout runtimes (cline, qwen, hermes, augment, trae, antigravity). The scan is scoped to `gsd-ns-*` router dirs only — unrelated user dirs that happen to have a `skills/` subdirectory are not traversed. Dual-routed concretes (same skill installed under two routers) are deduped by name within each root. (#929) diff --git a/.changeset/gentle-quails-snooze.md b/.changeset/gentle-quails-snooze.md deleted file mode 100644 index b9ffc66c1..000000000 --- a/.changeset/gentle-quails-snooze.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1236 ---- -**state record-session no longer pins a CPU core forever** — acquireStateLock busy-spun at 100% CPU when a recoverable errno (e.g. ENOENT from a removed worktree) persisted, because that retry path skipped the backoff sleep and the 30s time budget. Every retry path is now bounded and backed off. (#1236) diff --git a/.changeset/graceful-zebras-munch.md b/.changeset/graceful-zebras-munch.md deleted file mode 100644 index 1a361d6b1..000000000 --- a/.changeset/graceful-zebras-munch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Changed -pr: 1108 ---- -Edge-probe `precision` probe text now names tie-breaking / rounding-mode (half-up vs half-to-even, ceil/floor/truncate), so a surfaced precision edge cues the most common rounding failure mode. Prose-only; firing rule and the 8-category core unchanged. diff --git a/.changeset/happy-finches-travel.md b/.changeset/happy-finches-travel.md deleted file mode 100644 index 9c974f5bf..000000000 --- a/.changeset/happy-finches-travel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 863 ---- -**`/gsd-manager` and `/gsd-autonomous --interactive` no longer silently skip worktree isolation and independent verification on Claude Code.** They dispatched plan/execute as background agents, but a backgrounded Claude Code agent has no Agent/Task tool and cannot spawn the nested executors, plan-checker, or verifier — so isolation and verification silently never ran. Both workflows now resolve the runtime and run plan/execute inline on Claude Code (background dispatch is kept on runtimes that support nested subagents). diff --git a/.changeset/happy-otters-leap.md b/.changeset/happy-otters-leap.md deleted file mode 100644 index 80f3dcbcb..000000000 --- a/.changeset/happy-otters-leap.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Added -pr: 1063 ---- -**`phase uat-passed` predicate** — new runtime-neutral command evaluates HUMAN-UAT results with markdown-aware parsing (ignores frontmatter, fenced code, blockquotes, and HTML comments) and reports pass only when every required check passes. (#1063) diff --git a/.changeset/happy-voles-roar.md b/.changeset/happy-voles-roar.md deleted file mode 100644 index 024e0c6ae..000000000 --- a/.changeset/happy-voles-roar.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1288 ---- -**Researcher agents can now invoke Perplexity** — `gsd-phase-researcher` and `gsd-project-researcher` referenced `mcp__perplexity__*` in their provider dispatch tables but never granted it in their `tools:` allowlist, so Perplexity web research silently fell through to the next provider. The grant is now generated from the researcher profiles, with a parity guard that fails if a future dispatch-table provider is added without its tool grant. (#1284) diff --git a/.changeset/humble-cats-rally.md b/.changeset/humble-cats-rally.md deleted file mode 100644 index 5b4bd97ff..000000000 --- a/.changeset/humble-cats-rally.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1344 ---- -Init phase lookups now resolve active phases whose canonical details live in a flat Phase Details block outside the current milestone summary, restoring requirement coverage for plan/execute/phase-op flows. diff --git a/.changeset/humble-deer-gather.md b/.changeset/humble-deer-gather.md deleted file mode 100644 index 4fa6bfa35..000000000 --- a/.changeset/humble-deer-gather.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 862 ---- -**Installer no longer leaks `gsd-cmd-rewrites-*` temp directories.** Each install that emitted slash commands left one `fs.mkdtempSync` directory under the system temp root; on `tmpfs` `/tmp` hosts these accumulated and consumed RAM-backed storage. `installRuntimeArtifacts()` now removes the temp copy in a `finally` once command files are copied. diff --git a/.changeset/humble-pandas-purr.md b/.changeset/humble-pandas-purr.md deleted file mode 100644 index 59f0baa02..000000000 --- a/.changeset/humble-pandas-purr.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1079 ---- -`validate agents` (and `validate health`) now cross-reference the install manifest to detect manifest-backed Codex agent pair drift: when a generated `agents/gsd-*.md` / `agents/gsd-*.toml` pair has one side missing on disk, the agent is reported as incomplete and `agents_found` is `false` (previously a false-healthy `agents_found: true, missing: []`). `validate health` names the incomplete agents and recommends re-running the installer. The check no-ops when no manifest is present. (#1058) diff --git a/.changeset/issue-version-gate.md b/.changeset/issue-version-gate.md deleted file mode 100644 index 506d68708..000000000 --- a/.changeset/issue-version-gate.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Added -pr: 1181 ---- -Bug-report issues that lack a valid GSD Version are now auto-closed on open by a new `version-gate.yml` GitHub Actions workflow. GitHub Issue Forms only enforce `required: true` in the web UI, so issues filed via the REST API, `gh issue create`, or AI reporters can arrive without a version; values like `idk`, `_No response_`, or an empty field are treated as missing. Affected issues receive a closing comment with instructions to add the version (e.g. `1.18.0`) and reopen; maintainers can add the `version-exempt` label to opt an issue out. diff --git a/.changeset/kimi-runtime-support.md b/.changeset/kimi-runtime-support.md deleted file mode 100644 index 364b350b9..000000000 --- a/.changeset/kimi-runtime-support.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Added -pr: 743 ---- -**Kimi CLI runtime support is now documented and installable** — users can install global GSD Agent Skills with `--kimi --global`, invoke them as `/skill:gsd-*`, and launch the generated custom agent explicitly with `kimi --agent-file`. The custom-agent (`--agent-file`) surface targets the legacy/Python `kimi-cli` contract; newer Kimi Code (`@moonshot-ai/kimi-code`) consumes the same `/skill:gsd-*` skills via `--skills-dir` instead. diff --git a/.changeset/kind-quails-purr.md b/.changeset/kind-quails-purr.md deleted file mode 100644 index eb3da1c90..000000000 --- a/.changeset/kind-quails-purr.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Changed -pr: 1157 ---- -Capability manifests now declare runtime compatibility through a validated runtimeCompat contract, and runtime descriptor interpreters now read artifact layout, skills-home, and hook-surface facts directly from runtime Capability descriptors instead of parallel runtime-name allowlists or fallbacks. This preserves existing supported runtime behavior while making future descriptor-backed runtimes additive. diff --git a/.changeset/lively-quails-wave.md b/.changeset/lively-quails-wave.md deleted file mode 100644 index 0525f10d7..000000000 --- a/.changeset/lively-quails-wave.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Changed -pr: 1141 ---- -Planning-time research, AI integration, and pattern mapping now participate through Capability declarations and rendered plan:pre hooks, with developer documentation for building GSD capabilities. diff --git a/.changeset/lucky-wasps-chatter.md b/.changeset/lucky-wasps-chatter.md deleted file mode 100644 index a703d4e1d..000000000 --- a/.changeset/lucky-wasps-chatter.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Changed -pr: 1062 ---- -**The planner now blocks plans that would self-trip their own verify gate** — when an acceptance criterion negative-greps for a literal (`grep -c 'LIT' file == 0`) and that same literal appears verbatim in an `` body, plan creation now fails at write time instead of letting the executor waste cycles on a comment-text echo at commit time. Unquoted/ambiguous grep targets warn instead of failing; add `` to allowlist a legitimate occurrence. (#1062) diff --git a/.changeset/merry-birds-gather.md b/.changeset/merry-birds-gather.md deleted file mode 100644 index 78fd848e4..000000000 --- a/.changeset/merry-birds-gather.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1362 ---- -**The `map-codebase` and `docs-update` workflows no longer collect background sub-agent results with the deprecated Claude Code `TaskOutput` tool** — they keep `run_in_background=true` on the spawn and `Read` each agent's `outputFile` (from the `async_launched` result) once it reports completion, removing the `TaskOutput(block=true)` main-session hang surface (anthropics/claude-code#20236). Completion-marker contracts and on-disk verification are unchanged, and the non-Claude runtime fallbacks are preserved. diff --git a/.changeset/nested-namespace-skill-layout.md b/.changeset/nested-namespace-skill-layout.md deleted file mode 100644 index 6c42da6d2..000000000 --- a/.changeset/nested-namespace-skill-layout.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Changed -pr: 883 ---- -**Namespace router skills now nest their concrete sub-skills at install time (#69).** On runtimes with non-recursive skill loaders (Claude global, Cline, Qwen, Hermes, Augment, Trae, Antigravity) the installer emits the 6 `gsd-ns-*` routers as the only top-level skill bundles and nests the ~61 concrete skills under `/skills//SKILL.md`, cutting the eager skill-listing overhead to ≈6 entries. Concrete skills stay reachable via the router's `Read skills//SKILL.md` routing table. **Breaking:** on those runtimes the concrete skills are no longer invocable by bare name through the Skill tool / top-level listing — route via the namespace router (or the unchanged `/gsd-*` slash command where a commands surface exists). Legacy top-level `gsd-/` skill dirs are removed on upgrade. Recursive/unconfirmed loaders (Cursor, Codex, Copilot, Windsurf, CodeBuddy, OpenCode, Kilo) keep the flat layout. diff --git a/.changeset/nimble-eagles-fly.md b/.changeset/nimble-eagles-fly.md deleted file mode 100644 index 0a6ab0b3d..000000000 --- a/.changeset/nimble-eagles-fly.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1133 ---- -**`model_policy` is now honored on the default `claude` runtime** — including the `anthropic-fable` Claude Fable 5 preset. Policy-resolved model IDs map to Claude Code agent aliases (e.g. `claude-fable-5` → `fable`), and IDs without a Claude alias warn and fall back to the configured tier. Forward-port of #1133 (originally shipped on the 1.4.5 hotfix line). (#1133) diff --git a/.changeset/nimble-jays-fly.md b/.changeset/nimble-jays-fly.md deleted file mode 100644 index ba5ea417c..000000000 --- a/.changeset/nimble-jays-fly.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 728 ---- -**`/gsd-plan-review-convergence` now blocks on actionable review findings outside PLAN.md (#724).** The convergence summary contract includes current_actionable alongside current_high, and reviews-mode planning/checking requires actionable MEDIUM/LOW feedback to be incorporated or explicitly deferred in executable PLAN.md content. diff --git a/.changeset/nimble-mice-climb.md b/.changeset/nimble-mice-climb.md deleted file mode 100644 index d656faa73..000000000 --- a/.changeset/nimble-mice-climb.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1299 ---- -**Config docs/prompts now match the consumers** — `workflow.subagent_timeout` is documented in milliseconds (default 300000), not "seconds (default 600)" (a user who entered 600 got a 600 ms timeout); `review.models.` is documented as a bare model id injected into `--model`/`-m`, not a shell command; and `workflow.test_command` / `workflow.build_command` (consumed by verify-phase, execute-phase, audit-fix, and the post-merge gate) are now accepted by `config set` and documented. (#1296) diff --git a/.changeset/nimble-newts-rally.md b/.changeset/nimble-newts-rally.md deleted file mode 100644 index ecca6fc3e..000000000 --- a/.changeset/nimble-newts-rally.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Changed -pr: 1313 ---- -**Graphify now respects surface/profile state, not just `graphify.enabled`** — `gsd-tools graphify` is off unless graphify is installed AND surfaced AND `graphify.enabled` is true (previously only the config key was checked). The gate is now runtime-aware: Codex/Cursor/etc. read their own runtime's surface instead of `~/.claude`. (#1313) diff --git a/.changeset/nimble-quails-hum.md b/.changeset/nimble-quails-hum.md deleted file mode 100644 index 6e697bc90..000000000 --- a/.changeset/nimble-quails-hum.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Changed -pr: 1303 ---- -**Isolated-executor recovery now fails safe** — when an isolated (worktree) executor run is rejected (you decline to merge it) or over-reached the requested scope, `/gsd:execute-phase` and `/gsd:quick` no longer default or propose recovery by editing the primary checkout (`main`). The orchestrator halts safely and offers a fresh, narrowly-scoped worktree or inspect/discard; editing the primary checkout requires explicit, clearly-labeled confirmation. (#1292) diff --git a/.changeset/nimble-yaks-munch.md b/.changeset/nimble-yaks-munch.md deleted file mode 100644 index 1677bd988..000000000 --- a/.changeset/nimble-yaks-munch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1231 ---- -**`changeset new --pr 0` now accepted at creation** — the required-field guard treated the integer 0 as a missing `--pr` flag, so the documented `pr: 0` placeholder could not be authored via the CLI. (#1231) diff --git a/.changeset/noble-orcas-tumble.md b/.changeset/noble-orcas-tumble.md deleted file mode 100644 index 6c968fa3d..000000000 --- a/.changeset/noble-orcas-tumble.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Changed -pr: 1147 ---- -Migrate code review, security, and Nyquist verification workflows to ADR-857 capability hooks. diff --git a/.changeset/noble-tigers-tumble.md b/.changeset/noble-tigers-tumble.md deleted file mode 100644 index d733e85bb..000000000 --- a/.changeset/noble-tigers-tumble.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 958 ---- -**`$gsd-quick` Codex adapter no longer assumes typed `spawn_agent(agent_type=...)`** — documents that typed planner/executor spawning needs the agent_type-capable Codex schema and provides a clearly-labeled generic-subagent fallback when only `multi_agent_v1` is exposed. diff --git a/.changeset/proud-foxes-travel.md b/.changeset/proud-foxes-travel.md deleted file mode 100644 index 44d83abb6..000000000 --- a/.changeset/proud-foxes-travel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1172 ---- -**`state update` and `roadmap update-plan-progress` now handle current Markdown artifact shapes** — state field read/replace works on table-format `STATE.md` (`| Status | … |`), and `roadmap update-plan-progress` inserts missing per-plan checklist rows (filling partial gaps), tolerates `Plans:`/`**Plans:**`/`**Plans**:`, and scopes changes to the active milestone. diff --git a/.changeset/quick-ibex-gather.md b/.changeset/quick-ibex-gather.md deleted file mode 100644 index 4576cc675..000000000 --- a/.changeset/quick-ibex-gather.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1078 ---- -`state planned-phase` now advances the Status field when the prior phase left a `Complete ✓` (checkmark) or bare `Complete` terminal status. Previously such a status matched no known template default, so the transition was silently skipped and the state machine stayed stuck on the prior phase. Caveat-bearing statuses (e.g. `Complete but needs manual QA`) remain preserved. (#1070) diff --git a/.changeset/quick-yaks-march.md b/.changeset/quick-yaks-march.md deleted file mode 100644 index 7d66f985e..000000000 --- a/.changeset/quick-yaks-march.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Changed -pr: 1315 ---- -**Intel and loop-hook rendering now honor the single capability `active` state** — `gsd-tools intel` gates through the shared resolver (consistency; intel stays governed by `intel.enabled`), and loop-hook rendering now suppresses a config-disabled capability's hooks via the capability-level `active` gate (fail-closed), not just per-hook `when`. (#1315) diff --git a/.changeset/rapid-pumas-fly.md b/.changeset/rapid-pumas-fly.md deleted file mode 100644 index a863ebdaa..000000000 --- a/.changeset/rapid-pumas-fly.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Added -pr: 1261 ---- -**`agent_skills` can now reference Claude-Code plugin-provided skills** via the namespaced `global::` form (e.g. `global:coderabbit:code-review`). On the Claude runtime the agent's skills block emits a by-name Skill-tool load directive that resolves the plugin skill (no plugin-cache path is read); path-resolvable skills keep the existing `@`-include unchanged; on non-Claude runtimes a namespaced entry is skipped with a warning. The 22 agent_skills-consumer agents now carry the `Skill` tool so they can load plugin-provided skills. diff --git a/.changeset/runtime-install-no-drift-tests.md b/.changeset/runtime-install-no-drift-tests.md deleted file mode 100644 index 9981ebfff..000000000 --- a/.changeset/runtime-install-no-drift-tests.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -type: Changed -pr: 867 ---- -Added no-drift guard tests (`tests/issue-57-runtime-install-no-drift.test.cjs`) that protect the Runtime Install Policy Module boundary (ADR-58) and the explicit Runtime Config Adapter Registry (#60). They fail loudly when supported-runtime metadata is added to an installer call site (`allRuntimes`, the interactive `runtimeMap` menu) without a matching registry adapter entry, or when config-mutation dispatch escapes the registry's declared install surfaces — catching reintroduction of the scattered per-runtime branching those seams removed. - diff --git a/.changeset/serene-mice-swim.md b/.changeset/serene-mice-swim.md deleted file mode 100644 index 4e70dc202..000000000 --- a/.changeset/serene-mice-swim.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Changed -pr: 1117 ---- -Edge-probe now surfaces a zero-classification requirement (non-empty prose, no shape cue matched, no `shapes` override) as a single soft `unclassified — review manually` candidate instead of silently dropping it. Dismissible like any edge; `shapes: []` opt-out stays silent; TAXONOMY unchanged. diff --git a/.changeset/sharp-geese-glide.md b/.changeset/sharp-geese-glide.md deleted file mode 100644 index 5d207cb60..000000000 --- a/.changeset/sharp-geese-glide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Changed -pr: 1311 ---- -**Capability state now reports a tri-state `active`** — `gsd-tools capability state` adds an `active` field per capability (installed && surfaced && config-enabled), alongside the existing `enabled` (installed && surfaced). Internal `isCapabilityActive(capId, cwd)` lets consumers honor the single resolved on/off answer. (#1311) diff --git a/.changeset/sharp-wasps-fly.md b/.changeset/sharp-wasps-fly.md deleted file mode 100644 index 2463f4f8b..000000000 --- a/.changeset/sharp-wasps-fly.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1252 ---- -**`state.*` writes no longer silently revert the STATE.md frontmatter `status`/`stopped_at`** — an incidental write (e.g. `state record-session`) that doesn't change the body's `Status:`/`Stopped at:` source field now preserves the existing frontmatter value instead of re-deriving it from possibly-stale body text. Legitimate transitions (e.g. `begin-phase`/`complete-phase`, which do update the body Status) still re-derive normally, so a verified-complete phase can no longer be flipped back to `verifying` by an unrelated write. diff --git a/.changeset/silly-pandas-munch.md b/.changeset/silly-pandas-munch.md deleted file mode 100644 index 70c33a34a..000000000 --- a/.changeset/silly-pandas-munch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 951 ---- -**`audit-open` no longer false-flags completed quick tasks** — quick-task SUMMARYs now carry `status: complete` in frontmatter by construction, so the milestone-close auditor stops reporting finished quick tasks as `[unknown]`. diff --git a/.changeset/steady-otters-leap.md b/.changeset/steady-otters-leap.md deleted file mode 100644 index c84be2959..000000000 --- a/.changeset/steady-otters-leap.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1092 ---- -**Workspace (local) Antigravity and Copilot skill installs no longer point at the global config home** — a local install rewrote `~/.claude/` references in `SKILL.md` bodies to the global `~/.gemini/antigravity/` / `~/.copilot/` paths instead of the workspace-relative `.agent/` / `.github/`, because the skills layout wrapper passed the runtime name into the converter's `isGlobal` parameter slot. (#1092) diff --git a/.changeset/sturdy-herons-leap.md b/.changeset/sturdy-herons-leap.md deleted file mode 100644 index 2c1a509ea..000000000 --- a/.changeset/sturdy-herons-leap.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1084 ---- -Fix the workflow gsd_run launcher being unreachable in later bash blocks on runtimes that run each fenced block in a fresh shell (e.g. Claude Code): ship a standalone gsd-core/bin/gsd_run executable and have the per-file preamble persist the launcher's bin dir onto PATH via CLAUDE_ENV_FILE, with the inline function definition kept as the fallback for all other runtimes. diff --git a/.changeset/swift-otters-reroute.md b/.changeset/swift-otters-reroute.md deleted file mode 100644 index b0bbabead..000000000 --- a/.changeset/swift-otters-reroute.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 1148 ---- -**`/gsd:phase insert` and `/gsd:phase --edit` no longer dead-end recording Roadmap Evolution** — `query state.add-roadmap-evolution` was rejected as "SDK-only" with an error that pointed back at the very command that just failed, and no CJS handler existed after the SDK retirement. The handler is now implemented in CJS, so the insert/edit phase workflows append the `### Roadmap Evolution` entry under `## Accumulated Context` (creating the subsection if missing, deduping identical entries) as documented. (#1148) diff --git a/.changeset/tidy-lemurs-travel.md b/.changeset/tidy-lemurs-travel.md deleted file mode 100644 index 3a6b5a27f..000000000 --- a/.changeset/tidy-lemurs-travel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Changed -pr: 1271 ---- -**`gsd-verifier` no longer marks behavior-dependent must-haves `VERIFIED` on symbol presence alone** — a truth that asserts a state transition or a cancellation/cleanup/ordering invariant is marked `PRESENT_BEHAVIOR_UNVERIFIED` when no test exercises it: excluded from the `verified_truths` score, reported as a `behavior_unverified` count, and routed to human verification, so a clean N/N now certifies behavioral evidence rather than mere symbol presence. (#966) diff --git a/.changeset/vivid-lemurs-munch.md b/.changeset/vivid-lemurs-munch.md deleted file mode 100644 index 8d80c1d70..000000000 --- a/.changeset/vivid-lemurs-munch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 847 ---- -Corrected the installer `--help` profile skill counts: `core` now shows 8 (was 7) and `standard` shows 14 (was 13), both derived from `PROFILES` so they can't drift again; the `full` line drops the stale hardcoded `66` for `all skills`. (#834) diff --git a/.changeset/vivid-pumas-rally.md b/.changeset/vivid-pumas-rally.md deleted file mode 100644 index 15863e29b..000000000 --- a/.changeset/vivid-pumas-rally.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 731 ---- -**Codex-installed GSD skills and agents no longer rely on a bare `gsd-tools` executable** — generated Codex surfaces now call the bundled shim, and workflow launchers can resolve the Codex shim-only install path. diff --git a/.changeset/wired-discuss-loop-step.md b/.changeset/wired-discuss-loop-step.md deleted file mode 100644 index 42b812890..000000000 --- a/.changeset/wired-discuss-loop-step.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -type: Fixed -pr: 1199 ---- - -**Wire the discuss loop step for capability hooks** — capabilities can now register `discuss:pre`/`discuss:post` hooks (e.g. discuss-time context recall and CONTEXT capture); previously `discuss` was contract-declared but structurally unwireable. Also collapses the host-loop file set to a single source of truth and adds an authoring-time guard rejecting hooks at unwired extension points. (#1199) diff --git a/.changeset/wise-cranes-sing.md b/.changeset/wise-cranes-sing.md deleted file mode 100644 index 7e11533ca..000000000 --- a/.changeset/wise-cranes-sing.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Added -pr: 1225 ---- -**`gsd-tools capability set` — turn capabilities on/off and gate hooks from one command.** Adds the write side of the capability system (ADR-857/ADR-1213): `capability set --on|--off` toggles a capability through the runtime surface (the canonical on/off switch) and `--gate =` toggles a hook within an enabled capability, then re-resolves and reports — so disabling a capability is consistent across surface and config ("off means off") as a write-time invariant. `/gsd:settings` capability hook-gates now route through it. (#1213) diff --git a/.changeset/wise-ibex-tumble.md b/.changeset/wise-ibex-tumble.md deleted file mode 100644 index 3ed177654..000000000 --- a/.changeset/wise-ibex-tumble.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 729 ---- -**`/gsd-autonomous --converge` now routes phase planning through plan-review convergence** instead of silently ignoring the flag. (#711) diff --git a/.changeset/witty-cats-wander.md b/.changeset/witty-cats-wander.md deleted file mode 100644 index d86131a16..000000000 --- a/.changeset/witty-cats-wander.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 955 ---- -Hermes skills now install at skills/gsd/gsd-/SKILL.md with name gsd-, restoring canonical /gsd- dispatch that was broken by the bare-stem prefix introduced in #3664. diff --git a/.changeset/zesty-badgers-caper.md b/.changeset/zesty-badgers-caper.md deleted file mode 100644 index 2f911e84c..000000000 --- a/.changeset/zesty-badgers-caper.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Changed -pr: 1320 ---- -**`verify plan-structure` warns on cross-task region-scope conflicts (#968)** — when a plan task's file-wide negative grep (`! grep -Eq 'PAT' file` / `grep -c 'PAT' file == 0`) bans a construct a sibling task legitimately requires elsewhere in the same file, plan validation now surfaces a warning pointing to the new region/function-scoped negative-gate idiom (documented in the gsd-planner guidance and the planner-antipatterns reference, with a worked banned-in-X / required-in-Y example). Warn-only: it never errors and never changes `valid`. (#1320) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72ed80a19..a60c1508c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,186 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). ## [Unreleased] +## [1.5.0] - 2026-06-17 + +### Added + +- **`gen-capability-registry` now rejects duplicate artifact producers at the same Loop Extension Point** — if two capability `steps` declare `produces: []` at the same point, the generator throws at gen time naming the artifact, the point, and the producing capability ids, instead of letting the topological sort pick a winner silently (which left ADR-857 Decision #6's data-flow contract undefined). The check counts distinct `(capId, stepIdx)` producer steps, so a single step listing an artifact twice does not false-positive. ADR-894 §4's enumerated cross-capability invariant list gains the artifact-production-uniqueness rule. (#1123) (#1131) +- **`gsd-tools drift-guard` — deterministic plan-drift severity/authority decisions (ADR-22).** The plan-review source-grounding pass now classifies cited-symbol drift through a tested seam (5-rung authority ladder, `grep`→`intel` auto-upgrade, severity mapping, rung≥3 hard-block) instead of re-deriving the rules from workflow prose on each run. (#1190) (#1242) +- **`/gsd-progress --next --auto --converge` now routes planning through plan-review convergence.** ADR-15's designated *primary* convergence surface is wired into the progress/next workflow (previously only `/gsd-autonomous --converge` honored it; on `/gsd-progress` the flag was silently dropped). Accepts `--cross-ai` as an alias plus reviewer flags and `--max-cycles N`, and is gated on `workflow.plan_review_convergence`. (#1190) (#1237) +- +**`gsd-tools query teams-status` + a plan-phase warning detect claude-code agent-teams** — GSD's multi-agent orchestration can stall under claude-code's experimental agent-teams (a subagent's completion can fail to route back to the orchestrator). A new read-only `query teams-status` command reports `{ active, runtime, env_present, source }` (and `--active` for a clean shell guard), and `/gsd:plan-phase` now emits a single non-fatal warning when agent-teams is detected, recommending you disable it for GSD workflows. The detector only activates on the `claude` runtime with `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS` strictly truthy — every other runtime and the teams-off path are completely unaffected. (#1355) (#1371) +- spec-phase: prohibition probe — a prose-orchestrated Step 5.6 that surfaces the unwritten *must-NOT* constraints (values/safety/ethics) a feature could silently become but the spec never forbids. Two stages per requirement: an adversarial recall question ("what could this silently become that the author would NOT want?") then a one-pass precision classifier that drops routine engineering and keeps genuine prohibitions. Confirmed prohibitions become NEGATIVE SPEC acceptance criteria carrying a `test`/`judgment` verification tier, which plan-phase lifts into the `must_haves.prohibitions` sibling block (`truths` untouched). Judgment-tier items soft-gate at verify time (never silent, never hard-halt); unwired test-tier items fail closed. The recall stage is model-driven (no compiled engine); canon-bound concerns (OWASP/GDPR/fairness) are referred to `/gsd:secure-phase`. Additive and optional: existing SPECs without a Prohibitions section remain valid. Second adapter of the `probe-core` resolution model (ADR-550 Decision 7). (#1149) +- **Optional `## Business Context` section in the PROJECT.md template** — a four-field block (Customer, Revenue model, Success metric, Strategy notes) for monetized or customer-facing projects, positioned between Core Value and Requirements. Optional by default (an HTML comment tells non-business projects to delete it), capped at four one-line fields to stay a constraint reference rather than a business plan, and reviewed at each milestone by `/gsd-complete-milestone` when present. (#72) (#756) +- **Async external jobs can now defer an Execute step legally (`external_job_waiting`).** An Execute step that dispatches a long-running external job and commits a `.planning/async-jobs/.json` manifest — deferring `SUMMARY.md` — is now recognized as a *legal deferred state*, not an illegal partial-plan state. `execute-phase` safe-resume, `resume-project`, and `pause-work` reconcile against the manifest instead of re-dispatching (which would duplicate the external compute). This defines the versioned, scheduler-agnostic manifest **stability contract** consumed by the core loop; the scheduler adapter that *produces* manifests is the capability half (#1164). (#1165) (#1221) +- **MemPalace memory capability (opt-in)** — adds cross-session/cross-project recall and verbatim+temporal-KG capture at GSD loop boundaries via the MemPalace MCP server and CLI; disabled by default, skip-on-error. (#1201) (#1201) +- spec-phase: spec-completeness edge-probe — a taxonomy-driven Step 5.5 that walks each SPEC requirement against a closed 8-category edge taxonomy (boundary, adjacency, empty/degenerate, encoding, ordering, precision, idempotency, concurrency), proposes concrete candidate edges, and resolves each to covered/dismissed/backstop/unresolved. covered edges add acceptance criteria the planner lifts into must_haves.truths; a soft gate flags unresolved edges. Additive and optional: existing SPECs without an Edge Coverage section remain valid. (#584) +- **`phase uat-passed` predicate** — new runtime-neutral command evaluates HUMAN-UAT results with markdown-aware parsing (ignores frontmatter, fenced code, blockquotes, and HTML comments) and reports pass only when every required check passes. (#1063) (#1063) +- Bug-report issues that lack a valid GSD Version are now auto-closed on open by a new `version-gate.yml` GitHub Actions workflow. GitHub Issue Forms only enforce `required: true` in the web UI, so issues filed via the REST API, `gh issue create`, or AI reporters can arrive without a version; values like `idk`, `_No response_`, or an empty field are treated as missing. Affected issues receive a closing comment with instructions to add the version (e.g. `1.18.0`) and reopen; maintainers can add the `version-exempt` label to opt an issue out. (#1181) +- **Kimi CLI runtime support is now documented and installable** — users can install global GSD Agent Skills with `--kimi --global`, invoke them as `/skill:gsd-*`, and launch the generated custom agent explicitly with `kimi --agent-file`. The custom-agent (`--agent-file`) surface targets the legacy/Python `kimi-cli` contract; newer Kimi Code (`@moonshot-ai/kimi-code`) consumes the same `/skill:gsd-*` skills via `--skills-dir` instead. (#743) +- **`agent_skills` can now reference Claude-Code plugin-provided skills** via the namespaced `global::` form (e.g. `global:coderabbit:code-review`). On the Claude runtime the agent's skills block emits a by-name Skill-tool load directive that resolves the plugin skill (no plugin-cache path is read); path-resolvable skills keep the existing `@`-include unchanged; on non-Claude runtimes a namespaced entry is skipped with a warning. The 22 agent_skills-consumer agents now carry the `Skill` tool so they can load plugin-provided skills. (#1261) +- **`gsd-tools capability set` — turn capabilities on/off and gate hooks from one command.** Adds the write side of the capability system (ADR-857/ADR-1213): `capability set --on|--off` toggles a capability through the runtime surface (the canonical on/off switch) and `--gate =` toggles a hook within an enabled capability, then re-resolves and reports — so disabling a capability is consistent across surface and config ("off means off") as a write-time invariant. `/gsd:settings` capability hook-gates now route through it. (#1213) (#1225) + +### Changed + +- Added an opt-in `anthropic-fable` model policy provider preset for Claude Fable 5 high-budget routing while preserving the existing Anthropic Opus 4.8 defaults and `anthropic` provider preset. (#1014) (#1015) +- **Windsurf/Devin workspace skills now install to the canonical `.devin/skills/` directory** — fresh workspace installs write skills under `.devin/skills/` (Devin Desktop's documented preferred location) instead of `.windsurf/skills/`; the legacy `.windsurf/skills/` layout is still recognized. The global `~/.codeium/windsurf/skills/` path is unchanged. (#1093) (#1093) +- +**`loadCentralConfigKeys` now fails loud on a malformed central config-schema instead of silently returning an empty Set** — `ENOENT` (the schema legitimately absent) still returns an empty Set silently, but a JSON parse error or any other read failure now writes a prominent `stderr` warning naming the schema file and throws `ExitError(1)`. Previously a single `catch (_)` swallowed parse errors too, so a merge-conflict marker or truncated write in `config-schema.manifest.json` made every capability config key look non-central — the config-key collision / `pending-migration` gate fired zero warnings and `--check` passed clean, defeating the gate invisibly. (#1124) (#1131) +- **Capability hook rendering now consumes resolved Capability State** — `gsd-tools loop render-hooks` uses the same installed/surfaced/configured state reported by `gsd-tools capability state`, so disabling a migrated capability at the runtime surface removes its workflow hooks even when config defaults are enabled. Migrated capability config keys remain accepted through the generated capability registry/federated config path instead of duplicated central `VALID_CONFIG_KEYS` entries. (#1136) (#1153) +- +Added ADR-857 Phase 6 capstone conformance coverage so migrated Capability activation keys cannot be read directly from host loop workflows, Capability-owned config keys stay out of the central schema, and the host loop workflow size budgets remain documented. The verify-work UI automation preflight now resolves UI activation through the Capability hook registry instead of reading `workflow.ui_phase` directly. (#1158) +- **ADR-857 phase 6 complete: optional features are now Capabilities, not inline loop branches.** `tdd`, `schema-gate`, `drift`, `gap-analysis`, and `profile-pipeline` are migrated out of the five-step host loop into declarative Capabilities (loop hooks + a command family); their config keys are federated to capability ownership; and the `plan-phase`/`execute-phase` workflow bodies shrink accordingly. Two previously-declared-but-dead capability gates now actually fire — the security ship-time gate (`ship:pre`) and the UI safety gate (`execute:wave:post`) — and the phase-6 conformance gate is hardened to be un-gameable (rejects empty stubs, requires loop-body shrink, verifies hook dispatch and gate-result contracts). Behavior is preserved, verified across five adversarial review passes. (#1139, #1167, #1168, #1169) (#1183) +- +**Test-tier prohibitions are now a real, provable gate instead of a permanent, unsatisfiable `gaps_found`** — the deferred ENFORCEMENT half of ADR-550 Decision 5d (the "heavy half" that #644 / PR #1149 deferred) has landed. A new deterministic `check prohibition-enforcement` sub-command (authored as `src/prohibition-enforcement.cts`, compiled by `build:lib` to the gitignored `gsd-core/bin/lib/prohibition-enforcement.cjs`) is the missing PRODUCER: it locates the wired mechanical check, runs it for a genuine **non-vacuous** pass, builds `enforcementEvidence`, and emits the `dispositionForProhibition()` verdict. The previously-unreachable green branch in `dispositionForProhibition()` is now reachable from the live pipeline — a test-tier prohibition with a genuinely-passing wired check disposes `green` and can reach `passed`, while a missing, non-attested, or non-passing check hard-gates (flagged, never green → `gaps_found`) in BOTH interactive and autonomous modes (ADR-550 D4 / D3). `verify-phase.md` wires the consumer; the green/fail-closed policy in `src/probe-core.cts` is untouched. Both wired-check kinds are accepted (ADR-550 D2): a `node --test` negative test (requiring a real reported test — an empty file, which `node --test` counts as one passing "test", does NOT green) AND a lint/AST rule run as `eslint --format json` filtered by `ruleId` (so plugin rules like `local/*` load — bare `--rule` cannot), anchored on the in-tree `local/no-source-grep` rule (dogfooding, ADR-550 D4). This enforcement seam is the concrete instance of ADR-857 open-question §147 and lands on the core verify rail, never in `capabilities/` (D6). (#1259) + +**Honest scope — `failFirst` is caller-attested, not yet machine-proven.** This lands the *execution + non-vacuous-pass* half: the producer requires the caller to attest `failFirst: true` and the check to genuinely run and pass. It does NOT yet independently prove the check *fails-on-violation* (the literal `regression-must-fail-first` property) — cheap proof of that at verify time needs running the check against a known violation fixture, which is a **tracked follow-up (#1279)**. The red-first property currently rests on caller attestation, surfaced transparently in the evidence record. + +**Correction to the issue body (#1259):** the issue's "96 invalid/error negative-proof cases" figure is wrong. For the `no-source-grep` anchor specifically, the genuine `regression-must-fail-first` proofs are its **two `invalid` cases** (the `.includes()` and `.match()` blocks) in `tests/eslint-rules.test.cjs` — not 96. The anchor argument is unaffected (those two cases ARE real fail-first proofs); only the count was off. (#1273) +- **The test-tier prohibition gate now has a deterministic SOURCE for its wired check** — a resolved `test`-tier `must_haves.prohibitions` item MAY carry an optional `check` descriptor authored at spec-phase: the flat-scalar keys `check_kind` (`node-test` | `lint-rule`), `check_target`, and `check_rule` (lint-rule only). `projectProhibitions` projects these scalars deterministically and verify-phase reads them back (via `descriptorFromProjection`) to locate the check handed to `check prohibition-enforcement` — so a wired, passing test closes the gap with **zero manual descriptor authoring** (previously the verify-phase LLM had to invent `{kind, target, rule}` each run, #1259). This extends the ADR-550 Decision 3 prohibition-item shape (ratified in a dated 2026-06-15 ADR-550 addendum). The descriptor is **optional and fully backward-compatible** — a prohibition with no descriptor parses and disposes byte-identically to today — and **fail-closed**: a partial, invalid, or absent descriptor falls through to the producer's existing fail-closed locate, never a silent green. The descriptor is represented as flat scalars (not a nested `check:{}` object) to keep the shared `parseMustHavesBlock` round-trip regression-free. Out of scope: machine-proven fail-first (#1279) and the `dispositionForProhibition` policy stay unchanged. (#1278) (#1301) +- +**Test-tier prohibition fail-first is now MACHINE-PROVEN, not caller-attested** — the deferred literal `regression-must-fail-first` property of ADR-550 Decision 4 (the gap #1259 / PR #1273 left as a tracked follow-up) has landed. The `check prohibition-enforcement` producer (`src/prohibition-enforcement.cts`, compiled by `build:lib` to the gitignored `gsd-core/bin/lib/prohibition-enforcement.cjs`) no longer trusts the caller's `failFirst` attestation: before a clean, non-vacuous pass can dispose a `test`-tier prohibition green, the new `defaultProveFailFirst` prover independently RUNS the wired check against a KNOWN VIOLATION and confirms it goes RED. Attestation is gone from the green AND (`passed = proof.provenFailFirst === true && run.passed === true`); any other outcome — passes-on-violation, can't-prove, throws, times out, or no violation source — **hard-gates in BOTH interactive and autonomous modes** (ADR-550 D4 / D3). The evidence record gains a `failFirstProof` field recording HOW fail-first was proven (FF-07). A caller can no longer green a toothless check. + +The violation is sourced from a new descriptor field, **`CheckDescriptor.violationFixture`** — an author-supplied path to a known-bad subject. For a `lint-rule` the prover lints that fixture and requires the rule id to appear in the JSON report (the rule must have teeth); for a `node-test` the prover spawns the negative test with the subject injected through the **`GSD_PROHIB_SUBJECT`** env convention and requires a NON-VACUOUS red — `# fail >= 1` AND a failing test named distinctly from the file (`isNonVacuousNodeTestRed`), so a violation fixture that merely CRASHES the test at load is not mistaken for the negative assertion firing red (symmetric with the clean-pass non-vacuity guard). The node-test prover also requires the `violationFixture` to EXIST (resolved against `cwd`) before spawning — a missing/typo'd path fail-CLOSES rather than letting an honest test's ENOENT crash forge a green (symmetric with the lint path's file-result guard). The deterministic spec→verify path composes end-to-end: a fourth flat scalar **`check_violation_fixture`** is projected by `projectProhibitions` and read back by `descriptorFromProjection` (rides both kinds), so a prohibition authored with all four `check_*` scalars machine-proves fail-first and greens through the projection alone — zero hand-authoring at verify time (#1278 + #1279 + #1346; round-trip pinned by a fast-check property + CHK-03(D) + an end-to-end COMPOSE capstone). One documented residual remains under **#1346**: the node-test proof confirms the fixture exists and the check reds, but cannot generically prove the red was *caused by* the subject's content rather than by the env merely being set. The `lint-rule` path is fully shippable now and is dogfooded against the in-tree `local/no-source-grep` rule; the `node-test` path ships its mechanism (a fixture-bearing descriptor IS machine-proven) and is exercised by SYNTHETIC temp fixtures — there is no live in-tree `node --test` prohibition to dogfood. `CheckDescriptor.failFirst` is **DEMOTED, not removed** (FF-08): it is kept as a non-authoritative hint so the #1259 route-JSON shape and the `CheckDescriptor` type stay backward-compatible mid-migration, but no path greens on it alone. The green/fail-closed policy in `src/probe-core.cts` (`dispositionForProhibition`, reads only `evidence.length > 0`) is untouched; the evidence array shape is additive. This closes ADR-550's D5d follow-up — see the dated 2026-06-15 ADR-550 addendum. (#1279) + +**PR-review flag — `GSD_PROHIB_SUBJECT` + `violationFixture` are PROPOSED, renamable conventions.** Both are net-new surface with ZERO live in-tree consumers (no in-tree node-test prohibition yet; node-test proof runs only on synthetic test fixtures, the real dogfood stays the lint-rule). They are forward-looking scaffolding, so a later rename — or replacing the env var with an argv — is a mechanical, zero-migration find/replace. Surfacing them here so the maintainer can **ratify, rename, or replace them at PR review** with no migration cost, exactly as #1278's ADR addendum was reviewed at PR time. The `failFirst` demotion is likewise open to weighing outright removal; the keep-as-hint rationale is recorded in the ADR addendum. (#1314) +- **Read-only verifier/auditor agents now ship a Claude-Code `disallowedTools` deny-list** — the installer injects a framework-level write-tool deny-list into the Claude copies of the read-only verifier/auditor agents (gsd-verifier, gsd-plan-checker, gsd-integration-checker, gsd-doc-verifier, gsd-eval-auditor, gsd-ui-auditor, gsd-ui-checker) so write actions are blocked even if a tool grant is inherited. Injected for Claude only; other runtimes are unaffected. (#1081) (#1081) +- +**Antigravity workspace skills now install to the canonical `.agents/` directory** — fresh installs write workspace artifacts under `.agents/` (the Google-Codelabs-documented base) instead of `.agent/`; the legacy `.agent/` layout is still recognized so existing installs keep working. The global `~/.gemini/antigravity/` path is unchanged. (#1090) (#1090) +- +**`devin-desktop` runtime alias for the Windsurf→Devin Desktop rebrand** — the `windsurf` runtime now also answers to `devin-desktop` (CLI `--devin-desktop`), aiding discoverability after Cognition rebranded Windsurf as Devin Desktop. All paths are unchanged — global skills still install to `~/.codeium/windsurf/skills/`. (#1086) (#1086) +- Remove dead `loadConfig` export from `configuration.cts` — superseded by `config-loader.cts` (ADR-857 phase 2e, #885). All live callers already import `loadConfig` from `config-loader.cjs` or the `core.cjs` back-compat re-export; exhaustive grep confirms zero callers importing it from `configuration.cjs`. `configuration.cjs` now provides only the pure normalization and defaults primitives (`normalizeLegacyKeys`, `mergeDefaults`, `migrateOnDisk`, `CONFIG_DEFAULTS`) that `config-loader.cjs` depends on. (#893) (#893) +- audit(#779): correct stale model-catalog IDs verified against live provider sources. The gemini opus default `gemini-3-pro` → `gemini-3.1-pro-preview` (the bare `gemini-3-pro` ID is undefined in gemini-cli source — only `gemini-3-pro-preview`/`gemini-3.1-pro-preview` exist) and the codex sonnet default `gpt-5.3-codex` → `gpt-5.4` (deprecated per OpenAI's Codex models page); the same two IDs are also updated in the `google`/`openai` provider-preset entries. `qwen3-coder-next` was verified valid (callable on Alibaba Model Studio) and left unchanged. Adds a regression guard against the retired IDs and a sourcing/verification note in CONFIGURATION.md. Catalog IDs are internal defaults; users who pinned the old IDs must update their config. (#1047) +- **INVENTORY.md no longer carries `(N shipped)` count scalars** — the hand-maintained absolute counts collided silently on merge (two branches each bumping the same integer to N+1 while the merged tree held N+2), red-flagging CI on the merge commit across all platforms. The manifest's name-set is now the sole registry, anchors are count-free and stable, and a guard test blocks re-adding a count. (#1179) (#1179) +- Edge-probe `precision` probe text now names tie-breaking / rounding-mode (half-up vs half-to-even, ceil/floor/truncate), so a surfaced precision edge cues the most common rounding failure mode. Prose-only; firing rule and the 8-category core unchanged. (#1108) +- Capability manifests now declare runtime compatibility through a validated runtimeCompat contract, and runtime descriptor interpreters now read artifact layout, skills-home, and hook-surface facts directly from runtime Capability descriptors instead of parallel runtime-name allowlists or fallbacks. This preserves existing supported runtime behavior while making future descriptor-backed runtimes additive. (#1157) +- Planning-time research, AI integration, and pattern mapping now participate through Capability declarations and rendered plan:pre hooks, with developer documentation for building GSD capabilities. (#1141) +- **The planner now blocks plans that would self-trip their own verify gate** — when an acceptance criterion negative-greps for a literal (`grep -c 'LIT' file == 0`) and that same literal appears verbatim in an `` body, plan creation now fails at write time instead of letting the executor waste cycles on a comment-text echo at commit time. Unquoted/ambiguous grep targets warn instead of failing; add `` to allowlist a legitimate occurrence. (#1062) (#1062) +- **Namespace router skills now nest their concrete sub-skills at install time (#69).** On runtimes with non-recursive skill loaders (Claude global, Cline, Qwen, Hermes, Augment, Trae, Antigravity) the installer emits the 6 `gsd-ns-*` routers as the only top-level skill bundles and nests the ~61 concrete skills under `/skills//SKILL.md`, cutting the eager skill-listing overhead to ≈6 entries. Concrete skills stay reachable via the router's `Read skills//SKILL.md` routing table. **Breaking:** on those runtimes the concrete skills are no longer invocable by bare name through the Skill tool / top-level listing — route via the namespace router (or the unchanged `/gsd-*` slash command where a commands surface exists). Legacy top-level `gsd-/` skill dirs are removed on upgrade. Recursive/unconfirmed loaders (Cursor, Codex, Copilot, Windsurf, CodeBuddy, OpenCode, Kilo) keep the flat layout. (#883) +- **Graphify now respects surface/profile state, not just `graphify.enabled`** — `gsd-tools graphify` is off unless graphify is installed AND surfaced AND `graphify.enabled` is true (previously only the config key was checked). The gate is now runtime-aware: Codex/Cursor/etc. read their own runtime's surface instead of `~/.claude`. (#1313) (#1313) +- **Isolated-executor recovery now fails safe** — when an isolated (worktree) executor run is rejected (you decline to merge it) or over-reached the requested scope, `/gsd:execute-phase` and `/gsd:quick` no longer default or propose recovery by editing the primary checkout (`main`). The orchestrator halts safely and offers a fresh, narrowly-scoped worktree or inspect/discard; editing the primary checkout requires explicit, clearly-labeled confirmation. (#1292) (#1303) +- Migrate code review, security, and Nyquist verification workflows to ADR-857 capability hooks. (#1147) +- **Intel and loop-hook rendering now honor the single capability `active` state** — `gsd-tools intel` gates through the shared resolver (consistency; intel stays governed by `intel.enabled`), and loop-hook rendering now suppresses a config-disabled capability's hooks via the capability-level `active` gate (fail-closed), not just per-hook `when`. (#1315) (#1315) +- Added no-drift guard tests (`tests/issue-57-runtime-install-no-drift.test.cjs`) that protect the Runtime Install Policy Module boundary (ADR-58) and the explicit Runtime Config Adapter Registry (#60). They fail loudly when supported-runtime metadata is added to an installer call site (`allRuntimes`, the interactive `runtimeMap` menu) without a matching registry adapter entry, or when config-mutation dispatch escapes the registry's declared install surfaces — catching reintroduction of the scattered per-runtime branching those seams removed. (#867) +- Edge-probe now surfaces a zero-classification requirement (non-empty prose, no shape cue matched, no `shapes` override) as a single soft `unclassified — review manually` candidate instead of silently dropping it. Dismissible like any edge; `shapes: []` opt-out stays silent; TAXONOMY unchanged. (#1117) +- **Capability state now reports a tri-state `active`** — `gsd-tools capability state` adds an `active` field per capability (installed && surfaced && config-enabled), alongside the existing `enabled` (installed && surfaced). Internal `isCapabilityActive(capId, cwd)` lets consumers honor the single resolved on/off answer. (#1311) (#1311) +- **`gsd-verifier` no longer marks behavior-dependent must-haves `VERIFIED` on symbol presence alone** — a truth that asserts a state transition or a cancellation/cleanup/ordering invariant is marked `PRESENT_BEHAVIOR_UNVERIFIED` when no test exercises it: excluded from the `verified_truths` score, reported as a `behavior_unverified` count, and routed to human verification, so a clean N/N now certifies behavioral evidence rather than mere symbol presence. (#966) (#1271) +- **`verify plan-structure` warns on cross-task region-scope conflicts (#968)** — when a plan task's file-wide negative grep (`! grep -Eq 'PAT' file` / `grep -c 'PAT' file == 0`) bans a construct a sibling task legitimately requires elsewhere in the same file, plan validation now surfaces a warning pointing to the new region/function-scoped negative-gate idiom (documented in the gsd-planner guidance and the planner-antipatterns reference, with a worked banned-in-X / required-in-Y example). Warn-only: it never errors and never changes `valid`. (#1320) (#1320) + +### Fixed + +- **`gsd-intel-updater` now writes the canonical intel filenames the `gsd-tools intel` CLI actually reads** — the agent was instructed to emit short names (`files.json`, `apis.json`, `deps.json`) and a markdown `arch.md`, but the intel library reads only `file-roles.json`, `api-map.json`, `dependency-graph.json`, and `arch-decisions.json` (JSON). After `/gsd:map-codebase --query refresh` the output was orphaned, so `intel status`/`validate` reported the files missing and `intel query` returned nothing. The agent now emits the canonical long names and structured `arch-decisions.json`. (#1000) (#1037) +- **Installer no longer appends a duplicate managed hook when it is registered via an HTTP route** — a hook re-registered as a `type:"http"` entry (local hook-server routing) carries its identity only in `url`, which the installer's presence check ignored, so a stock command duplicate was appended on every install/update and the hook ran twice per event. The presence check now also inspects `h.url`. (#1004) (#1032) +- **`/gsd-code-review`'s fallow structural pre-pass now actually runs and delivers findings** — it invoked fallow with flags no published fallow version accepts (`--json`, `--profile`, `--stdin-files`), so the pre-pass failed on every run and silently degraded (the structural-findings feature never delivered on any fallow version). It now uses fallow's real CLI (`audit --format json --quiet`, `--changed-since` for phase scope, and `--max-crap` mapped from the `code_quality.fallow.profile` preset: minimal→50, standard→30, strict→15), treats fallow's exit code 1 ("issues found") as a successful run instead of a crash (gating on a valid JSON report, not the exit code), and normalizes fallow's real `audit --format json` schema (`dead_code.*`, `duplication.clone_groups`) into the reviewer's `` contract. The report normalizer — previously dead code parsing a schema fallow never shipped — is wired to the real schema and exercised against real fallow output. (#1012) (#1044) +- **`worktree base-check` now honors a user/global `worktree.baseRef:"head"` (and `CLAUDE_CONFIG_DIR`)** — base-check resolved `baseRef` from the project checkout's `.claude/` only, so a machine-wide `head` set via `/config` (the layer the harness itself honors) was invisible. On any phase/feature lane it returned `shouldDegrade:true` and `execute-phase` silently forced sequential execution, losing the parallel worktree execution the user configured. Resolution now falls back to the user/global `settings.json` (via `getGlobalConfigDir('claude')`, honoring `CLAUDE_CONFIG_DIR`) below the existing project-local and project-shared layers. (#1013) (#1038) +- **Agent SDK/state/commit steps now resolve `gsd-tools` on shim-only installs for every runtime** — source `agents/*.md` (`gsd-planner`, `gsd-executor`, `gsd-verifier`, `gsd-plan-checker`, …) invoked bare `gsd-tools …`, which fails with `command not found` on shim-only installs where the binary is only reachable as `/gsd-core/bin/gsd-tools.cjs` and is not on `PATH`. The agent then silently skipped init/state/validate/commit ceremony. #725 fixed only Codex's conversion layer; the source agents were never migrated, so the bug persisted on Claude Code and every other runtime that consumes the source agents directly. All 12 `gsd-tools`-calling agents now carry the canonical multi-runtime `gsd_run` resolver (the same preamble the workflow launchers use — covering claude/codex/cursor/gemini/copilot/windsurf/augment/trae/qwen/cline/opencode/kilo/hermes/antigravity homes), `gsd-phase-researcher`'s stale claude-only resolver is upgraded to the canonical one, and the launcher-parity + bare-call regression guards are extended to `agents/` so no runtime can silently regress. (#1041) (#1045) +- **`gsd-tools generate-claude-md` no longer clobbers a hand-crafted `CLAUDE.md`, and defaults the Claude-runtime output to `./.claude/CLAUDE.md`** — `/gsd-new-project` wrote a repo-root `CLAUDE.md` full of broad project documentation, overwriting/diluting an existing hand-authored instruction file. Now: (1) an existing instruction file that contains no GSD section markers (a hand-crafted file) is left untouched and the command reports `action: "skipped"` — pass `--force` to overwrite intentionally (the flag was already parsed but ignored); (2) the default output for Claude-family runtimes is `./.claude/CLAUDE.md` (a valid project-scoped memory location) instead of repo-root `./CLAUDE.md`, so generated content does not pollute a repo-root file. The config default (`claude_md_path`), the project config template, and the new-project workflow are aligned to the new location. Codex projects still write `AGENTS.md`. (#1098) (#1118) +- **`state record-session` updates an existing `## Session Continuity` section in place instead of appending a duplicate `## Session` block** — on a freshly bootstrapped project (workstream / gsd2-import / new-project templates all emit `## Session Continuity`), the auto-create path recognised only the normalized `## Session` heading, so it appended a second session block. It now inserts only the missing canonical fields after the `## Session Continuity` heading, preserving the heading and any existing prose, and the snapshot / frontmatter readers recognise that heading. (The originally reported `recorded:false`-yet-mutated symptom was already resolved by #944/#948.) (#1101) (#1113) +- **`roadmap annotate-dependencies` no longer fuses the preceding summary line onto the `Plans:` header** — when the match regex's `(?:^|\n)` anchor consumed a leading newline (mid-string match), the replacement dropped it, producing corrupted output like `**Plans:** 3 plansPlans:`. The replacement now re-emits the leading newline when present. (#1103) (#1111) +- **`/gsd-progress` no longer reports a phase as complete (and routes to the next phase) when its verification ended `human_needed` or `gaps_found`** — routing derived completeness from plan/summary counts only and never consulted the `verification.status` query (the seam built in #651). A new Step 1.7 consults it for the current phase, and the routing table sends `gaps_found` to `/gsd:plan-phase {phase} --gaps` (Route V.gaps) and `human_needed` to `/gsd:verify-work {phase}` (Route V.human) before the generic complete row. `passed`, `missing` (unverified), and `unknown` still route as complete, so unverified phases are not falsely blocked. (#1107) (#1116) +- **`write-profile` now writes `USER-PROFILE.md` to the active runtime's config home instead of always `~/.claude`** — under Codex, `gsd-tools query write-profile` wrote `~/.claude/gsd-core/USER-PROFILE.md` while Codex `discuss-phase` advisor-mode (installed under `~/.codex`) checked the Codex home and never found it, so advisor-mode silently stayed disabled. The default output path is now resolved via the runtime-aware `getGlobalConfigDir` (`GSD_RUNTIME` / `config.runtime` → e.g. `~/.codex` for Codex), matching how the runtime's own workflows resolve it — mirroring `generate-dev-preferences`. Claude is unchanged (`~/.claude`); an explicit `--output` still wins. (#1114) (#1119) +- **`/gsd:review` no longer produces a silent empty Codex review on codex-cli < 0.137** — the `codex exec` invocation passed `--dangerously-bypass-hook-trust` (added in codex 0.137.0) unconditionally and discarded stderr, so on older CLIs codex exited with `unexpected argument` before reading the prompt and the empty output was treated as a completed review. The flag is now capability-probed (`codex exec --help | grep`) and applied via `$CODEX_BYPASS_FLAG` only when supported, codex stderr is captured to a `.err` file instead of `/dev/null`, and an empty Codex output is replaced with a diagnostic so a broken reviewer is surfaced rather than silently skipped. (#1115) (#1122) +- **`sandbox_mode` emission in Codex TOML is now gated on the runtime descriptor's `sandboxTier` axis** — previously `installCodexConfig` emitted `sandbox_mode` unconditionally from a hardcoded policy map regardless of whether the runtime descriptor declared a sandbox tier, making the descriptor field cosmetic. `resolveInstallPlan` now projects `sandboxTier` from the capability registry, and `generateCodexAgentToml` / `installCodexConfig` gate emission on `sandboxTier !== 'none'`. The per-agent mode table `CODEX_AGENT_SANDBOX` remains GSD agent policy (not a runtime-descriptor property). For codex (`sandboxTier === 'codex-agent-sandbox'`) output is byte-identical to before; for all other runtimes (`sandboxTier === 'none'`) `sandbox_mode` is correctly omitted. `resolveInstallPlan` now fails loud (throws `TypeError`) on a missing or invalid `sandboxTier` descriptor axis rather than silently coercing garbage to `'none'`, preventing a corrupt/stale registry from silently dropping sandbox enforcement. Full removal of the per-agent registration-tax map remains tracked under #1138. (#1151) (#1152) +- **Installed runtimes no longer silently disable `verify:post` gates** — in a global skills-runtime install (e.g. Codex at `~/.codex`), the `commands/gsd` source tree is absent, so capability-state resolved an empty skill manifest. The full-profile `*` sentinel then materialized to an empty surfaced set, marking every capability `surfaced=false` → `enabled=false`. The result: `gsd-tools loop render-hooks verify:post` returned `activeHooks: []` even with `security_enforcement` and `nyquist_validation` enabled, so the security and Nyquist gates never fired. Capability-state now falls back to the installed `/skills/gsd-*/SKILL.md` layout when the source tree is unreachable, so `verify:post` again includes `security -> secure-phase` and `nyquist -> validate-phase`. (#1206) (#1206) +- **`gsd install` no longer warns that `settings.local.json` "may be malformed" when the file contains a valid JSON `null`.** `readSettings` now treats a successfully-parsed `null` as empty settings (`{}`) instead of collapsing it into the parse-failure path, so a literal-`null` settings file is preserved silently; genuinely unparseable files still emit the warning. (#1191) (#1233) +- **gsd-tools no longer crashes at load on a fresh install** — the installer omitted `scripts/fix-slash-commands.cjs`, which `command-roster` requires at module load, so every `gsd-tools` command failed with MODULE_NOT_FOUND. The installer now ships it (with a smoke assertion), and `readCmdNames()` tolerates a missing commands directory. (#1240) (#1240) +- **`state begin-phase` / `complete-phase` now advance the frontmatter `status` for pipe-table `STATE.md`, not only inline `Status:` files.** The status update matched the YAML frontmatter `status:` line first and never updated a body `| Status | … |` cell, so the frontmatter `status` froze (e.g. stuck at `planning`); it now transitions correctly (`planning → executing → completed`) regardless of whether the body `Status` is inline or pipe-table. (#1255) (#1256) +- **`state planned-phase` now advances the pipe-table `Status` cell (and frontmatter `status`), and `state begin-phase` now updates the Current Position `| Phase |` / `| Plan |` cells instead of prepending stray inline lines.** Systemic follow-up to #1255: `planned-phase` ran its body-field replacements on the full file content, so the YAML frontmatter `status:` line was matched before the body `| Status | … |` cell and the status never reached `Ready to execute`; and `begin-phase` had pipe-table branches only for `Status`/`Last activity`, so for pipe-table `STATE.md` the `Phase`/`Plan` rows were left stale while a spurious inline `Phase: N — EXECUTING` line was prepended. Both handlers now strip frontmatter before body-field replacement and update pipe-table cells in place, matching the inline-format behaviour. (#1257) (#1260) +- +**Parallel worktree execution now has executor-authored cleanup metadata** — executor agents capture their worktree path, branch, and expected base before task commits and return a parseable metadata block for execute-phase to prefer over runtime harness metadata. (#1297) (#1349) +- +**UAT resume now accepts paused checkpoints** — `uat render-checkpoint` treats a non-structured paused `Current Test` placeholder as a resume signal and derives the checkpoint from the first pending UAT test instead of failing as malformed. (#1300) (#1350) +- +**`phase complete` now preserves prose-block STATE phase names** — template-shaped `Current Position` prose now advances with the next phase name, avoids missing-field warnings, and keeps `Last activity:` on the template em-dash delimiter. (#1316) (#1351) +- +**Claude skill installs now avoid rejected `xhigh` effort frontmatter** — heavyweight GSD skills now ship with portable `effort: max`, and the Claude skill converter normalizes any remaining `xhigh` source effort before writing `SKILL.md`. (#1319) (#1352) +- +**Glued letter-prefix phase directories now resolve correctly** -- phase lookup now recognizes tokens like `P0.3` and `M1-2` from directory names, so phase commands can find their plans instead of reporting none found. (#1324) (#1353) +- +**Update backups now ignore preserved shared skills and hooks** -- `/gsd-update` custom-file detection now mirrors installer cleanup scope for shared runtime roots, so non-`gsd-*` skills and hooks are not copied into backup folders unnecessarily. (#1325) (#1354) +- +**Codex skills no longer show up twice in autocomplete** — GSD's Codex install wrote an `agents/openai.yaml` sidecar under every managed `gsd-*` skill directory, and recent Codex builds index both `SKILL.md` and the sidecar, so each skill appeared twice (once as `gsd-foo`, once as a humanized `foo` display name). The installer now stops emitting these sidecars and removes stale ones left by prior installs (pruning the empty `agents/` directory), while preserving user-owned skill directories. Codex discovers GSD skills via `SKILL.md` alone. (#1326) (#1360) +- +**The worktree path guard no longer blocks ordinary writes in non-GSD git worktrees** — the `gsd-worktree-path-guard` PreToolUse hook fired for every `Write`/`Edit` in any linked git worktree, so Claude Code plan-mode writing its plan to `~/.claude/plans/.md` from a manually-created worktree was hard-blocked. The hook now only enforces inside a GSD isolated-executor worktree (branch `worktree-agent-*`) and fails open when a target resolves to no git repository, while still blocking writes that escape to a different git root (the #260 protection) or into a repository's `.git` internals. (#1342) (#1361) +- +**`check.decision-coverage-plan` no longer reports a false pass when a `D-NN` decision header has text before the colon** — `parseDecisions` previously dropped any `- **D-NN …:**` bullet whose header contained a `(parenthetical)`, em-dash, or other prose before the `:**`, silently narrowing the trackable set so the blocking coverage gate green-lit a phase whose dropped decisions were never checked. The parser now tolerates a freeform run before the colon (preserving `[bracket]` tags) and warns on any `D-NN` bullet it still cannot parse instead of dropping it. (#1343) (#1358) +- +**Codex `hooks.json` is now always written in the nested `{ "hooks": { … } }` shape Codex expects** — the writer previously echoed back whatever shape it read, so an empty, absent, or legacy top-level `hooks.json` (`{ "SessionStart": [...] }`) stayed in the legacy shape that current Codex can reject or warn on. Every write now canonicalizes to the nested form, lifting any legacy top-level event entries (including mixed nested+top-level files) under `hooks` without dropping user-owned entries. Managed-hook dedup/removal is unchanged. (#1348) (#1363) +- +**`gsd install --cursor` no longer leaves bare `~/.claude` paths in installed artifacts** — the Cursor install branch only rewrote the trailing-slash `.claude` forms, so bare `~/.claude` / `$HOME/.claude` references survived into installed skills and workflows (e.g. `gsd-surface`, `gsd-graphify`, `plan-phase`, `autonomous`) and tripped the post-install "unreplaced .claude path reference(s)" warning, pointing at a directory that doesn't exist on a Cursor-only install. The Cursor branch now rewrites bare forms too (mirroring the Trae/Augment/Copilot branches), using a `(?![\w-])` lookahead so `.claude-plugin` / `.claudeignore` are not corrupted. (#1356) (#1368) +- **`/gsd-new-project` and `/gsd-new-milestone` now self-heal when the research synthesizer returns `SUMMARY.md` inline instead of writing it** — under some context loads the `gsd-research-synthesizer` agent hits an LLM false-refusal (fabricating a non-existent write restriction) and returns the SUMMARY.md content in its reply rather than writing `.planning/research/SUMMARY.md`. Prompt hardening (#240) reduced but did not eliminate this. Both workflows now verify the file exists after the synthesizer returns and, if it is missing but content came back inline, the orchestrator persists it before spawning `gsd-roadmapper` — so the roadmapper never fails with "SUMMARY.md not found". (#222) (#1042) +- Codex agent TOML generation no longer pins `model_reasoning_effort` when the agent is intentionally inheriting the active Codex chat model. GSD still emits both `model` and `model_reasoning_effort` when a per-agent model override or `runtime: "codex"` resolver pins the model, avoiding the confusing partial state where the model followed Codex UI selection while effort followed GSD catalog defaults. (#838) (#842) +- **profile-pipeline temp output now lands under the reaped GSD temp root.** `cmdExtractMessages` and `cmdProfileSample` previously created their output directories directly in `os.tmpdir()` root (`gsd-pipeline-*` / `gsd-profile-*`), which `reapStaleTempFiles` never scans (it only scans `GSD_TEMP_DIR = os.tmpdir()/gsd`). The directories accumulated forever. Both sites now call `ensureGsdTempDir()` and create under `GSD_TEMP_DIR`. Also adds missing `after`/`afterEach` teardown to four test fixtures that leaked `gsd-*` temp dirs on every `npm test` run. (#866) (#879) +- `getMilestonePhaseFilter` now excludes phase headings inside fenced code blocks (``` ``` ``` or `~~~`) — consistent with the fence-aware behavior of `extractCurrentMilestone`. Previously, a `### Phase N:` line inside a fenced block was wrongly counted as a real phase. (#875) (#880) +- **`gsd_run` launcher shim now probes all non-Claude runtime homes before failing.** The shim's last-resort detection previously stopped at `$HOME/.claude`, causing a false-positive fatal error on every non-Claude runtime (Hermes, Cursor, Codex, Copilot, Windsurf, Augment, Trae, Qwen, CodeBuddy, Cline, Grok, Antigravity, OpenCode, Kilo) when `RUNTIME_DIR` was unset and `gsd-tools` was not on `PATH`. The snippet now probes each runtime's config directory (respecting `HERMES_HOME`, `CURSOR_CONFIG_DIR`, `CODEX_HOME`, etc. with sensible `$HOME`-relative defaults) before emitting the install error. (#903) +- **`validate health` and `validate consistency` no longer emit false-positive W007 warnings for projects using checklist-style ROADMAP.md phases.** `buildRoadmapPhaseVariants()` in `src/validate.cts` previously used only a heading-style regex (`## Phase N: name`), silently ignoring the supported checklist format (`- [x] **Phase N: name**`). This caused every on-disk phase directory to trigger W007 ("exists on disk but not in ROADMAP.md") when the project's ROADMAP used checklist-only notation. The fix adds a second regex pass mirroring the existing `buildNotStartedPhaseVariants()` approach. Additionally, `cmdValidateConsistency()` in `src/verify.cts` had a duplicate inline heading-only regex with the same gap — refactored to delegate to `buildRoadmapPhaseVariants()` (DRY). (#892) (#893) +- **`init execute-phase` and `cmdCommit` now produce correct `branch_name` when `project_code` is set** — the `{phase}` substitution in `phase_branch_template` now calls `normalizePhaseName()`, stripping the project-code prefix and zero-padding the number, so the generated branch is e.g. `gsd/phase-01-foundation` instead of `gsd/phase-CK-01-foundation`. Both the execute-phase output path (`src/init.cts`) and the pre-execution commit path (`src/commands.cts`) are fixed. (#904) (#904) +- **`syncStateFrontmatter` no longer strips `current_phase`, `current_phase_name`, `current_plan`, and `progress` from `STATE.md`** — when body annotations are absent (e.g. after an agent rewrites the body), the existing frontmatter values for those scalars are now preserved, mirroring the fallback already applied in `cmdStateJson`. (#905) (#905) +- **Top-level Claude Code `/gsd-plan-phase` now always spawns the researcher/planner/plan-checker agents instead of collapsing them inline** — a `` block after `` makes the Agent-availability requirement explicit and documents that the workflow fails-closed (stops with a clear log message) in genuinely Agent-less contexts; seven "ORCHESTRATOR RULE — CODEX RUNTIME" labels are renamed to "ALL RUNTIMES" so the guard applies universally; `execute-phase.md` scopes its existing "Other runtimes" inline-fallback prose to non-Claude contexts, preserving the #853 backgrounded-agent behaviour. (#913) (#913) +- **`/gsd-plan-phase`, `/gsd-execute-phase`, `/gsd-autonomous` no longer carry `context: fork`** — these are spawning orchestrators; a forked subagent context has no `Agent` tool, preventing them from spawning the subagents they require. `effort: xhigh` is preserved. Fixes `/gsd:autonomous` halting with "running as a forked subagent" on 1.4.1 (#921). Also replaces the introspection-based Agent-availability check in `plan-phase`'s `` block with an attempt-based gate: the workflow now always attempts the `Agent()` call and only stops if a real tool-unavailable error is returned, eliminating false-negative aborts in top-level sessions (#922). (#921) +- **Claude global install reverted to flat skill layout so concrete skills are discoverable.** PR #883 introduced nested skill layout for Claude (`~/.claude/skills/gsd-ns-/skills//SKILL.md`), but Claude Code's skill discovery scans only one level under `~/.claude/skills/` — nested concrete skills were never listed in the Skill-tool available-skills list and direct `Skill(skill="gsd-plan-phase")` calls stopped working. This fix reverts Claude to the flat layout (`~/.claude/skills/gsd-/SKILL.md`) so all ~61 concrete skills are top-level and immediately discoverable. The 6 other runtimes that confirmed non-recursive scanning (cline, qwen, hermes, augment, trae, antigravity) retain their nested layout. (#924) (#924) +- **`gsd-context-monitor.js` now echoes the actual invoking hook event name** — instead of hardcoding `hookEventName: "PostToolUse"` (or `"AfterTool"` for Gemini), the hook reads `data.hook_event_name` from the stdin payload and falls back to the runtime heuristic only when the field is absent or blank; this fixes Claude Code rejecting hook output with `"expected Stop but got PostToolUse"` when the monitor is invoked by the Stop, SubagentStop, or PreCompact hooks registered in PR #821. (#925) (#926) +- Fix `--reapply` verifier false-positives on post-#604-rename installs caused by two gaps in pristine-baseline handling: + +**Gap 1** (`verify-reapply-patches.cjs`): when `backup-meta.json` records a `pristine_hash` for a file but `gsd-pristine/` has no corresponding snapshot on disk, the verifier fell to over-broad mode (every upstream-changed line treated as a user-added requirement) and produced `FAIL_USER_LINES_MISSING` false positives. Fix: return advisory `OK_NO_BASELINE` reason (non-blocking, exit 0) when a recorded hash is present but the pristine file is absent — the verifier cannot reason correctly without a baseline and must not block. + +**Gap 2** (new migration `004-prune-stale-pristine-get-shit-done`): migration 003 removed legacy `get-shit-done/` runtime files but left `gsd-pristine/get-shit-done/` orphan snapshots in place. Those stale snapshots referenced `get-shit-done/...` key paths that no longer match the active `gsd-core/...` layout, contributing to `FAIL_INSTALLED_MISSING` false reports. Fix: add a new migration (not editing 003, to preserve its checksum) that removes all files under `gsd-pristine/get-shit-done/`. (#934) (#935) +- **`/gsd-update` changelog preview no longer silently fails** — the installer now copies `scripts/changeset/` and `scripts/lib/` into the runtime config dir so `$GSD_DIR/scripts/changeset/cli.cjs` resolves at runtime; `update.md` was updated to use the correct installed path and to surface an explicit error if the CLI is missing rather than swallowing it. (#935) +- **`plan-review-convergence` now runs `gsd-plan-phase` inline instead of inside `Agent()`** — both sites that previously wrapped `gsd-plan-phase` in `Agent()` (initial planning + replan loop) have been changed to bare `Skill()` calls at depth 0. On Claude Code, a depth-1 Agent has no Agent tool, so a wrapped `plan-phase` could never spawn `gsd-planner` or `gsd-plan-checker` — the replan loop silently failed to produce a revised plan whenever HIGH concerns were found. Running plan-phase inline from the depth-0 orchestrator (which retains the Agent tool) restores the full planner→checker sub-agent chain. A new structural guard test (`bug-936-no-nested-spawner-wrap.test.cjs`) statically scans all workflow files and fails if any workflow wraps a spawner orchestrator in `Agent()` without a `RUNTIME != claude` carve-out, preventing regression. (#936) (#939) +- **`--json-errors` now emits a structured error even when a handler throws unexpectedly** — an unexpected (non-`ExitError`) throw fell through to a raw stack trace on stderr, breaking SDK structured-error parsing. (#965) (#987) +- **`verify key-links` docs now correctly state `from:`/`to:` are relative file paths** — the reference implied component/endpoint values the verifier never supported, so locator-style links failed with a misleading 'Source file not found' and the author's `pattern:` was never evaluated. (#967) (#990) +- **Fixed a test-infrastructure regression (#996) where bug-969 hardening tests deleted the shared `gsd-core/bin/lib/core.cjs` during concurrent runs and the build tsbuildinfo lived inside the copied install tree, intermittently failing CI with MODULE_NOT_FOUND/ENOENT.** The destructive tests now run hermetically against a temp project, and the tsbuildinfo moved out of `gsd-core/bin/`. (#969) (#1002) +- **`gsd-planner` now ships the `Edit` tool, so it can no longer destroy `ROADMAP.md` via a whole-file `Write`** — the planner had `Write` but not `Edit` (the #571/#581 writer-agent gap), so an in-place ROADMAP edit fell back to a full overwrite that truncated committed milestone history. The `update_roadmap` step now directs scoped `Edit` calls and explicitly forbids passing the full file to `Write`. (#973) (#989) +- **`graphify query --budget` with no value now errors instead of silently ignoring the budget** — a trailing `--budget` parsed as `NaN` and was treated as 'no budget', so the query ran unbounded with no warning. (#974) (#986) +- **The installer now resolves a stable fnm node path instead of the ephemeral multishell shim on Windows** — managed `.js` hooks were pinned to `fnm_multishells//node.exe`, a per-shell-session path fnm later deletes, breaking every managed hook until reinstall. (#977) (#992) +- **`gsd-tools milestone complete --force` now actually overrides the unstarted-phase guard** — the dispatcher never parsed `--force`, so the guard's own documented escape hatch was inert. (#978) (#982) +- +**Trae and Windsurf installs no longer leak unreplaced `~/.claude` / `$HOME/.claude` paths** — both converters only rewrote trailing-slash `.claude/` forms, so bare home-path references survived conversion and pointed users at the wrong config dir; bare forms are now rewritten (Codex/Cline #570/#782 parity) and `CLAUDE_CONFIG_DIR` maps to the runtime's own var, with `.claude-plugin` preserved. (#983) (#995) +- **Claude Code plugin installs no longer fail with empty `@~/.claude/gsd-core/...` includes** — agents, commands, and templates `@`-include the canonical `~/.claude/gsd-core/` path, but a marketplace plugin install (`claude plugin install`) never creates that directory, so every include resolved to nothing and agents (e.g. the executor) failed. A new `SessionStart` hook (`gsd-ensure-canonical-path.js`) symlinks the canonical path's immutable subdirs (`bin`, `contexts`, `references`, `templates`, `workflows`) to the plugin's bundled tree. It is a no-op in classic `bin/install.js` installs, preserves user-generated files (e.g. `USER-PROFILE.md`), prunes stale links so it self-heals after `claude plugin update`, and uses Windows junctions. (#1207) (#1207) +- **`/gsd-code-review`, `/gsd-code-review --fix`, and `/gsd-eval-review` now inject configured `agent_skills` into their subagents** — these review-family workflows previously spawned their reviewer/fixer/auditor agents (including the `--auto` re-review/re-fix loops) without the project-configured skill and rule context, so any `agent_skills` set for `gsd-code-reviewer`, `gsd-code-fixer`, or `gsd-eval-auditor` were silently ignored. They now query and inject those skills like the ~20 sibling workflows. (#1005) +- **`phase complete` no longer rewrites an existing roadmap completion date** — repeat runs on an already-`Complete` phase preserve the recorded `YYYY-MM-DD` date (4- and 5-column layouts); empty/`-`/non-date cells are still stamped with the current date. (#1177) +- **Legacy ROADMAP projects no longer get deprecation-warning spam** — the free-form ROADMAP warning fired on every command regardless of phase_id_convention; it now only warns when the milestone-prefixed convention is explicitly set and unmet. (#1218) (#1218) +- **Forking workflows target wrong base branch on `master` repos when `origin/HEAD` is unset** — `execute-phase`, `quick`, `ship`, `complete-milestone`, and `pr-branch` detection bash fell through to a hardcoded `main` fallback whenever `origin/HEAD` was absent (common in `git init` + `remote add` + `fetch` without `set-head`, CI checkouts, and worktrees), causing GSD to fork phase branches off a non-existent `main` on `master` repos. Replaced with a single `gsd_run query git.base-branch` resolver that walks the full precedence ladder: config override → `origin/HEAD` symref → `git remote show origin` → local branch presence → `"main"`. (#1198) (#1198) +- **`query user-story.validate` now works** — `mvp-phase` and `verify-work` workflows both invoked this command to validate "As a / I want to / so that" user stories, but no CJS handler existed; every call errored with "Unknown command: user-story". (#1193) (#1193) +- **Context meter no longer sticks at 100%** — the statusline reserved-buffer math was inverted, pinning usage at 100% whenever CLAUDE_CODE_AUTO_COMPACT_WINDOW equalled the total window. (#1194) (#1211) +- **Roadmapper honors phase_id_convention** — new-project roadmaps now use milestone-prefixed phase IDs when phase_id_convention is set, instead of ignoring the default. (#1205) (#1215) +- +**`phase complete` no longer emits false warnings from historical verification metadata or deferred requirement IDs** — two distinct false-positive warning bugs: (A) the verification-status check used a full-text regex that matched `previous_status: gaps_found` in the file body, triggering an "unresolved gaps" warning even when the current frontmatter `status: passed`; the check now reads only the frontmatter `status` key via `extractFrontmatter`. (B) requirement IDs under explicitly deferred/backlog/future/v2 section headings in `REQUIREMENTS.md` were flagged as missing from the Traceability table; the check now skips any section whose heading matches those terms. (#1197) (#1197) +- **verify key-links no longer fails on planned future files** — a from: link whose file is declared in a current/upcoming wave plan’s files_modified is now reported pending instead of a hard missing-file failure. (#1202) (#1219) +- **`state patch` and `state record-session` no longer corrupt STATE.md** — a no-match patch no longer rewrites the file (was resetting `milestone_name` and resurrecting a stale `stopped_at`), and `record-session` now persists `--stopped-at`/`--resume-file` even when the body lacks the exact labels. (#952) +- **`/gsd-update` no longer flags `managed-hooks-registry.cjs` as a custom file** — the shipped hook is now recorded in the file manifest, eliminating a perpetual false-positive custom-file warning. (#953) +- **`gsd-tools` no longer throws `EAGAIN` or truncates output under heavy load** — the CLI's stdout/stderr writes now retry the transient `EAGAIN`/`EINTR` errnos and handle short writes when the output stream is a full non-blocking pipe (e.g. the parallel test runner), instead of throwing or silently dropping bytes. (#1009) +- **Quick worktree execution now accepts parent-or-plan bases for pre-dispatch plan commits** — quick mode records the parent and plan commit around the pre-dispatch PLAN.md commit, lets the worktree guard accept either approved base, materializes the plan from git objects when a runtime forks from the parent, and teaches cleanup to validate the same allowed-base set. (#1265) (#1347) +- **`phase add` no longer reuses an existing phase number when that phase exists only as a roadmap bullet** — the next-number scan now counts phases listed only as `- [ ] **Phase N: ...**` bullets (all checkbox variants, with or without a title), in addition to `### Phase N:` section headers and on-disk phase directories, so a bullet-only phase is no longer shadowed and `phase add` appends after the highest used number. (#1249) +- Preserve curated STATE.md progress frontmatter when `state patch` updates non-progress fields, while still allowing progress-related fields to resync from disk-derived project state. (#1345) +- **The installer no longer re-adds a duplicate managed hook when the user registered it in `command`+`args` (wrapped) form** — the presence checks only inspected `h.command`, so an args-form wrapper (a common Windows windowless-launcher mitigation) was invisible and a stock entry was appended on every install/update, running the hook twice. (#976) (#994) +- `cmdSkillManifest` now discovers concrete skills nested under `gsd-ns-*` routers (`/gsd-ns-/skills//SKILL.md`), so `gsd-health` and `gsd-settings` report the correct count on nested-layout runtimes (cline, qwen, hermes, augment, trae, antigravity). The scan is scoped to `gsd-ns-*` router dirs only — unrelated user dirs that happen to have a `skills/` subdirectory are not traversed. Dual-routed concretes (same skill installed under two routers) are deduped by name within each root. (#929) (#929) +- **state record-session no longer pins a CPU core forever** — acquireStateLock busy-spun at 100% CPU when a recoverable errno (e.g. ENOENT from a removed worktree) persisted, because that retry path skipped the backoff sleep and the 30s time budget. Every retry path is now bounded and backed off. (#1236) (#1236) +- **`/gsd-manager` and `/gsd-autonomous --interactive` no longer silently skip worktree isolation and independent verification on Claude Code.** They dispatched plan/execute as background agents, but a backgrounded Claude Code agent has no Agent/Task tool and cannot spawn the nested executors, plan-checker, or verifier — so isolation and verification silently never ran. Both workflows now resolve the runtime and run plan/execute inline on Claude Code (background dispatch is kept on runtimes that support nested subagents). (#863) +- **Researcher agents can now invoke Perplexity** — `gsd-phase-researcher` and `gsd-project-researcher` referenced `mcp__perplexity__*` in their provider dispatch tables but never granted it in their `tools:` allowlist, so Perplexity web research silently fell through to the next provider. The grant is now generated from the researcher profiles, with a parity guard that fails if a future dispatch-table provider is added without its tool grant. (#1284) (#1288) +- Init phase lookups now resolve active phases whose canonical details live in a flat Phase Details block outside the current milestone summary, restoring requirement coverage for plan/execute/phase-op flows. (#1344) +- **Installer no longer leaks `gsd-cmd-rewrites-*` temp directories.** Each install that emitted slash commands left one `fs.mkdtempSync` directory under the system temp root; on `tmpfs` `/tmp` hosts these accumulated and consumed RAM-backed storage. `installRuntimeArtifacts()` now removes the temp copy in a `finally` once command files are copied. (#862) +- `validate agents` (and `validate health`) now cross-reference the install manifest to detect manifest-backed Codex agent pair drift: when a generated `agents/gsd-*.md` / `agents/gsd-*.toml` pair has one side missing on disk, the agent is reported as incomplete and `agents_found` is `false` (previously a false-healthy `agents_found: true, missing: []`). `validate health` names the incomplete agents and recommends re-running the installer. The check no-ops when no manifest is present. (#1058) (#1079) +- **The `map-codebase` and `docs-update` workflows no longer collect background sub-agent results with the deprecated Claude Code `TaskOutput` tool** — they keep `run_in_background=true` on the spawn and `Read` each agent's `outputFile` (from the `async_launched` result) once it reports completion, removing the `TaskOutput(block=true)` main-session hang surface (anthropics/claude-code#20236). Completion-marker contracts and on-disk verification are unchanged, and the non-Claude runtime fallbacks are preserved. (#1362) +- **`model_policy` is now honored on the default `claude` runtime** — including the `anthropic-fable` Claude Fable 5 preset. Policy-resolved model IDs map to Claude Code agent aliases (e.g. `claude-fable-5` → `fable`), and IDs without a Claude alias warn and fall back to the configured tier. Forward-port of #1133 (originally shipped on the 1.4.5 hotfix line). (#1133) (#1133) +- **`/gsd-plan-review-convergence` now blocks on actionable review findings outside PLAN.md (#724).** The convergence summary contract includes current_actionable alongside current_high, and reviews-mode planning/checking requires actionable MEDIUM/LOW feedback to be incorporated or explicitly deferred in executable PLAN.md content. (#728) +- **Config docs/prompts now match the consumers** — `workflow.subagent_timeout` is documented in milliseconds (default 300000), not "seconds (default 600)" (a user who entered 600 got a 600 ms timeout); `review.models.` is documented as a bare model id injected into `--model`/`-m`, not a shell command; and `workflow.test_command` / `workflow.build_command` (consumed by verify-phase, execute-phase, audit-fix, and the post-merge gate) are now accepted by `config set` and documented. (#1296) (#1299) +- **`changeset new --pr 0` now accepted at creation** — the required-field guard treated the integer 0 as a missing `--pr` flag, so the documented `pr: 0` placeholder could not be authored via the CLI. (#1231) (#1231) +- **`$gsd-quick` Codex adapter no longer assumes typed `spawn_agent(agent_type=...)`** — documents that typed planner/executor spawning needs the agent_type-capable Codex schema and provides a clearly-labeled generic-subagent fallback when only `multi_agent_v1` is exposed. (#958) +- **`state update` and `roadmap update-plan-progress` now handle current Markdown artifact shapes** — state field read/replace works on table-format `STATE.md` (`| Status | … |`), and `roadmap update-plan-progress` inserts missing per-plan checklist rows (filling partial gaps), tolerates `Plans:`/`**Plans:**`/`**Plans**:`, and scopes changes to the active milestone. (#1172) +- `state planned-phase` now advances the Status field when the prior phase left a `Complete ✓` (checkmark) or bare `Complete` terminal status. Previously such a status matched no known template default, so the transition was silently skipped and the state machine stayed stuck on the prior phase. Caveat-bearing statuses (e.g. `Complete but needs manual QA`) remain preserved. (#1070) (#1078) +- **`state.*` writes no longer silently revert the STATE.md frontmatter `status`/`stopped_at`** — an incidental write (e.g. `state record-session`) that doesn't change the body's `Status:`/`Stopped at:` source field now preserves the existing frontmatter value instead of re-deriving it from possibly-stale body text. Legitimate transitions (e.g. `begin-phase`/`complete-phase`, which do update the body Status) still re-derive normally, so a verified-complete phase can no longer be flipped back to `verifying` by an unrelated write. (#1252) +- **`audit-open` no longer false-flags completed quick tasks** — quick-task SUMMARYs now carry `status: complete` in frontmatter by construction, so the milestone-close auditor stops reporting finished quick tasks as `[unknown]`. (#951) +- **Workspace (local) Antigravity and Copilot skill installs no longer point at the global config home** — a local install rewrote `~/.claude/` references in `SKILL.md` bodies to the global `~/.gemini/antigravity/` / `~/.copilot/` paths instead of the workspace-relative `.agent/` / `.github/`, because the skills layout wrapper passed the runtime name into the converter's `isGlobal` parameter slot. (#1092) (#1092) +- Fix the workflow gsd_run launcher being unreachable in later bash blocks on runtimes that run each fenced block in a fresh shell (e.g. Claude Code): ship a standalone gsd-core/bin/gsd_run executable and have the per-file preamble persist the launcher's bin dir onto PATH via CLAUDE_ENV_FILE, with the inline function definition kept as the fallback for all other runtimes. (#1084) +- **`/gsd:phase insert` and `/gsd:phase --edit` no longer dead-end recording Roadmap Evolution** — `query state.add-roadmap-evolution` was rejected as "SDK-only" with an error that pointed back at the very command that just failed, and no CJS handler existed after the SDK retirement. The handler is now implemented in CJS, so the insert/edit phase workflows append the `### Roadmap Evolution` entry under `## Accumulated Context` (creating the subsection if missing, deduping identical entries) as documented. (#1148) (#1148) +- Corrected the installer `--help` profile skill counts: `core` now shows 8 (was 7) and `standard` shows 14 (was 13), both derived from `PROFILES` so they can't drift again; the `full` line drops the stale hardcoded `66` for `all skills`. (#834) (#847) +- **Codex-installed GSD skills and agents no longer rely on a bare `gsd-tools` executable** — generated Codex surfaces now call the bundled shim, and workflow launchers can resolve the Codex shim-only install path. (#731) +- +**Wire the discuss loop step for capability hooks** — capabilities can now register `discuss:pre`/`discuss:post` hooks (e.g. discuss-time context recall and CONTEXT capture); previously `discuss` was contract-declared but structurally unwireable. Also collapses the host-loop file set to a single source of truth and adds an authoring-time guard rejecting hooks at unwired extension points. (#1199) (#1199) +- **`/gsd-autonomous --converge` now routes phase planning through plan-review convergence** instead of silently ignoring the flag. (#711) (#729) +- Hermes skills now install at skills/gsd/gsd-/SKILL.md with name gsd-, restoring canonical /gsd- dispatch that was broken by the bare-stem prefix introduced in #3664. (#955) + ## [1.4.5] - 2026-06-12 ### Fixed