Merge pull request #1673 from open-gsd/chore/backmerge-main-to-next-329233fc

chore: back-merge main → next (329233fc)
This commit is contained in:
Tom Boucher
2026-06-24 19:10:57 -04:00
committed by GitHub
120 changed files with 190 additions and 521 deletions

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1367
---
**Project-local Claude Code install now produces `/gsd-<cmd>` (hyphen) slash commands** — the installer was writing command files to `.claude/commands/gsd/<cmd>.md` (subdirectory with bare names), causing Claude Code to namespace them as `/gsd:<cmd>` (colon form). The fix writes flat `gsd-<cmd>.md` files at `.claude/commands/` level so Claude Code registers `/gsd-<cmd>` (hyphen form), matching hooks, statusline, and all cross-command references. Legacy `commands/gsd/` directories from prior installs are cleaned up on reinstall and uninstall, with `dev-preferences.md` preserved. (#1367)

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1369
---
**`execute-phase` now re-checks the worktree fork base at the start of every wave and resets the wave manifest between waves (#1369)** — two compounding issues caused wave N+1 worktrees to be created from the stale pre-wave-N commit. First, the `worktree.base-check` auto-degrade only ran once at initialize time; after Wave N merged and tracking commits advanced orchestrator HEAD past `origin/HEAD`, Wave N+1 worktrees were still forked from `origin/HEAD` (Claude Code's "fresh" base), causing both agents to immediately halt with `FATAL: worktree base mismatch` from the `worktree_branch_check` guard. Second, `WAVE_WORKTREE_MANIFEST` was never unset between waves, so wave N+1 would reuse the consumed wave-N manifest file, causing the step 5.5 manifest guard (#3384) to block on subsequent waves. Two safeguards fix this: step 0.5 in the `execute_waves` "For each wave" loop re-runs `worktree.base-check` before every wave's dispatch (when divergence is detected, `USE_WORKTREES` is overridden to `false` for that wave); step 7c between waves unsets `WAVE_WORKTREE_MANIFEST` so wave N+1 creates a fresh per-wave manifest, and re-asserts `worktree.baseRef:"head"` (idempotent) so the Claude Code harness re-reads the live HEAD on the next dispatch. The permanent fix remains setting `worktree.baseRef:"head"` in `.claude/settings.local.json` (see #683).

View File

@@ -1,5 +0,0 @@
---
type: Added
pr: 1452
---
**`workflow.context_guard_mode` config key** — proactive context-exhaustion guard for `execute-phase`. Before each wave, the orchestrator self-assesses context pressure using the degradation signals defined in `context-budget.md`. Values: `warn` (default — emit warning and recommend `/gsd:pause-work` when POOR tier detected), `auto` (automatically invoke `/gsd:pause-work` before next wave), `off` (disable). Set via `gsd config-set workflow.context_guard_mode auto` for fully autonomous checkpoint behaviour. (#1452)

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1550
---
**Workflow temp files now randomize correctly on BSD/macOS** — several workflows called `mktemp` with templates where `XXXXXX` was followed by a `.json`/`.md` suffix (e.g. `gsd-worktree-wave-XXXXXX.json`, `gsd-pr-body.XXXXXX.md`). BSD/macOS `mktemp` only substitutes `XXXXXX` when it is the final path component, so those templates returned a literal, non-randomized path, letting concurrent workflow runs collide on the same temp manifest/body file (one run overwriting or consuming another's). The fix creates a suffixless temp then renames to add the extension — portable across BSD + GNU. Affected: `execute-phase`, `quick`, `spec-phase`, `ship`, `profile-user`. (#1520)

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1532
---
**Core-path file locks now verify the holder process is alive before stealing a stale lock (#1532)** — the STATE.md write lock (`acquireStateLock`) and the `.planning/` workspace lock (`withPlanningLock`) previously stole locks on a bare `mtime` timer with no liveness check, so a live-but-slow holder (e.g. a deep `.planning/` scan on slow NFS) could have its lock stolen mid-write, corrupting STATE.md or losing an update. Both locks now gate stealing on `process.kill(pid,0)` liveness with a deadman ceiling above the wait budget (pid-reuse backstop), `withPlanningLock` no longer force-steals a live holder on timeout (and can no longer leak an uncaught `EEXIST`), `writeStateMd` computes its disk scan inside the lock, and `acquireStateLock` no longer leaks a file descriptor or strands an empty lock on a recoverable write error. The steal itself is now race-safe: a lock is never stolen while its body is still being written (the create→pid-write window), and stealing uses an atomic rename with an identity re-confirm so two waiters can no longer both reclaim the same lock and end up holding it concurrently. The uncontended path is unchanged.

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1621
---
**`normalizeNodePath` now maps pruned mise node paths to the stable shim (#1619)** — `resolveNodeRunner()` bakes `process.execPath` into managed `.js` hook commands. Node realpaths execPath, so under mise it resolves to `<data>/installs/node/<ver>/bin/node` — a concrete version mise prunes on `mise up`, after which every managed hook fails to spawn (`No such file or directory` on every SessionStart and tool event), the same ephemeral-path failure #977 fixed for fnm and #3181 for Homebrew. `normalizeNodePath` now rewrites a mise versioned install path to the stable sibling shim `<data>/shims/node` (`.exe` preserved on Windows) when that shim exists, deriving `<data>` from execPath so a custom `MISE_DATA_DIR` works, and falling back to the raw execPath unchanged otherwise. (#1619)

View File

@@ -1,10 +0,0 @@
---
type: Fixed
pr: 1483
---
fix(#1472): validate health is now workstream-aware — PROJECT.md and config.json are resolved from .planning/ root, while ROADMAP.md, STATE.md, and phases/ follow the workstream-scoped path; previously both sets were routed through planningDir() causing false E002/E003/E004/W003 when GSD_WORKSTREAM is set.
fix(#1454): validate health W017 no longer suggests removing the active session's worktree — stale-worktree findings are now skipped when the worktree path matches or is an ancestor of process.cwd().
<!-- docs-exempt: internal verify.cts fix — no public user-facing API or CLI change; behavior correction for workstream-scoped health validation -->

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1656
---
**`frontmatter set` / `frontmatter merge` no longer destroy `must_haves` object-lists** — changing one frontmatter field (e.g. `wave`) silently dropped every `provides:` value and collapsed `must_haves.artifacts`/`.prohibitions` from a structured `[{path, provides}]` list into a malformed inline array, because the whole frontmatter was round-tripped through a lossy parse→serialize path that flattens object-list items to scalar strings. The write now preserves the original raw text for any structurally-unchanged top-level key and regenerates only the field that actually changed, so unrelated `must_haves` blocks survive verbatim. (#1572)

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1537
---
**Non-Claude runtime installs now resolve their own runtime and never attempt Claude-only worktree isolation** — on any non-Claude install (Cursor, Gemini, Qwen, etc.) a runtime-neutral `.planning/config.json` previously resolved `runtime=claude` and enabled git worktree isolation, which only Claude Code's `isolation="worktree"` can honor — risking main-checkout edits while the workflow believed agents were isolated. Every non-Claude install now resolves its own runtime identity, defaults `workflow.use_worktrees` to `false`, fails closed if worktrees are forced on, and runs plan/execute inline in the manager/autonomous flows since only Codex can background-nest the pipeline's subagents. (#1521)

View File

@@ -1,5 +0,0 @@
---
type: Changed
pr: 1647
---
**Capability commands now emit dispatch audit records** — `graphify`, `intel`, `audit-uat`, and `audit-open` now route through the Command Routing Hub per ADR-959 §III(B), so `GSD_AUDIT=1` traces, the structured stderr JSON error envelope, and the typed Result contract cover them uniformly with all other command families. JSON-error `reason` values (`usage`, `sdk_unknown_command`) are preserved byte-identical. (#1646)

View File

@@ -1,5 +0,0 @@
---
type: Changed
pr: 1611
---
**`/gsd-verify-work` now routes UAT deterministically from a structured `coverage:` block on SUMMARY.md** — deliverables proven by passing tests (`human_judgment: false` with a non-empty all-`pass` `verification` list) are auto-passed (`source: automated`, no prompt), and only judgment-dependent or unverified deliverables are presented for human sign-off. SUMMARYs without a `coverage:` block fall back to the previous prose-based extraction, byte-identical. Authored by `execute-plan` and validated by the new `gsd-tools uat classify-coverage` verb.

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1456
---
Phase-aware commands now resolve project-code-prefixed ROADMAP headings such as MANIFOLD-117, while the roadmapper is instructed to keep project_code out of phase headings.

View File

@@ -1,7 +0,0 @@
---
type: Changed
pr: 1438
---
**Thread `isGlobal` install scope through the descriptor-driven `convertedAgentsKind` / `stageAgentsForRuntimeWithConverter` plumbing** — a prerequisite for the ADR-1235 agent-conversion cutover. No runtime declares a converted `agents` kind yet; the `capability.json` wiring is deferred to a follow-up that first ships the ADR-1235 §0 byte-for-byte parity harness (so the `/gsd:surface` / `--materialize` consumer can mirror the legacy agent pipeline before the kind goes live). The legacy `bin/install.js` agent loop remains authoritative, so installed agent output is unchanged. (#1173)
<!-- docs-exempt: internal install-path plumbing only (ADR-1235 cutover prerequisite); no runtime declares the converted agents kind, the legacy loop remains authoritative, and installed agent output is unchanged — no user-facing command/config/behavior surface. -->

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1500
---
**`workflow.mvp_mode` now accepted by `config-set`; three undocumented workflow keys added to references** — `workflow.mvp_mode`, `workflow.code_review_command`, and `workflow.plan_chunked` were consumed by planning-pipeline code but could not be set via `config-set` (they were missing from `VALID_CONFIG_KEYS`) or discovered via reference docs. All three are now in the schema and documented in `references/planning-config.md`. (#1500)

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1631
---
**Windsurf reinstall removes legacy .devin/skills/ artifacts** — pre-#1615 installs wrote skills under .devin/skills/gsd-*/ (Devin Desktop layout, #1085). #1615 moved Windsurf to .windsurf/workflows/ but never cleaned up the old layout. Reinstalls now remove GSD-managed .devin/skills/gsd-* dirs; user-owned content is preserved.

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1536
---
adr-parser now classifies 9 previously-dropped punctuated ADR headers (Trade-offs, Non-Goals, Won't Do, Follow-up, How We'll Know, etc.) into their intended buckets instead of leaving them unmapped.

View File

@@ -1,5 +0,0 @@
---
type: Changed
pr: 1421
---
**`/gsd-review` now asks external reviewers to verify plan claims against the source** — the reviewer prompt requires opening the referenced files, citing `file:line` evidence + mechanism, and tracing asserted behavior, with a graceful-degradation clause for reviewers that have no file access. This turns every capable agentic reviewer into a real second source instead of a plan-text paraphraser. (#1318)

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1534
---
Add prototype-pollution guard to the workstream/root config merge (_deepMergeConfig) so a config.json with a __proto__/constructor/prototype key can no longer spoof unset config flags.

View File

@@ -1,5 +0,0 @@
---
type: Changed
pr: 1583
---
**eval-auditor scoring moved into a deterministic `eval.score` query verb (LLM-playbook principle 10)** — coverage/infra/overall arithmetic and verdict banding are computed in code (`gsd-tools query eval.score`) instead of by the model. Based on arXiv 2601.15130 (Plausibility Trap / DPDM), 2508.15754 (Tool-Integrated Reasoning), 2507.10281 (Table Agent); 2504.00406 / 2510.15955 supporting.

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1418
---
**All GSD agents load on Gemini again** — the Claude `Skill`/`SlashCommand` tools were converted to an invalid `skill` tool that Gemini rejects, aborting the load of 22 of 34 agents. They are now excluded from the Gemini and Gemini-backed Antigravity agent `tools:` frontmatter, the same way `AskUserQuestion` already is. (#1394)

View File

@@ -1,5 +0,0 @@
---
type: Added
pr: 1425
---
**`agent-skills --json` IR gains an additive `value: { block, skills_count }` field** formalizing the `Resolution<T>` convention for config-interpreting read verbs; no breaking change. The new `src/resolution.cts` module exports `Resolution<T> { value, configured, reason, warnings }` (the canonical envelope) and `makeResolution<T>()` (the builder); `AgentSkillsValue { block, skills_count }` is the first adopter. All existing flat fields (`agent_type`, `block`, `skills_count`, `warnings`, `configured`, `reason`, `source`, `degraded`) are retained for back-compat. Capability-state and capability-writer keep their existing JSON shapes unchanged; only doc comments are added naming them the canonical read-verb and mutation-verb envelopes respectively. The shared seam across all shapes is `warnings: string[]`; a single generic across read+write verbs was rejected by the deletion test (ADR-1411 P3 amendment). (Part of #1411, P3 / #1416.)

View File

@@ -1,5 +0,0 @@
---
type: Added
pr: 1488
---
**Added `gsd capability outdated`** — a new subcommand that light-peeks each installed overlay capability's recorded source for the latest version that re-resolving that source would install and reports which have an update available (ADR-1244 D6 per-source matrix: git `ls-remote --tags`, npm `view … version`, local re-read; tarball → `manual`, registry → `unknown`). A capability is reported `outdated` only if re-resolving its recorded source would fetch a newer version: an npm range (`@^1`) resolves to the highest version **matching the range** (read from each `npm view` line's canonical version field, so a version-like substring in the package name never poisons the result), and a source pinned to an immutable ref (git `#sha:`/`#tag:`) or an exact npm version is reported `pinned` — never `outdated`, since `update` will not move it. A bare git ref (`#<ref>`) is classified at the remote with a bounded `git ls-remote`: a ref that resolves to a tag is `pinned`, while a **mutable branch** ref is never `pinned` (it degrades to `unknown`, since the installed commit is not recorded to compare against). Each capability is classified `outdated` / `current` / `pinned` / `manual` / `unknown`; subprocesses are bounded (git ≤30s, npm ≤60s) and a failing or unsupported peek degrades that row to `unknown` instead of crashing the command. `--json` emits the records array; the default prints a table. (#1463)

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1442
---
**Antigravity config-dir resolution no longer shadows the active runtime** — when more than one of `~/.gemini/antigravity`, `antigravity-ide`, or `antigravity-cli` exists, GSD now resolves to the directory it actually installed into (marked by `gsd-core/VERSION`) instead of whichever directory existed first. Fixes silent misresolution where a CLI user who also had the Antigravity-IDE dir present was sent to the legacy dir (regression from #217).

View File

@@ -1,8 +0,0 @@
---
type: Changed
pr: 1423
---
**`gsd-tools` now resolves the project root from a descendant subdirectory** — `findProjectRoot` walks up to the nearest ancestor directory containing `.planning/` so config loads correctly when invoked outside the project root; previously it fell through to defaults for plain descendant paths (cwd-drift gap #1366). Sub_repos, multiRepo, and `.git`-based heuristics retain priority. (Part of #1411, P1 / #1414)
<!-- docs-exempt: internal resolution heuristic in project-root.cts — no public docs surface for findProjectRoot; behavior change surfaced via config loading, not a user-visible API -->

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1424
---
**`gsd-tools query agent-skills` no longer silently drops a configured agent's skills under cwd or workstream drift** — `cmdAgentSkills` now anchors to the project root via `findProjectRoot` before loading config, so invoking it from a descendant subdirectory or with a `GSD_WORKSTREAM` that has no scoped config correctly resolves the configured `agent_skills` block. A new `loadConfigResolved(cwd, options) → { config, source, degraded }` function reports provenance alongside the config object: `source` distinguishes `'root' | 'workstream' | 'builtin-defaults' | 'global-defaults'`; `degraded:true` signals a workstream was requested but its config.json was absent. The `--json` IR of `agent-skills` gains four new fields — `configured` (bool), `reason` (`'resolved' | 'not_configured' | 'configured_empty' | 'configured_unresolved'`), `source`, and `degraded` — making silent failures visible and testable. A `configured_empty` or `configured_unresolved` agent emits a `stderr WARNING`; an unconfigured agent stays silent. (Closes #1366. Part of #1411, P2 / #1415.)

View File

@@ -1,9 +0,0 @@
---
type: Fixed
pr: 1484
---
**`findProjectRoot` now respects explicit `sub_repos` config over implicit `.git`** — when a parent workspace's `.planning/config.json` lists a child directory in `sub_repos`, that declaration takes precedence over the child's own `.git/` directory. Previously, if the child had both `.planning/` and `.git/`, the `.git` heuristic fired first and resolved to the child rather than the parent workspace, making the `sub_repos` declaration ineffective. (#1422)
**`phases clear` now refuses to delete phase directories with uncommitted changes** — `cmdPhasesClear` runs `git status --porcelain` over the phases directory before executing any deletion. If uncommitted or staged-but-not-committed files are found it aborts with a clear error message, preventing silent data loss at `new-milestone` time. Pass `--force` to bypass the guard when archival is already complete. Non-git projects are unaffected. (#1447, data-loss fix)
<!-- docs-exempt: internal CLI guard in milestone.cts — no public docs surface change; --force flag is an operator escape hatch, not a user-visible API change -->

View File

@@ -1,6 +0,0 @@
---
type: Fixed
pr: 1490
---
**999.x backlog phases are now excluded from `total_phases`, and `total_phases` can correct downward** — `deriveProgressFromRoadmap` counted all progress-table rows whose phase cell started with a digit, so a `999.1 Backlog` row inflated `total_phases` by one per entry (#1445). The same overcounting occurred in `getMilestonePhaseFilter` (which feeds `isDirInMilestone` and `phaseDirs`) and in the `roadmapPhaseCount` loop in `buildStateFrontmatter`. All three sites now filter phase tokens matching `/^999\b/`, consistent with the existing exclusion in `init.cts`. Additionally, `shouldPreserveExistingProgress` included `total_phases` in its ratchet check, preventing the counter from decreasing once set too high — e.g. after a 999.x fix or a ROADMAP correction (#1446). `total_phases` is now always taken from the freshly derived value; only `completed_phases`, `total_plans`, and `completed_plans` retain ratchet behaviour.

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +0,0 @@
---
type: Fixed
pr: 1481
---
**Capability `--integrity` is now verified or rejected per source, and hook commands are confined to the bundle** — a supplied `--integrity` pin was silently dropped for npm, git, and local capability sources (only the tarball source verified it), so a user could believe content was pinned when it was not. npm now verifies the pin over the `npm pack` `.tgz` bytes; git and local sources, which have no single hashable artifact, now reject a supplied `--integrity` with an actionable error instead of ignoring it. Separately, a capability hook's relative `script` was written verbatim as the hook command, so it resolved against the working directory (not the capability bundle) at hook-exec time and a crafted relative path could escape the bundle; the command is now resolved against the capability's own install dir and realpath-confined to it, then written as an absolute path. That absolute command is consumed by a shell, which exposed two further problems now fixed: (1) a manifest could ship a file literally named `run.sh; touch /tmp/pwn` (filenames may legally contain `;`, spaces, `$`, backtick, `|`, newline) and declare it as the hook `script`, so the emitted command injected a second shell command even though the file lived inside the bundle — the validator now rejects any hook script path outside a conservative `[A-Za-z0-9._/-]` allowlist (no whitespace, shell metacharacters, leading `-`, absolute path, or `..`), failing the install/load loudly, and the confinement helper mirrors the same rejection defensively; (2) the absolute path begins with the install-home directory, which commonly contains spaces (e.g. `/Users/Bob Smith/.claude/...`) and word-split or broke when written unquoted — the emitted command is now POSIX single-quoted so the install prefix can neither break nor inject. (#1460)

View File

@@ -1,7 +0,0 @@
---
type: Fixed
pr: 1475
---
**The capability loader never crashes on a single malformed overlay, and untrusted manifest/tar reads are size-bounded (ADR-1244 D2 invariant)** — `loadRegistry` now makes the WHOLE per-candidate overlay-processing body total: ANY throw from ANY validator or step (including the committed `validateCapability`, which dereferences a malformed array entry such as `gates: [null]` / `steps: [null]` / `contributions: [null]` before its shape check) drops just that one overlay with a skip-warning instead of escaping the loader, while `gatePointsOf` is hardened to be total over null/non-array/malformed gates. The final canonical `buildRegistry` compose stays guarded: a throw on the merged set falls back to the frozen first-party registry plus a warning, records each dropped gate-declaring overlay's declared gate as blocked (`incompatibleGateCapIds` / `blockedGates`) so a dropped blocking gate FAILS CLOSED, AND now clears `_overlay.commandRoots` in the fallback so no dropped overlay retains a stale command root. Previously a malformed-array throw or a compose throw escaped the loader and crashed every consumer (loop-resolver, config-loader, surface, capability-state, gsd-tools). On the source side, the capability resolver/staging now reads every untrusted `capability.json` (tarball / npm / git / local) via the shared bounded fd-reader (regular-file + 8 MiB cap) instead of a raw `fs.readFileSync`, so an oversized or FIFO/non-regular extracted-or-local manifest can no longer OOM or hang the resolver; the fetch (`realHttpsGet`) bounds the downloaded response to 64 MiB; and `stageValidated` now enforces ONE uniform aggregate byte-budget (`MAX_STAGED_BUNDLE_BYTES`, 128 MiB) over the STAGED bundle directory via a bounded streaming walk (cumulative byte + entry counters; symlink / non-regular entries rejected) at the common staging chokepoint — AFTER staging and BEFORE validation/promotion — so a huge source tree, git repo, npm package, or gzip/tar bomb is rejected (and its staging dir cleaned up) before promotion, uniformly bounding the RESULT of `copyDirRecursive` / `git clone` / `npm pack` / `tar -x` that were previously only timeout-bounded. `copyDirRecursive` itself is now STREAMING and BUDGETED: it enumerates each directory via `fs.opendirSync` + `dir.readSync()` (one entry at a time) and threads CUMULATIVE entry (`MAX_STAGED_BUNDLE_ENTRIES`, 100k) and byte (`MAX_STAGED_BUNDLE_BYTES`) counters through the recursion, failing closed the MOMENT either cap is exceeded DURING the copy — closing a residual where the former `fs.readdirSync(src, { withFileTypes: true })` materialized the ENTIRE directory-entry array into memory at staging time (BEFORE the post-copy budget walk), so a hostile source whose tree held a directory of millions of tiny files (fetch < 64 MiB, but a colossal dirent array) could OOM the process during the copy before the budget could fail closed; the post-copy walk is retained as a cheap belt-and-suspenders re-verification on what actually landed in staging. The spoofable per-member `tar`-header size parse (`parseTarMemberSize`, which mis-anchored on BSD `tar -tv` owner/group columns such as a `Jan` group → fail-open) was REMOVED in favor of that non-spoofable staged-dir budget; `assertSafeTarMembers` keeps its unambiguous traversal / symlink / hardlink NAME and TYPE guards. (#1461)
<!-- docs-exempt: internal robustness hardening of the runtime capability loader/source seams (capability-loader.cts / capability-source.cts) — no user-visible API change; the never-crash + bounded-fetch guarantees are ADR-1244 D2 internal invariants -->

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1469
---
**Capability ledger: fail closed on corruption, with durable atomic writes and a race-safe install lock.** A corrupt or unreadable `.gsd-capabilities.json` is now left in place and surfaced (not silently overwritten) — `install`/`update`/`remove`/`list`/`reconcile` fail closed and report it, so a corrupt ledger can no longer wipe prior capabilities' tracked files and shared-config fragments (which previously left unremovable orphans in `settings.json`/`hooks.json`). Ledger writes are atomic and crash-durable (exclusive temp file + `fsync` of file and directory + rename, with temp cleanup on failure). The per-capability lock is race-safe: a holder is identified by `(pid, process start-time, hostname)`, so a reused PID cannot deadlock recovery and a verifiably-live holder is never stolen, with a hard deadman timeout for unverifiable or cross-host holders. Untrusted ledger and lock reads are bounded (regular-file + size caps; FIFOs/devices rejected) and validated through a single shared entry validator (prototype-safe ids, DoS length caps). (#1462, ADR-1244.)

View File

@@ -1,8 +0,0 @@
---
type: Fixed
pr: 1482
---
fix(#1478,#1479,#1480): prohibit ungrounded baselines, error-suppressing fallbacks, and stale-artifact authority in planner verify blocks
<!-- docs-exempt: instruction-text updates to agents/gsd-planner.md, agents/gsd-plan-checker.md, and references/planner-antipatterns.md are themselves the documentation — no public user-facing API or CLI change -->

View File

@@ -1,6 +0,0 @@
---
type: Fixed
pr: 667
---
**`/gsd:pr-branch` now handles sub-repos defined in config** — when `planning.sub_repos` is set, the command scans each sub-repo for uncommitted changes and offers to create a branch, commit, push, and open a companion PR per sub-repo. Previously, sub-repos were silently ignored because all git commands ran against the shell's current directory instead of the intended repo path. All sub-repo git operations now use `git -C <repo>` so no shell-state assumptions are made.

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1654
---
**`/gsd-new-project` AI Models prompt now exposes the `adaptive` model profile** — both onboarding paths (auto-mode and interactive) listed only Balanced/Quality/Budget/Inherit, so the `adaptive` profile (role-based cost optimization across Claude/Codex/Gemini/OpenRouter/local) was unreachable through `/gsd-new-project` despite being a first-class catalog entry and documented in CONFIGURATION.md. Both prompts now use the proven two-question split (Q1: Adaptive / Standard tier / Inherit; Q2: Quality / Balanced / Budget) already shipped for `/gsd:settings` (#3784), and both `config-new-project` example payloads list `adaptive`. (#1516)

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1457
---
**`--raw` CLI commands no longer drop stdout on the error path** — a command that emitted a JSON result/error envelope and then exited non-zero previously lost all of stdout (the output-capture wrapper discarded its buffer when the command threw to set a non-zero exit); the buffer is now flushed before the error propagates. (#1457)

View File

@@ -1,5 +0,0 @@
---
type: Added
pr: 1457
---
**`gsd capability` management command** — install, update, remove, list, disable, and enable GSD capabilities (first-party and third-party overlays) from a registry / git / npm / tarball / local source, wiring the ADR-1244 lifecycle (source resolver, ledger, consent + integrity trust gate) to a user-facing CLI. (#1457)

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1661
---
**`gsd install`/upgrade now recovers a malformed `~/.gsd/defaults.json` instead of leaving it broken** — a `defaults.json` containing a valid-JSON-but-non-object value (`null`, `[]`, a number, or a string) bypassed the parse `catch` and flowed through unrecovered: `null` threw a TypeError (swallowed by the outer guard, logging a confusing "Could not write" warning and leaving the file as `null`), while `[]`/`42`/`"str"` silently kept their broken shape on every install. The non-Claude finishInstall step now resets any non-object parse result to a fresh `{}` before reading/writing it, so the file is repaired and `resolve_model_ids` defaults normally.

View File

@@ -1,5 +0,0 @@
---
type: Security
pr: 1585
---
**Prompt-injection defence extended to the untrusted-input surface (LLM-playbook principle 12)** — the read-injection scanner (a pattern-based pre-filter) now also scans WebFetch/WebSearch output (closing the largest untrusted channel at ingress), and the 10 research/doc-ingest agents (issue #1577 AC #2's named eight plus `gsd-ai-researcher` and `gsd-domain-researcher`, both web-ingress) isolate fetched/read content as data-not-instructions via a shared `untrusted-input-boundary` reference — this prompt-level boundary is what keeps an injection from being *followed*. An opt-in `security.injection_blocking` (registered config key; default advisory, unchanged) upgrades HIGH-confidence detections to a PostToolUse circuit-breaker: since the hook runs after the fetch, `decision: "block"` halts the agent's next step rather than redacting the already-fetched content (it is not a redactor). Based on arXiv 2506.05739 (PPA), 2507.15219 (PromptArmor), 2504.20472, 2503.00061.

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1568
---
**Shipped milestones with a retired/folded phase now reach 100%** — a phase struck through in ROADMAP (marked `[x]`, with a directory but no completion artifact) was counted in `progress.total_phases` but could never be counted complete, freezing the milestone below 100% (e.g. 5/6 = 83%) with `state sync --verify` reporting no drift. Both STATE counting paths (`state json` and `state sync`) now exclude retired phases — detected from GFM strikethrough whose subject is the phase on a checklist/heading line — from both the phase-dir set and the heading count, via the canonical phase-id helpers so numeric, decimal, and project-code IDs match alike. (#1514)

View File

@@ -1,5 +0,0 @@
---
type: Added
pr: 1440
---
**Runtime capability registry overlay** — installed third-party capabilities (under `~/.gsd/capabilities/` or a project's `.gsd/capabilities/`) are now composed into the registry at runtime via `loadRegistry({ includeInstalled })`: validated against the same conformance invariants as first-party, first-party-wins on any collision, skipped-with-a-warning when incompatible with the running GSD version (`engines.gsd`), with gate-kind capabilities failing closed. Installed overlays are toggable via surface and federate their config keys (cwd-aware) exactly like first-party. Foundation (ADR-1244 Phase 2) for capability install/upgrade/remove.

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1519
---
**Codex installs no longer run with unsafe Claude-style worktree isolation** — a Codex install with a runtime-neutral `.planning/config.json` was resolving its runtime as Claude and enabling git worktree isolation, which Codex's `spawn_agent` cannot honor; the Codex fail-closed guard was also silently dead because runtime/worktree config was read JSON-quoted and broke shell equality checks. Codex-emitted workflows now resolve `runtime=codex`, default `workflow.use_worktrees` to `false`, and fail closed when worktrees are forced on. (#1515)

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1622
---
**Windsurf installs expose /gsd-* commands in Cascade again** — Windsurf runtime installs now emit workflow files under .windsurf/workflows instead of dead skills-only artifacts. (#1615)

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1638
---
**Capability `settings.json` hooks no longer fire on every tool and no longer fail when non-executable** — installing a capability that declared a tool-scoped `PreToolUse`/`PostToolUse` hook wrote the entry with no `matcher`, so a guard intended for only `Write|Edit` fired on every tool call (including `Bash`) and a fail-closed guard could block the whole session; the emitted command was also a bare script path, so a `.js`-family hook delivered via `git`/tarball that lost the executable bit failed with `Permission denied` on every matching call. Install now honors a declared `matcher` (absent = match-all, unchanged for existing capabilities) and emits a `node`-prefixed command for `.js`/`.cjs`/`.mjs` hooks so they run regardless of file-mode bits. (#1634)

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1633
---
**`/gsd:secure-phase` now honors the configured ASVS level and block threshold** — the security auditor previously received unsubstituted `{SECURITY_ASVS}` / `{SECURITY_BLOCK_ON}` placeholder text because secure-phase.md never assigned those variables. It now resolves `workflow.security_asvs_level` and `workflow.security_block_on` from config (`--raw`) before the auditor handoff. (#1625)

View File

@@ -1,5 +0,0 @@
---
type: Added
pr: 1436
---
**Capability manifests are now versioned** — every `capability.json` carries a required semver `version`, plus optional `engines.gsd`, `compatVersions`, `integrity` and `provenance` fields, enforced by the capability conformance validator. First-party capabilities are version-stamped in lockstep with the GSD release. Foundation (ADR-1244 Phase 1) for installing, upgrading, and removing capabilities in later releases.

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1548
---
**Phase transitions now require fresh canonical verification** - implementation-complete phases no longer advance when verification is missing, gap-bearing, human-pending, or stale relative to phase summaries.

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1635
---
**The security audit gate now respects `workflow.security_block_on` severity** — `/gsd:secure-phase` previously blocked phase advancement on *any* open threat regardless of severity, so the documented `security_block_on` threshold had no effect (and the auditor's block vocabulary didn't even match the config enum). Threats now carry a per-threat **Severity** (critical|high|medium|low), and only open threats at or above the configured `security_block_on` severity count toward the blocking gate (`SECURITY.md threats_open`); `none` disables blocking, and a missing/unparseable severity fails closed as critical. (#1626)

View File

@@ -1,5 +0,0 @@
---
type: Security
pr: 1449
---
**Third-party capability trust gate (ADR-1244 Phase 4)** — installing a capability from a git/npm/tarball/local source now discloses every executable surface it ships (hooks, command modules, MCP servers, with the actual commands) and requires explicit consent before anything is promoted; integrity (sha512) and `engines.gsd` are verified before any code is staged, install never executes capability code, and reserved `gsd-`/`gsd-core-`/`anthropic-` namespaces are refused. `capabilities.strict_known_registries` gates which sources may be installed (`[]` = local-only lockdown; host-based allowlist otherwise) and `capabilities.auto_update` is off by default, re-prompting whenever a new version's executable set changes. An install ledger makes `remove` surgical (strips only the capability's own shared-config entries, preserving your hand-edits) and `update` an atomic, crash-safe stage-then-swap. (#1449)

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1504
---
`verify codebase-drift` now reads `workflow.drift_action` and `workflow.drift_threshold` from the correct nested config shape — previously both keys silently no-oped because `loadConfig()` returns a flattened object and `config?.workflow` was always `undefined`.

View File

@@ -1,5 +0,0 @@
---
type: Added
pr: 722
---
**`/gsd-capture --list-seeds` audits parked seeds** — a new read-only listing of `.planning/seeds/` showing each seed's ID, status, scope, and trigger, with an optional status filter (e.g. `--list-seeds dormant`). Backed by the `gsd-tools list-seeds` command. Previously seeds could only be created or auto-surfaced at `/gsd-new-milestone`, with no way to browse them on demand (#441).

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1665
---
**`check.decision-coverage-plan` no longer false-passes when CONTEXT.md decisions use the titled-colon bullet form** — `parseDecisions` recognized the colon-immediate (`- **D-NN:** text`) and em-dash (`- **D-NN — title** body`) forms but dropped the titled-colon form (`- **D-NN: Title.** body`, where a title sits between the colon and the closing `**`) via the parse-miss guard. When all decisions used the titled convention, the parser returned 0 decisions and the coverage gate passed vacuously. A third per-form regex (checked last, a strict superset of the colon form) now parses the titled-colon form; id and `[tags]` trackability are honored.

View File

@@ -1,5 +0,0 @@
---
type: Added
pr: 1443
---
**Capability source resolver + install ledger** — `resolveCapabilitySource(spec)` fetches a capability from a local path, git repo, npm package, or tarball URL, verifies it (sha512 integrity before staging, `engines.gsd` compatibility, full conformance validation) and stages a bundle **without executing any capability code** (copy/extract only — `npm pack --ignore-scripts`, never `npm install`; symlink/tar-slip/shell-metacharacter/unsafe-transport inputs rejected). A per-runtime ledger records what each install wrote for atomic, reversible upgrade/remove. Foundation (ADR-1244 Phase 3) for the upcoming `gsd capability install` command.

View File

@@ -1,5 +0,0 @@
---
type: Added
pr: 1458
---
**Capability matrix reference** — a generated catalogue (`docs/reference/capability-matrix.md`) of every first-party capability's role, tier, extension points, hook kinds, and `engines.gsd`, generated from the committed registry and kept honest by a CI drift guard so it can never fall out of sync with the actual capability set. (#1458)

View File

@@ -1,7 +0,0 @@
---
type: Fixed
pr: 1499
---
**`npm version` no longer leaves `capability-registry.cjs` stale** — the `version` npm lifecycle script now regenerates and stages the capability registry after stamping new version strings into all capability manifests, preventing the 1.6.0-rc regression where `gen-capability-registry.cjs --check` failed. (#1498)
<!-- docs-exempt: internal release-tooling fix; no user-facing command or API change -->

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1616
---
**Antigravity installs all GSD slash-command skills where AGY can discover them** — concrete skills such as /gsd-progress and /gsd-verify-work now land directly under the Antigravity skills directory instead of router-nested folders. (#1614)

View File

@@ -1,5 +0,0 @@
---
type: Added
pr: 1450
---
**Third-party capabilities can ship dispatchable CLI commands (ADR-1244 Phase 5)** — a capability that declares a `commands` family is now dispatched by `gsd-tools <family>` via the registry, the same seam the first-party `graphify`/`intel`/`audit` commands already use. Third-party command dispatch runs only for an installed, consented capability (a committed ledger entry) and loads the router module strictly from that capability's own install root (basename + realpath confinement, rejecting `..` traversal and symlink escape); a bundle merely present on disk with no install record keeps its declarative surfaces but is never command-dispatchable. (#1450)

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1664
---
**`frontmatter set` on an object-list field now fails closed instead of silently doing nothing** — setting `must_haves` (or another object-list field) to a value whose lossy parse projection matched the original's was a silent no-op: the command reported `{updated:true}` but the change never applied (the writer's scalar-only parser had flattened both to the same shape). `frontmatter set` now detects a no-op write for dict-valued fields and surfaces a clear error directing the user to edit the file directly. Scalars and scalar arrays round-trip faithfully, so idempotent sets of those still report `{updated:true}` (no false positive).

View File

@@ -1,5 +0,0 @@
---
type: Changed
pr: 1518
---
**verify-phase test-tier prohibition fail-first can now prove the RED is caused by the violation's _content_** — the `node-test` machine-proof (#1279) confirmed a known-bad subject drives the negative test RED, but could not tell a genuine content-violation from a deceptive test that reds merely because `GSD_PROHIB_SUBJECT` is set. An optional fifth flat scalar `check_clean_fixture` (→ `CheckDescriptor.cleanFixture`) threads a KNOWN-CLEAN control subject through `projectProhibitions` + `descriptorFromProjection`; when present the prover also runs the check against it and requires GREEN, so fail-first is proven only when the check is RED on the violation **and** GREEN on the clean subject (content-dependent). It is opt-in and additive: absent a clean fixture the prover behaves exactly as it did post-#1314 (no control, documented residual), preserving the zero-authoring compose path; the lint-rule kind needs no analog. (#1346)

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1632
---
**`config-set` now rejects invalid config values instead of storing them silently** — out-of-enum strings, JSON array/object coercion (e.g. `["high"]` stored as an array in a scalar key), and wrong-typed values for capability-registry-owned keys are validated against each key's declared schema at set time. Previously these were accepted and persisted, mis-configuring GSD. (#1628)

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1574
---
**OpenCode and other AGENTS-native runtimes now get a root `AGENTS.md` from `/gsd:new-project`** — the workflow hardcoded a codex-only branch that sent every other runtime to `.claude/CLAUDE.md`, a location OpenCode never loads. A shared `getProjectInstructionFile(runtime)` policy (claude→`.claude/CLAUDE.md`, codex/opencode/kilo/kimi→`AGENTS.md`, copilot→`.github/copilot-instructions.md`, antigravity/gemini→`GEMINI.md`) is now the single source of truth consumed by both the new-project workflow and the generate-claude-md path, with a parity test guarding drift.

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1539
---
`roadmap upgrade` now rejects an unsupported or malformed `--convention` value (including the `--convention=` form) instead of silently running the milestone-prefixed migration, and no longer hard-exits inside the command-routing hub.

View File

@@ -1,5 +0,0 @@
---
type: Added
pr: 1597
---
**Plugin installs now expose GSD skills** — when GSD is installed as a Claude Code plugin (`claude plugin install`), its skills are available via `gsd-core:<skill>` the native way. Previously, plugin-only installs lacked the skill surface because `bin/install.js` never ran; agents that preload `global:gsd-core:<skill>` (PR #1261) now resolve against plugin-provided skills. (#1596)

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1663
---
**`phase complete` no longer duplicates a By-Phase row when the phase number's padding differs** — completing a phase by its unpadded number (e.g. `phase complete 5`) against an existing zero-padded By-Phase row (`| 05 |`) appended a second `| 5 |` row instead of updating it, double-counting the phase in any column sum. The row matcher now canonicalizes a numeric phase to its integer form (matching `5`, `05`, `005` in either direction), so the existing row is upserted regardless of padding.

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1653
---
**Non-Claude installs no longer rewrite an explicit `resolve_model_ids: true` to "omit"** — Codex, OpenCode, Gemini, and the other non-Claude runtimes were silently clobbering the deliberate opt-in to full materialized model IDs on every install/upgrade, so generated agent manifests inherited the active chat model instead of pinning the resolved model. The finish step now only defaults `resolve_model_ids` to "omit" when it is absent or falsy; an explicit `true` is preserved. (#1569)

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1543
---
A failed `roadmap upgrade --apply` now actually rolls back .planning/ even when it is gitignored (commit_docs:false), instead of reporting a successful rollback while leaving the workspace half-migrated. Rollback is surgical and no longer runs a whole-repo git reset --hard.

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1409
---
**Codex runtime no longer crashes on startup** — every `gsd-tools` command previously aborted with `Cannot find module '../../../package.json'` on Codex, whose runtime root has no `package.json`, because a module in the loader chain did a top-level require of it. The version emitted into Hermes skill frontmatter is now sourced lazily from the installed `gsd-core/VERSION` (validated semver), so `gsd-tools` loads on every runtime and never emits `version: undefined`. (#1383)

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1630
---
**`/gsd-*` commands in Windsurf Cascade resolve their command bodies** — Windsurf slash-command workflows delegate to canonical command bodies at gsd-core/commands/gsd/X.md, but the install never copied those files. Commands appeared in the `/` menu yet silently failed when invoked because the LLM was told to read a missing file. Installs now copy commands/gsd/*.md into the workflow delegation target.

View File

@@ -1,5 +0,0 @@
---
type: Added
pr: 1448
---
Added a validated `gsd-tools worktree record-agent` writer verb that appends a per-agent entry to the wave cleanup manifest, validating every field at write time with the same rules the `cleanup-wave` reader enforces (write-strict `--agent-id`) and failing loudly with a recovery hint instead of silently appending an under-populated entry. The execute-phase orchestrator now records each spawned worktree through this verb. (#1448)

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1410
---
**`query agent-skills` no longer returns empty output on Windows** — the plain (non-`--json`) path wrote the `<agent_skills>` block then immediately called `process.exit(0)`, which truncated the async stdout buffer on Windows pipes/files so every `${AGENT_SKILLS_*}` workflow capture expanded empty and configured per-agent skills were silently dropped. It now flushes synchronously via the same `writeAllSync` helper the `--json` path uses. (#1400)

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1662
---
**`phase complete` now updates the By-Phase table on CRLF (Windows) STATE.md files** — the By-Phase table matcher required bare `\n` line endings, so a STATE.md written or hand-edited with CRLF (`\r\n`) was treated as having no table: the completed phase's row was never upserted (and, with the velocity-from-table derivation, the total went stale). The matcher is now CRLF-tolerant (`\r?\n`) on the header/separator/lookahead, so CRLF STATE.md files are handled identically to LF.

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1453
---
clean up stale get-shit-done paths in Codex and Kimi skill mirrors on upgrade (#1453)

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1437
---
add phase.list-plans to gsd-tools — the command was referenced in agents/gsd-plan-checker.md but was missing from the router, causing 'Unknown phase subcommand' on every invocation

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1552
---
roadmap analyze no longer reports phantom missing_phase_details for milestone-prefixed (M-NN) phase IDs

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1636
---
**`workflow.security_asvs_level` now actually scales security rigor** — it was display-only (the planner hardcoded ASVS L1 and the auditor only echoed the level), so L2/L3 behaved identically to L1. The configured ASVS level now scales both planner threat-disposition rigor and auditor verification depth (L1 grep-presence → L2 boundary/vector checks → L3 end-to-end trace), defined in a new `references/security-asvs-levels.md`; the secure-phase clean-phase short-circuit now spawns the auditor at L2/L3 so deep verification runs even when the preliminary grep classification is clean. (#1627)

View File

@@ -1,7 +0,0 @@
---
type: Added
pr: 1419
---
**`gap-analysis --phase-req-ids` now expands numeric ID ranges** — a same-prefix ascending equal-width range like `SEL-01..SEL-03` expands to `SEL-01, SEL-02, SEL-03` (zero-pad preserved) instead of being treated as one literal ID that gap-analysis then reports as missing. Ambiguous tokens (mismatched prefix, descending, differing width, non-numeric, >1000 span) stay literal. (#1269)
<!-- docs-exempt: `--phase-req-ids` is an internal gsd-tools query flag consumed by GSD workflows, not part of the user-facing documented command surface; no docs/ entry exists for it. -->

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1541
---
Atomic file writes now retry a transient rename lock on Windows (a reader holding the target open) instead of falling back to a non-atomic write that could let a concurrent reader observe a truncated STATE.md/ROADMAP.md.

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1376
---
**Misconfigured agent skills no longer fail silently** — when an agent's configured `agent_skills` paths all fail to resolve (e.g. a missing `SKILL.md`), `gsd-tools query agent-skills` now emits an aggregate warning to stderr and adds a `warnings[]` field to its `--json` output, instead of returning an empty block with no signal. (#1376)

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1386
---
**Decision-coverage gate now reads markdown-header and em-dash decisions, and fails loud when it can't parse them** — `check.decision-coverage-plan` (a blocking gate) and `gap-analysis` previously extracted **zero** decisions from a populated CONTEXT.md that recorded its decisions under markdown headers (`## Locked decisions`) or with em-dash bullets (`- **D-1 — title**`), and silently reported a clean pass — so real decisions went un-checked. Decisions in those shapes are now recognized, and when decision-shaped content cannot be parsed (or a `- **D-NN**` bullet is malformed), the gate fails loud with a format-mismatch message instead of passing. (#1386)

View File

@@ -1,5 +0,0 @@
---
type: Changed
pr: 727
---
**fish-shell support in the post-install PATH suggestion.** When a directory is not on your PATH, the installer now prints a fish-native `fish_add_path '<dir>'` line alongside the zsh/bash suggestions (the previous `export PATH=…` commands are inert in fish). It also stops the false-positive "not on your PATH" warning for fish users whose `fish_user_paths`/`config.fish` already covers the directory, detected via a read-only probe of fish's config (no fish subprocess, no writes). No change for bash/zsh/PowerShell/cmd/Git-Bash users.

View File

@@ -1,5 +0,0 @@
---
type: Added
pr: 1595
---
**`/gsd-plan-phase` now flags a stale codebase map before planning** — the `drift` capability runs its codebase-drift check at `plan:pre` (non-blocking, warn-only), so a stale STRUCTURE.md is surfaced before the planner is spawned instead of being discovered mid-execution by the existing `execute:wave:post` gate. Gated on a new `workflow.plan_drift_precheck` toggle (default on), independent of `workflow.schema_drift_gate`, so autonomous/CI runs can silence the plan-time advisory without disabling the execute-time gates.

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1655
---
**`phase complete` no longer double-counts Total plans completed velocity on re-run** — re-running `phase complete` on an already-complete phase incremented the velocity total each time (2 -> 4 -> 6 ...), because the metric re-read the cumulative total and blind-added the phase's plan count on every invocation. The total is now derived from the By-Phase table's Plans column (the same source the table upserts against), so re-completing a phase upserts the same row and the sum stays stable — and a hand-edited inflated total self-heals to the true sum on the next completion. (#1582)

View File

@@ -1,5 +0,0 @@
---
type: Fixed
pr: 1640
---
verify schema-drift now resolves the target phase by its canonical token instead of substring containment, so a non-existent phase no longer silently matches a token-superstring phase (e.g. "1" matching "11-expansion") and runs the drift gate against the wrong phase.

View File

@@ -1,7 +1,7 @@
{
"name": "gsd-core",
"displayName": "GSD Core",
"version": "1.6.0-rc.3",
"version": "1.6.0",
"description": "GSD Core is a meta-prompting, context engineering, and spec-driven development system for AI coding agents.",
"author": {
"name": "open-gsd",

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,7 @@
{
"id": "ai-integration",
"role": "feature",
"version": "1.6.0-rc.3",
"version": "1.6.0",
"title": "AI design contract",
"description": "AI-SPEC design contract workflow for phases that build AI systems; owns the AI integration command, agents, and workflow.ai_integration_phase activation key.",
"tier": "full",

View File

@@ -1,7 +1,7 @@
{
"id": "antigravity",
"role": "runtime",
"version": "1.6.0-rc.3",
"version": "1.6.0",
"title": "Antigravity",
"description": "Google Antigravity IDE — nested under ~/.gemini/antigravity; probed across 1.x and 2.x layouts; Gemini hook event dialect; flat skill layout; tier-1 support.",
"tier": "core",

View File

@@ -1,7 +1,7 @@
{
"id": "audit",
"role": "feature",
"version": "1.6.0-rc.3",
"version": "1.6.0",
"title": "Audit",
"description": "Open-artifact audit and UAT-gap audit for milestone close gates; exposes `gsd-tools audit-uat` (cross-phase UAT outstanding items) and `gsd-tools audit-open` (structured open-artifact scan across debug, tasks, threads, todos, seeds, UAT, verification, context-questions).",
"tier": "full",

View File

@@ -1,7 +1,7 @@
{
"id": "augment",
"role": "runtime",
"version": "1.6.0-rc.3",
"version": "1.6.0",
"title": "Augment Code",
"description": "Augment Code CLI — commands + nested-skill artifact layout; settings-json hook surface; Claude hook event dialect; tier-2 support.",
"tier": "core",

View File

@@ -1,7 +1,7 @@
{
"id": "claude",
"role": "runtime",
"version": "1.6.0-rc.3",
"version": "1.6.0",
"title": "Claude Code",
"description": "Anthropic Claude Code — primary development runtime; tier-1 support with full hook surface and skills-based global install.",
"tier": "core",

View File

@@ -1,7 +1,7 @@
{
"id": "cline",
"role": "runtime",
"version": "1.6.0-rc.3",
"version": "1.6.0",
"title": "Cline",
"description": "Cline (VS Code extension) — global-only nested-skill layout; cline-rules hook surface (.clinerules); no hook events emitted; tier-2 support.",
"tier": "core",

View File

@@ -1,7 +1,7 @@
{
"id": "code-review",
"role": "feature",
"version": "1.6.0-rc.3",
"version": "1.6.0",
"title": "Code review",
"description": "Source-file code review and review-fix workflow support for completed execution work.",
"tier": "full",

View File

@@ -1,7 +1,7 @@
{
"id": "codebuddy",
"role": "runtime",
"version": "1.6.0-rc.3",
"version": "1.6.0",
"title": "CodeBuddy",
"description": "CodeBuddy (Tencent) — converted commands + skills artifact layout; settings-json hook surface; Claude hook event dialect; tier-2 support.",
"tier": "core",

View File

@@ -1,7 +1,7 @@
{
"id": "codex",
"role": "runtime",
"version": "1.6.0-rc.3",
"version": "1.6.0",
"title": "OpenAI Codex CLI",
"description": "OpenAI Codex CLI — shell-var command style; per-agent sandbox tiers; config.toml + hooks.json hook surface; tier-1 support.",
"tier": "core",

View File

@@ -1,7 +1,7 @@
{
"id": "copilot",
"role": "runtime",
"version": "1.6.0-rc.3",
"version": "1.6.0",
"title": "GitHub Copilot",
"description": "GitHub Copilot (VS Code) — markdown config format; copilot-inline hook surface; no hook events emitted; flat skill nesting (unconfirmed recursive loader); tier-2 support.",
"tier": "core",

View File

@@ -1,7 +1,7 @@
{
"id": "cursor",
"role": "runtime",
"version": "1.6.0-rc.3",
"version": "1.6.0",
"title": "Cursor",
"description": "Cursor IDE — skills + converted commands artifact layout; hooks.json surface; Claude hook event dialect; recursive skill loader (flat nesting); tier-2 support.",
"tier": "core",

View File

@@ -1,7 +1,7 @@
{
"id": "drift",
"role": "feature",
"version": "1.6.0-rc.3",
"version": "1.6.0",
"title": "Drift detection gates",
"description": "Drift detection gates for the planning loop. At execute:wave:post: a blocking schema drift gate (detects schema files changed without a database push) and a non-blocking codebase drift gate (detects structural additions not reflected in STRUCTURE.md). At plan:pre: a non-blocking, warn-only codebase drift gate (gated on workflow.plan_drift_precheck) that flags a stale codebase map before planning, so plans are authored against a fresh STRUCTURE.md instead of discovering drift mid-execution.",
"tier": "full",

View File

@@ -1,7 +1,7 @@
{
"id": "gap-analysis",
"role": "feature",
"version": "1.6.0-rc.3",
"version": "1.6.0",
"title": "Post-planning gap analysis",
"description": "Proactive, non-blocking post-planning coverage report. After all PLAN.md files are generated, cross-references every REQ-ID and D-ID from REQUIREMENTS.md and CONTEXT.md against plan bodies. Emits a Source | Item | Status table. Does not block phase advancement.",
"tier": "standard",

View File

@@ -1,7 +1,7 @@
{
"id": "gemini",
"role": "runtime",
"version": "1.6.0-rc.3",
"version": "1.6.0",
"title": "Gemini CLI",
"description": "Google Gemini CLI — commands-only artifact layout (TOML); Gemini hook event dialect; settings-json hook surface; tier-2 support.",
"tier": "core",

View File

@@ -1,7 +1,7 @@
{
"id": "graphify",
"role": "feature",
"version": "1.6.0-rc.3",
"version": "1.6.0",
"title": "Knowledge graph",
"description": "Build, query, and inspect the project knowledge graph in `.planning/graphs/`; exposes graphify CLI subcommands (build, query, status, diff) and the /gsd-graphify skill.",
"tier": "full",

View File

@@ -1,7 +1,7 @@
{
"id": "hermes",
"role": "runtime",
"version": "1.6.0-rc.3",
"version": "1.6.0",
"title": "Hermes Agent",
"description": "Hermes Agent (NousResearch) — skills nest under skills/gsd/ category bucket; nested skill layout; settings-json hook surface; Claude hook event dialect; tier-2 support.",
"tier": "core",

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