From d0bf2c516568746401351af22ffb12615e1f23f8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 6 Sep 2026 02:09:28 +0000 Subject: [PATCH 1/2] chore: finalize v1.13.0 --- .claude-plugin/marketplace.json | 2 +- .claude-plugin/plugin.json | 2 +- capabilities/ai-integration/capability.json | 2 +- capabilities/antigravity/capability.json | 2 +- capabilities/assumption-delta/capability.json | 2 +- capabilities/audit/capability.json | 2 +- capabilities/augment/capability.json | 2 +- capabilities/broken-windows/capability.json | 2 +- .../claude-orchestration/capability.json | 2 +- capabilities/claude/capability.json | 2 +- capabilities/cline/capability.json | 2 +- capabilities/code-review/capability.json | 2 +- capabilities/codebuddy/capability.json | 2 +- capabilities/coderabbit/capability.json | 2 +- capabilities/codex/capability.json | 2 +- capabilities/copilot/capability.json | 2 +- capabilities/cursor/capability.json | 2 +- capabilities/drift/capability.json | 2 +- capabilities/external-job/capability.json | 2 +- capabilities/gap-analysis/capability.json | 2 +- capabilities/gemini/capability.json | 2 +- capabilities/graphify/capability.json | 2 +- capabilities/hermes/capability.json | 2 +- capabilities/intel/capability.json | 2 +- capabilities/kilo/capability.json | 2 +- capabilities/kimi-code/capability.json | 2 +- capabilities/kimi/capability.json | 2 +- capabilities/live-dom-uat/capability.json | 2 +- capabilities/llama-cpp/capability.json | 2 +- capabilities/lm-studio/capability.json | 2 +- capabilities/mempalace/capability.json | 2 +- capabilities/nyquist/capability.json | 2 +- capabilities/ollama/capability.json | 2 +- capabilities/opencode/capability.json | 2 +- capabilities/pattern-mapper/capability.json | 2 +- capabilities/pi/capability.json | 2 +- capabilities/profile-pipeline/capability.json | 2 +- capabilities/qwen/capability.json | 2 +- capabilities/refactor-trigger/capability.json | 2 +- capabilities/research/capability.json | 2 +- capabilities/schema-gate/capability.json | 2 +- capabilities/security/capability.json | 2 +- capabilities/tdd/capability.json | 2 +- capabilities/trae/capability.json | 2 +- capabilities/ui/capability.json | 2 +- capabilities/vscode/capability.json | 2 +- capabilities/windsurf/capability.json | 2 +- capabilities/zcode/capability.json | 2 +- gsd-core/bin/lib/capability-registry.cjs | 130 +++++++++--------- package-lock.json | 4 +- package.json | 2 +- vscode/package.json | 2 +- 52 files changed, 117 insertions(+), 117 deletions(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 5f64ca67e..5dda4c795 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -9,7 +9,7 @@ { "name": "gsd-core", "description": "GSD Core is a meta-prompting, context engineering, and spec-driven development system for AI coding agents.", - "version": "1.12.0", + "version": "1.13.0", "source": "./", "author": { "name": "open-gsd", diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 2357ac945..a6ecbf90e 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "gsd-core", "displayName": "GSD Core", - "version": "1.12.0", + "version": "1.13.0", "description": "GSD Core is a meta-prompting, context engineering, and spec-driven development system for AI coding agents.", "author": { "name": "open-gsd", diff --git a/capabilities/ai-integration/capability.json b/capabilities/ai-integration/capability.json index 62097466c..086bab607 100644 --- a/capabilities/ai-integration/capability.json +++ b/capabilities/ai-integration/capability.json @@ -1,7 +1,7 @@ { "id": "ai-integration", "role": "feature", - "version": "1.12.0", + "version": "1.13.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", diff --git a/capabilities/antigravity/capability.json b/capabilities/antigravity/capability.json index 269beeb99..2b685fe93 100644 --- a/capabilities/antigravity/capability.json +++ b/capabilities/antigravity/capability.json @@ -1,7 +1,7 @@ { "id": "antigravity", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "Antigravity", "description": "Google Antigravity IDE — config/settings home nested under ~/.gemini/antigravity (probed across 1.x and 2.x layouts); global skills/agents install under ~/.gemini/config, the dir AGY scans for global discovery (#3738); Gemini hook event dialect; flat skill layout; tier-1 support.", "tier": "core", diff --git a/capabilities/assumption-delta/capability.json b/capabilities/assumption-delta/capability.json index 1428b2c7b..b21f54670 100644 --- a/capabilities/assumption-delta/capability.json +++ b/capabilities/assumption-delta/capability.json @@ -1,7 +1,7 @@ { "id": "assumption-delta", "role": "feature", - "version": "1.12.0", + "version": "1.13.0", "title": "Assumption-delta architecture checkpoint", "description": "Rarely-firing advisory checkpoint that triggers when a phase makes something plural, optional, or chosen that used to be singular, required, or derived. Surfaces one identity-model question (promote the new general representation to primary, or add it alongside?) so a silent primary-key drift does not accumulate into a later user-facing bug. Non-blocking; fires only on a detected signal.", "tier": "full", diff --git a/capabilities/audit/capability.json b/capabilities/audit/capability.json index 6272d2334..010dd4324 100644 --- a/capabilities/audit/capability.json +++ b/capabilities/audit/capability.json @@ -1,7 +1,7 @@ { "id": "audit", "role": "feature", - "version": "1.12.0", + "version": "1.13.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", diff --git a/capabilities/augment/capability.json b/capabilities/augment/capability.json index 012d14296..061e742fe 100644 --- a/capabilities/augment/capability.json +++ b/capabilities/augment/capability.json @@ -1,7 +1,7 @@ { "id": "augment", "role": "runtime", - "version": "1.12.0", + "version": "1.13.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", diff --git a/capabilities/broken-windows/capability.json b/capabilities/broken-windows/capability.json index bc2668904..3b4508cb0 100644 --- a/capabilities/broken-windows/capability.json +++ b/capabilities/broken-windows/capability.json @@ -1,7 +1,7 @@ { "id": "broken-windows", "role": "feature", - "version": "1.12.0", + "version": "1.13.0", "title": "Broken-windows ledger", "description": "Cross-phase defect register accumulating stubs, TODOs, skipped tests, unrun verifies, and unmet truths into .planning/WINDOWS.md. When enforcement is enabled, it blocks /gsd-ship while any window is open unless explicitly waived with a recorded reason. Operationalizes GSD's no-defer discipline as a tracked artifact (issue #1950).", "tier": "full", diff --git a/capabilities/claude-orchestration/capability.json b/capabilities/claude-orchestration/capability.json index 02f29e528..059019b31 100644 --- a/capabilities/claude-orchestration/capability.json +++ b/capabilities/claude-orchestration/capability.json @@ -1,7 +1,7 @@ { "id": "claude-orchestration", "role": "feature", - "version": "1.12.0", + "version": "1.13.0", "title": "Claude orchestration (Workflow backend)", "description": "Default-off, BETA, claude-only capability that adopts Claude Code's Workflow tool (the engine behind /effort ultracode) as an optional parallel-execution backend for the GSD loop. When the runtime exposes the Workflow tool and claude_orchestration.execution_backend resolves to 'workflow', execute-phase emits a generated Workflow script (waves -> parallel() barriers, plans -> agent({ agentType: 'gsd-executor', isolation: 'worktree' }), files_modified overlap -> separate sequential stages, resumeFromRunId wired to the phase run id, shared token budget) that composes the SAME gsd-executor agent and worktree isolation the inline path uses, restoring the wave parallelism the #853 backgrounded-agent nesting limitation forces inline on Claude Code. (The plan-checker and verifier remain inline until separately wired — this capability delivers the parallel-execution backend, not those gates.) Also folds the ultraplan plan-offload under one runtime gate (plan:* surface). On any runtime lacking the Workflow tool, or when the capability is disabled, behaviour is byte-identical to today (inline/manual dispatch). Detection + emission live in gsd-core/bin/lib/claude-orchestration.cjs (pure, fail-closed). Mirrors the existing gsd-ultraplan-phase BETA-isolation posture.", "tier": "full", diff --git a/capabilities/claude/capability.json b/capabilities/claude/capability.json index b73233255..8b6d6d947 100644 --- a/capabilities/claude/capability.json +++ b/capabilities/claude/capability.json @@ -1,7 +1,7 @@ { "id": "claude", "role": "runtime", - "version": "1.12.0", + "version": "1.13.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", diff --git a/capabilities/cline/capability.json b/capabilities/cline/capability.json index b17f19375..6e1e4bef9 100644 --- a/capabilities/cline/capability.json +++ b/capabilities/cline/capability.json @@ -1,7 +1,7 @@ { "id": "cline", "role": "runtime", - "version": "1.12.0", + "version": "1.13.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", diff --git a/capabilities/code-review/capability.json b/capabilities/code-review/capability.json index 1857a8a07..77c988f9b 100644 --- a/capabilities/code-review/capability.json +++ b/capabilities/code-review/capability.json @@ -1,7 +1,7 @@ { "id": "code-review", "role": "feature", - "version": "1.12.0", + "version": "1.13.0", "title": "Code review", "description": "Source-file code review and review-fix workflow support for completed execution work.", "tier": "full", diff --git a/capabilities/codebuddy/capability.json b/capabilities/codebuddy/capability.json index 6d43e72e3..c37ed61fb 100644 --- a/capabilities/codebuddy/capability.json +++ b/capabilities/codebuddy/capability.json @@ -1,7 +1,7 @@ { "id": "codebuddy", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "CodeBuddy", "description": "CodeBuddy (Tencent) — converted commands + skills artifact layout; settings-json hook surface; Claude hook event dialect; tier-2 support.", "tier": "core", diff --git a/capabilities/coderabbit/capability.json b/capabilities/coderabbit/capability.json index 70c49949a..c1b3801d8 100644 --- a/capabilities/coderabbit/capability.json +++ b/capabilities/coderabbit/capability.json @@ -1,7 +1,7 @@ { "id": "coderabbit", "role": "reviewer", - "version": "1.12.0", + "version": "1.13.0", "title": "CodeRabbit", "description": "CodeRabbit CLI — cross-AI /gsd:review reviewer lane only; not a GSD install target (no runtime body, no artifacts). Reviews the working-tree diff (`coderabbit review --prompt-only`), not the source tree, and accepts neither a prompt nor a model flag; findings are down-weighted in consensus (evidenceClass: diff-only).", "tier": "full", diff --git a/capabilities/codex/capability.json b/capabilities/codex/capability.json index 487d1304d..71bcd1f53 100644 --- a/capabilities/codex/capability.json +++ b/capabilities/codex/capability.json @@ -1,7 +1,7 @@ { "id": "codex", "role": "runtime", - "version": "1.12.0", + "version": "1.13.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", diff --git a/capabilities/copilot/capability.json b/capabilities/copilot/capability.json index 87ccba1a9..e4fd59a81 100644 --- a/capabilities/copilot/capability.json +++ b/capabilities/copilot/capability.json @@ -1,7 +1,7 @@ { "id": "copilot", "role": "runtime", - "version": "1.12.0", + "version": "1.13.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", diff --git a/capabilities/cursor/capability.json b/capabilities/cursor/capability.json index f862d6b55..23f1a92f3 100644 --- a/capabilities/cursor/capability.json +++ b/capabilities/cursor/capability.json @@ -1,7 +1,7 @@ { "id": "cursor", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "Cursor", "description": "Cursor IDE — skills-only workflow surface; hooks.json surface; Claude hook event dialect; recursive skill loader (flat nesting); tier-2 support.", "tier": "core", diff --git a/capabilities/drift/capability.json b/capabilities/drift/capability.json index fae5dfe7d..49432f59c 100644 --- a/capabilities/drift/capability.json +++ b/capabilities/drift/capability.json @@ -1,7 +1,7 @@ { "id": "drift", "role": "feature", - "version": "1.12.0", + "version": "1.13.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", diff --git a/capabilities/external-job/capability.json b/capabilities/external-job/capability.json index 5a7c12363..8e5529a54 100644 --- a/capabilities/external-job/capability.json +++ b/capabilities/external-job/capability.json @@ -1,7 +1,7 @@ { "id": "external-job", "role": "feature", - "version": "1.12.0", + "version": "1.13.0", "title": "Async external-job scheduler adapter", "description": "Default-off producer of the async external-job manifest (#1164). At execute:wave:post an executor can externalize long-running compute (SLURM first, scheduler-pluggable), commit a .planning/async-jobs/.json manifest, defer SUMMARY.md, and return external_job_waiting. The core loop (#1165) consumes the manifest; this capability is the only thing that writes it. NOTE on contribution point: #1164 specifies classification at execute:wave:pre and recording at execute:wave:post. This capability still contributes executor guidance at wave:post; execute-phase now renders wave:pre entries and dispatches generic step hooks there independently. Moving external-job classification to wave:pre is a separate capability change, not part of #4148. The adapter (scripts/slurm-adapter.cjs) reads external_job.submit_timeout_ms / poll_timeout_ms / artifact_dir through the canonical capability-config seam (env override > config > registry default).", "tier": "full", diff --git a/capabilities/gap-analysis/capability.json b/capabilities/gap-analysis/capability.json index dbdd16477..62279c644 100644 --- a/capabilities/gap-analysis/capability.json +++ b/capabilities/gap-analysis/capability.json @@ -1,7 +1,7 @@ { "id": "gap-analysis", "role": "feature", - "version": "1.12.0", + "version": "1.13.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", diff --git a/capabilities/gemini/capability.json b/capabilities/gemini/capability.json index af0f4b36c..869a6b4ca 100644 --- a/capabilities/gemini/capability.json +++ b/capabilities/gemini/capability.json @@ -1,7 +1,7 @@ { "id": "gemini", "role": "reviewer", - "version": "1.12.0", + "version": "1.13.0", "title": "Gemini CLI", "description": "Google Gemini CLI — cross-AI /gsd:review reviewer lane only; not a GSD install target (no runtime body, no artifacts). Spawned as `gemini -p - -m ` with the plan piped on stdin.", "tier": "full", diff --git a/capabilities/graphify/capability.json b/capabilities/graphify/capability.json index 14ffe61db..512354376 100644 --- a/capabilities/graphify/capability.json +++ b/capabilities/graphify/capability.json @@ -1,7 +1,7 @@ { "id": "graphify", "role": "feature", - "version": "1.12.0", + "version": "1.13.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", diff --git a/capabilities/hermes/capability.json b/capabilities/hermes/capability.json index a80ae03fb..890e12998 100644 --- a/capabilities/hermes/capability.json +++ b/capabilities/hermes/capability.json @@ -1,7 +1,7 @@ { "id": "hermes", "role": "runtime", - "version": "1.12.0", + "version": "1.13.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", diff --git a/capabilities/intel/capability.json b/capabilities/intel/capability.json index 94b89cf25..9ea4743a3 100644 --- a/capabilities/intel/capability.json +++ b/capabilities/intel/capability.json @@ -1,7 +1,7 @@ { "id": "intel", "role": "feature", - "version": "1.12.0", + "version": "1.13.0", "title": "Codebase intelligence", "description": "Code-intelligence store for codebase querying, diff, snapshot, and API-surface extraction; exposes `gsd-tools intel` subcommands (query, status, update, diff, snapshot, patch-meta, validate, extract-exports, api-surface) and backs `/gsd-map-codebase` and `gsd-intel-updater`.", "tier": "full", diff --git a/capabilities/kilo/capability.json b/capabilities/kilo/capability.json index fab009328..7d0a65abe 100644 --- a/capabilities/kilo/capability.json +++ b/capabilities/kilo/capability.json @@ -1,7 +1,7 @@ { "id": "kilo", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "Kilo Code", "description": "Kilo Code — XDG-based config dir; global skills at ~/.kilo/skills (separate from XDG config); flat command/ + skills artifact layout; no lifecycle hook registration; tier-2 support.", "tier": "core", diff --git a/capabilities/kimi-code/capability.json b/capabilities/kimi-code/capability.json index d313371d6..55f610552 100644 --- a/capabilities/kimi-code/capability.json +++ b/capabilities/kimi-code/capability.json @@ -1,7 +1,7 @@ { "id": "kimi-code", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "Kimi Code CLI", "description": "Kimi Code CLI (Moonshot AI, Node) — Agent Skills auto-discovered at ~/.kimi-code/skills; global AGENTS.md at ~/.kimi-code/AGENTS.md; native config.toml + [[hooks]] bus; three built-in subagents (coder/explore/plan), NO custom named subagents; background dispatch; tier-2 support. Distinct from Python kimi-cli (the 'kimi' capability) per ADR-1239 EoS — Kimi Code cannot dispatch named subagents so the kimi-agents YAML layout does NOT apply; persona injection rides the existing ${AGENT_SKILLS_*} workflow fallback. Install-layout, agent-install-check, and install-time decision (kimi vs kimi-code) land in follow-up PRs; this descriptor is the EoS foundation.", "tier": "core", diff --git a/capabilities/kimi/capability.json b/capabilities/kimi/capability.json index f2f07c550..c19387e89 100644 --- a/capabilities/kimi/capability.json +++ b/capabilities/kimi/capability.json @@ -1,7 +1,7 @@ { "id": "kimi", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "Kimi CLI", "description": "Kimi CLI (Moonshot AI) — generic agents root at ~/.config/agents; skills + kimi-agents artifact layout; native config.toml [[hooks]] bus at ~/.kimi/config.toml; background dispatch; tier-2 support.", "tier": "core", diff --git a/capabilities/live-dom-uat/capability.json b/capabilities/live-dom-uat/capability.json index 272c21742..5332493a4 100644 --- a/capabilities/live-dom-uat/capability.json +++ b/capabilities/live-dom-uat/capability.json @@ -1,7 +1,7 @@ { "id": "live-dom-uat", "role": "feature", - "version": "1.12.0", + "version": "1.13.0", "title": "Live-DOM UAT", "description": "Default-off live-DOM verification (#2856). Confines browser MCP reach to one purpose-built agent (gsd-dom-verifier) that carries the browser globs in its own tools: line, registered as an additive step hook at execute:wave:post. agents/gsd-executor.md is deliberately NOT widened: for a first-party agent the static tool list is the only control that exists, no capability can grant tools to one (ADR-1244 D2), no hook kind grants tool permissions (ADR-857 D4), and there is no per-dispatch tool override. Gated by activationKey workflow.live_dom_uat (default false), so with the key off the capability resolves inactive and the hook does not render at all. NOTE on the browser profile lock: chrome-devtools-mcp holds an exclusive lock on $HOME/.cache/chrome-devtools-mcp/chrome-profile, and --isolated is a flag on the user's own MCP-server registration that GSD cannot pass. Concurrent execution waves sharing one profile will therefore collide; the step tolerates and reports that (onError: skip, never blocking) rather than pretending to coordinate a resource it does not own.", "tier": "full", diff --git a/capabilities/llama-cpp/capability.json b/capabilities/llama-cpp/capability.json index 9f8c03bbb..419b901bb 100644 --- a/capabilities/llama-cpp/capability.json +++ b/capabilities/llama-cpp/capability.json @@ -1,7 +1,7 @@ { "id": "llama-cpp", "role": "reviewer", - "version": "1.12.0", + "version": "1.13.0", "title": "llama.cpp", "description": "llama.cpp server — cross-AI /gsd:review reviewer lane only; not a GSD install target (no runtime body, no artifacts). OpenAI-compatible HTTP transport against a user-configured `review.llama_cpp_host` (POST /v1/chat/completions); model discovered via GET /v1/models piped through jq. Capability id/folder are kebab (`llama-cpp`, required by KEBAB_RE); `reviewer.slug` stays snake (`llama_cpp`) to match the shipped roster and the `review.llama_cpp_host` config key (ADR-2782's three-namespace trap).", "tier": "full", diff --git a/capabilities/lm-studio/capability.json b/capabilities/lm-studio/capability.json index c2ff8647c..fe43cfb67 100644 --- a/capabilities/lm-studio/capability.json +++ b/capabilities/lm-studio/capability.json @@ -1,7 +1,7 @@ { "id": "lm-studio", "role": "reviewer", - "version": "1.12.0", + "version": "1.13.0", "title": "LM Studio", "description": "LM Studio local model server — cross-AI /gsd:review reviewer lane only; not a GSD install target (no runtime body, no artifacts). OpenAI-compatible HTTP transport against a user-configured `review.lm_studio_host` (POST /v1/chat/completions); model discovered via GET /v1/models piped through jq. Capability id/folder are kebab (`lm-studio`, required by KEBAB_RE); `reviewer.slug` stays snake (`lm_studio`) to match the shipped roster and the `review.lm_studio_host` config key (ADR-2782's three-namespace trap).", "tier": "full", diff --git a/capabilities/mempalace/capability.json b/capabilities/mempalace/capability.json index 8c929be0f..9741939cc 100644 --- a/capabilities/mempalace/capability.json +++ b/capabilities/mempalace/capability.json @@ -1,7 +1,7 @@ { "id": "mempalace", "role": "feature", - "version": "1.12.0", + "version": "1.13.0", "title": "MemPalace memory", "description": "Cross-session, cross-project memory: deliberate recall before discuss/plan and verbatim capture + temporal-KG sync at phase boundaries, via the MemPalace MCP server and CLI.", "tier": "full", diff --git a/capabilities/nyquist/capability.json b/capabilities/nyquist/capability.json index c8c2a283c..0fdc80f60 100644 --- a/capabilities/nyquist/capability.json +++ b/capabilities/nyquist/capability.json @@ -1,7 +1,7 @@ { "id": "nyquist", "role": "feature", - "version": "1.12.0", + "version": "1.13.0", "title": "Nyquist validation", "description": "Validation coverage audit that maps executed work back to tests and manual-only evidence.", "tier": "full", diff --git a/capabilities/ollama/capability.json b/capabilities/ollama/capability.json index 460c0cf75..8444f2ea2 100644 --- a/capabilities/ollama/capability.json +++ b/capabilities/ollama/capability.json @@ -1,7 +1,7 @@ { "id": "ollama", "role": "reviewer", - "version": "1.12.0", + "version": "1.13.0", "title": "Ollama", "description": "Ollama local model server — cross-AI /gsd:review reviewer lane only; not a GSD install target (no runtime body, no artifacts). OpenAI-compatible HTTP transport against a user-configured `review.ollama_host` (POST /v1/chat/completions); model discovered via GET /v1/models piped through jq.", "tier": "full", diff --git a/capabilities/opencode/capability.json b/capabilities/opencode/capability.json index 22e2ed158..3930324de 100644 --- a/capabilities/opencode/capability.json +++ b/capabilities/opencode/capability.json @@ -1,7 +1,7 @@ { "id": "opencode", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "OpenCode", "description": "OpenCode — XDG-based config dir; flat commands/ + skills artifact layout; settings-json config format; no lifecycle hook registration; tier-2 support.", "tier": "core", diff --git a/capabilities/pattern-mapper/capability.json b/capabilities/pattern-mapper/capability.json index 54ff772b5..670797b69 100644 --- a/capabilities/pattern-mapper/capability.json +++ b/capabilities/pattern-mapper/capability.json @@ -1,7 +1,7 @@ { "id": "pattern-mapper", "role": "feature", - "version": "1.12.0", + "version": "1.13.0", "title": "Pattern mapping", "description": "Optional codebase-pattern mapping before planning; owns the pattern mapper agent and workflow.pattern_mapper activation key.", "tier": "full", diff --git a/capabilities/pi/capability.json b/capabilities/pi/capability.json index e2ea1d30f..543129846 100644 --- a/capabilities/pi/capability.json +++ b/capabilities/pi/capability.json @@ -1,7 +1,7 @@ { "id": "pi", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "pi", "description": "pi (pi.dev) — bun-runtime programmatic-CLI; TS ExtensionAPI (registerCommand/registerTool/registerProvider/pi.on); single native-extension file at ~/.pi/agent/extensions/gsd.js (.js, not .cjs — pi's extension auto-discovery accepts only .ts/.js, #2470); no shared-settings hook surface; tier-2 support.", "tier": "core", diff --git a/capabilities/profile-pipeline/capability.json b/capabilities/profile-pipeline/capability.json index d0fdafa35..55d5a796f 100644 --- a/capabilities/profile-pipeline/capability.json +++ b/capabilities/profile-pipeline/capability.json @@ -1,7 +1,7 @@ { "id": "profile-pipeline", "role": "feature", - "version": "1.12.0", + "version": "1.13.0", "title": "Developer profiling pipeline", "description": "Developer behavioral profiling from Claude Code session history; scans session JSONL files, extracts and samples user messages, and generates profile artifacts (USER-PROFILE.md, dev-preferences.md, CLAUDE.md sections). Exposes eight `gsd-tools` commands: scan-sessions, extract-messages, profile-sample (pipeline phase) and write-profile, profile-questionnaire, generate-dev-preferences, generate-claude-profile, generate-claude-md (output phase). Backs the /gsd-profile-user skill and gsd-user-profiler agent.", "tier": "full", diff --git a/capabilities/qwen/capability.json b/capabilities/qwen/capability.json index 07ef831c6..75eb5fd52 100644 --- a/capabilities/qwen/capability.json +++ b/capabilities/qwen/capability.json @@ -1,7 +1,7 @@ { "id": "qwen", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "Qwen Code", "description": "Qwen Code (Alibaba) — nested-skill artifact layout; settings-json hook surface; Claude hook event dialect; tier-2 support.", "tier": "core", diff --git a/capabilities/refactor-trigger/capability.json b/capabilities/refactor-trigger/capability.json index 72deb19c7..3422cbabe 100644 --- a/capabilities/refactor-trigger/capability.json +++ b/capabilities/refactor-trigger/capability.json @@ -1,7 +1,7 @@ { "id": "refactor-trigger", "role": "feature", - "version": "1.12.0", + "version": "1.13.0", "title": "Complexity-triggered refactor", "description": "Measures the complexity of the code a phase touched and, when a function crosses a configured threshold or jumps past its recorded anchor, surfaces a scoped refactor proposal at .planning/phases//-REFACTOR.md. Advisory by default — it never edits code and never blocks. Opt-in strict mode blocks /gsd-ship while a proposal is untriaged; a declined proposal is recorded in the broken-windows ledger when that capability is present. Operationalizes 'refactor early, refactor often' as continuous pressure instead of a thing you have to remember (issue #1953).", "tier": "full", diff --git a/capabilities/research/capability.json b/capabilities/research/capability.json index 20b3a983f..9162e9331 100644 --- a/capabilities/research/capability.json +++ b/capabilities/research/capability.json @@ -1,7 +1,7 @@ { "id": "research", "role": "feature", - "version": "1.12.0", + "version": "1.13.0", "title": "Phase research", "description": "Optional phase research before planning; owns the phase researcher agent and workflow.research activation key.", "tier": "standard", diff --git a/capabilities/schema-gate/capability.json b/capabilities/schema-gate/capability.json index ed8f7ff77..c6ea90908 100644 --- a/capabilities/schema-gate/capability.json +++ b/capabilities/schema-gate/capability.json @@ -1,7 +1,7 @@ { "id": "schema-gate", "role": "feature", - "version": "1.12.0", + "version": "1.13.0", "title": "Schema push detection gate", "description": "Detects ORM schema-relevant files in the phase scope during planning and injects a mandatory [BLOCKING] schema push task into the plan. Prevents false-positive verification where build/types pass because TypeScript types come from config, not the live database.", "tier": "full", diff --git a/capabilities/security/capability.json b/capabilities/security/capability.json index 7aa4abd4b..a79560dce 100644 --- a/capabilities/security/capability.json +++ b/capabilities/security/capability.json @@ -1,7 +1,7 @@ { "id": "security", "role": "feature", - "version": "1.12.0", + "version": "1.13.0", "title": "Security enforcement", "description": "Threat mitigation verification and ship-time security blocking for phases with security enforcement enabled.", "tier": "full", diff --git a/capabilities/tdd/capability.json b/capabilities/tdd/capability.json index 3dba7e1d7..6296508dc 100644 --- a/capabilities/tdd/capability.json +++ b/capabilities/tdd/capability.json @@ -1,7 +1,7 @@ { "id": "tdd", "role": "feature", - "version": "1.12.0", + "version": "1.13.0", "title": "Test-driven development", "description": "Injects TDD heuristics into the planner and enforces RED/GREEN gate compliance on type:tdd plans after execution. Owns workflow.tdd_mode; the --tdd CLI flag is the ephemeral override.", "tier": "full", diff --git a/capabilities/trae/capability.json b/capabilities/trae/capability.json index 7b52deee8..1aa36ba33 100644 --- a/capabilities/trae/capability.json +++ b/capabilities/trae/capability.json @@ -1,7 +1,7 @@ { "id": "trae", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "Trae IDE", "description": "Trae IDE — nested-skill artifact layout; no hook surface (profile-marker-only config); tier-2 support.", "tier": "core", diff --git a/capabilities/ui/capability.json b/capabilities/ui/capability.json index b42e610cb..c84639e9a 100644 --- a/capabilities/ui/capability.json +++ b/capabilities/ui/capability.json @@ -1,7 +1,7 @@ { "id": "ui", "role": "feature", - "version": "1.12.0", + "version": "1.13.0", "title": "UI design contracts", "description": "UI-SPEC design contract + retrospective UI audit for frontend phases.", "tier": "full", diff --git a/capabilities/vscode/capability.json b/capabilities/vscode/capability.json index 2e4c23d25..1197fa4d5 100644 --- a/capabilities/vscode/capability.json +++ b/capabilities/vscode/capability.json @@ -1,7 +1,7 @@ { "id": "vscode", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "VS Code", "description": "VS Code — Marketplace/VSIX extension; no file-projected config directory; IDE-profile reference host (active vscode.lm model, engine-owned hook bus, sandboxed globalState/workspaceState stateIO).", "tier": "core", diff --git a/capabilities/windsurf/capability.json b/capabilities/windsurf/capability.json index 494a7794e..de376d8da 100644 --- a/capabilities/windsurf/capability.json +++ b/capabilities/windsurf/capability.json @@ -1,7 +1,7 @@ { "id": "windsurf", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "Windsurf", "description": "Windsurf (Codeium) — workspace workflow artifact layout for slash commands; Cascade native hooks.json blocking hook bus (pre_write_code, pre_run_command); tier-2 support.", "tier": "core", diff --git a/capabilities/zcode/capability.json b/capabilities/zcode/capability.json index 511027d11..32514694e 100644 --- a/capabilities/zcode/capability.json +++ b/capabilities/zcode/capability.json @@ -1,7 +1,7 @@ { "id": "zcode", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "ZCode", "description": "ZCode (Z.ai) — desktop Agentic Development Environment for GLM-5.2; Claude-shaped nested skills at ~/.zcode/skills//SKILL.md, slash commands, named subagents, native MCP; declarative plugin surface; profile-marker install; tier-2 community support.", "tier": "core", diff --git a/gsd-core/bin/lib/capability-registry.cjs b/gsd-core/bin/lib/capability-registry.cjs index 338372f8c..05c338919 100644 --- a/gsd-core/bin/lib/capability-registry.cjs +++ b/gsd-core/bin/lib/capability-registry.cjs @@ -10,7 +10,7 @@ const capabilities = { "ai-integration": { "id": "ai-integration", "role": "feature", - "version": "1.12.0", + "version": "1.13.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", @@ -95,7 +95,7 @@ const capabilities = { "antigravity": { "id": "antigravity", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "Antigravity", "description": "Google Antigravity IDE — config/settings home nested under ~/.gemini/antigravity (probed across 1.x and 2.x layouts); global skills/agents install under ~/.gemini/config, the dir AGY scans for global discovery (#3738); Gemini hook event dialect; flat skill layout; tier-1 support.", "tier": "core", @@ -258,7 +258,7 @@ const capabilities = { "assumption-delta": { "id": "assumption-delta", "role": "feature", - "version": "1.12.0", + "version": "1.13.0", "title": "Assumption-delta architecture checkpoint", "description": "Rarely-firing advisory checkpoint that triggers when a phase makes something plural, optional, or chosen that used to be singular, required, or derived. Surfaces one identity-model question (promote the new general representation to primary, or add it alongside?) so a silent primary-key drift does not accumulate into a later user-facing bug. Non-blocking; fires only on a detected signal.", "tier": "full", @@ -304,7 +304,7 @@ const capabilities = { "audit": { "id": "audit", "role": "feature", - "version": "1.12.0", + "version": "1.13.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", @@ -341,7 +341,7 @@ const capabilities = { "augment": { "id": "augment", "role": "runtime", - "version": "1.12.0", + "version": "1.13.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", @@ -455,7 +455,7 @@ const capabilities = { "broken-windows": { "id": "broken-windows", "role": "feature", - "version": "1.12.0", + "version": "1.13.0", "title": "Broken-windows ledger", "description": "Cross-phase defect register accumulating stubs, TODOs, skipped tests, unrun verifies, and unmet truths into .planning/WINDOWS.md. When enforcement is enabled, it blocks /gsd-ship while any window is open unless explicitly waived with a recorded reason. Operationalizes GSD's no-defer discipline as a tracked artifact (issue #1950).", "tier": "full", @@ -501,7 +501,7 @@ const capabilities = { "claude": { "id": "claude", "role": "runtime", - "version": "1.12.0", + "version": "1.13.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", @@ -682,7 +682,7 @@ const capabilities = { "claude-orchestration": { "id": "claude-orchestration", "role": "feature", - "version": "1.12.0", + "version": "1.13.0", "title": "Claude orchestration (Workflow backend)", "description": "Default-off, BETA, claude-only capability that adopts Claude Code's Workflow tool (the engine behind /effort ultracode) as an optional parallel-execution backend for the GSD loop. When the runtime exposes the Workflow tool and claude_orchestration.execution_backend resolves to 'workflow', execute-phase emits a generated Workflow script (waves -> parallel() barriers, plans -> agent({ agentType: 'gsd-executor', isolation: 'worktree' }), files_modified overlap -> separate sequential stages, resumeFromRunId wired to the phase run id, shared token budget) that composes the SAME gsd-executor agent and worktree isolation the inline path uses, restoring the wave parallelism the #853 backgrounded-agent nesting limitation forces inline on Claude Code. (The plan-checker and verifier remain inline until separately wired — this capability delivers the parallel-execution backend, not those gates.) Also folds the ultraplan plan-offload under one runtime gate (plan:* surface). On any runtime lacking the Workflow tool, or when the capability is disabled, behaviour is byte-identical to today (inline/manual dispatch). Detection + emission live in gsd-core/bin/lib/claude-orchestration.cjs (pure, fail-closed). Mirrors the existing gsd-ultraplan-phase BETA-isolation posture.", "tier": "full", @@ -770,7 +770,7 @@ const capabilities = { "cline": { "id": "cline", "role": "runtime", - "version": "1.12.0", + "version": "1.13.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", @@ -863,7 +863,7 @@ const capabilities = { "code-review": { "id": "code-review", "role": "feature", - "version": "1.12.0", + "version": "1.13.0", "title": "Code review", "description": "Source-file code review and review-fix workflow support for completed execution work.", "tier": "full", @@ -947,7 +947,7 @@ const capabilities = { "codebuddy": { "id": "codebuddy", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "CodeBuddy", "description": "CodeBuddy (Tencent) — converted commands + skills artifact layout; settings-json hook surface; Claude hook event dialect; tier-2 support.", "tier": "core", @@ -1065,7 +1065,7 @@ const capabilities = { "coderabbit": { "id": "coderabbit", "role": "reviewer", - "version": "1.12.0", + "version": "1.13.0", "title": "CodeRabbit", "description": "CodeRabbit CLI — cross-AI /gsd:review reviewer lane only; not a GSD install target (no runtime body, no artifacts). Reviews the working-tree diff (`coderabbit review --prompt-only`), not the source tree, and accepts neither a prompt nor a model flag; findings are down-weighted in consensus (evidenceClass: diff-only).", "tier": "full", @@ -1117,7 +1117,7 @@ const capabilities = { "codex": { "id": "codex", "role": "runtime", - "version": "1.12.0", + "version": "1.13.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", @@ -1293,7 +1293,7 @@ const capabilities = { "copilot": { "id": "copilot", "role": "runtime", - "version": "1.12.0", + "version": "1.13.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", @@ -1393,7 +1393,7 @@ const capabilities = { "cursor": { "id": "cursor", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "Cursor", "description": "Cursor IDE — skills-only workflow surface; hooks.json surface; Claude hook event dialect; recursive skill loader (flat nesting); tier-2 support.", "tier": "core", @@ -1562,7 +1562,7 @@ const capabilities = { "drift": { "id": "drift", "role": "feature", - "version": "1.12.0", + "version": "1.13.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", @@ -1663,7 +1663,7 @@ const capabilities = { "external-job": { "id": "external-job", "role": "feature", - "version": "1.12.0", + "version": "1.13.0", "title": "Async external-job scheduler adapter", "description": "Default-off producer of the async external-job manifest (#1164). At execute:wave:post an executor can externalize long-running compute (SLURM first, scheduler-pluggable), commit a .planning/async-jobs/.json manifest, defer SUMMARY.md, and return external_job_waiting. The core loop (#1165) consumes the manifest; this capability is the only thing that writes it. NOTE on contribution point: #1164 specifies classification at execute:wave:pre and recording at execute:wave:post. This capability still contributes executor guidance at wave:post; execute-phase now renders wave:pre entries and dispatches generic step hooks there independently. Moving external-job classification to wave:pre is a separate capability change, not part of #4148. The adapter (scripts/slurm-adapter.cjs) reads external_job.submit_timeout_ms / poll_timeout_ms / artifact_dir through the canonical capability-config seam (env override > config > registry default).", "tier": "full", @@ -1746,7 +1746,7 @@ const capabilities = { "gap-analysis": { "id": "gap-analysis", "role": "feature", - "version": "1.12.0", + "version": "1.13.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", @@ -1787,7 +1787,7 @@ const capabilities = { "gemini": { "id": "gemini", "role": "reviewer", - "version": "1.12.0", + "version": "1.13.0", "title": "Gemini CLI", "description": "Google Gemini CLI — cross-AI /gsd:review reviewer lane only; not a GSD install target (no runtime body, no artifacts). Spawned as `gemini -p - -m ` with the plan piped on stdin.", "tier": "full", @@ -1850,7 +1850,7 @@ const capabilities = { "graphify": { "id": "graphify", "role": "feature", - "version": "1.12.0", + "version": "1.13.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", @@ -1891,7 +1891,7 @@ const capabilities = { "hermes": { "id": "hermes", "role": "runtime", - "version": "1.12.0", + "version": "1.13.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", @@ -2003,7 +2003,7 @@ const capabilities = { "intel": { "id": "intel", "role": "feature", - "version": "1.12.0", + "version": "1.13.0", "title": "Codebase intelligence", "description": "Code-intelligence store for codebase querying, diff, snapshot, and API-surface extraction; exposes `gsd-tools intel` subcommands (query, status, update, diff, snapshot, patch-meta, validate, extract-exports, api-surface) and backs `/gsd-map-codebase` and `gsd-intel-updater`.", "tier": "full", @@ -2055,7 +2055,7 @@ const capabilities = { "kilo": { "id": "kilo", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "Kilo Code", "description": "Kilo Code — XDG-based config dir; global skills at ~/.kilo/skills (separate from XDG config); flat command/ + skills artifact layout; no lifecycle hook registration; tier-2 support.", "tier": "core", @@ -2185,7 +2185,7 @@ const capabilities = { "kimi": { "id": "kimi", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "Kimi CLI", "description": "Kimi CLI (Moonshot AI) — generic agents root at ~/.config/agents; skills + kimi-agents artifact layout; native config.toml [[hooks]] bus at ~/.kimi/config.toml; background dispatch; tier-2 support.", "tier": "core", @@ -2289,7 +2289,7 @@ const capabilities = { "kimi-code": { "id": "kimi-code", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "Kimi Code CLI", "description": "Kimi Code CLI (Moonshot AI, Node) — Agent Skills auto-discovered at ~/.kimi-code/skills; global AGENTS.md at ~/.kimi-code/AGENTS.md; native config.toml + [[hooks]] bus; three built-in subagents (coder/explore/plan), NO custom named subagents; background dispatch; tier-2 support. Distinct from Python kimi-cli (the 'kimi' capability) per ADR-1239 EoS — Kimi Code cannot dispatch named subagents so the kimi-agents YAML layout does NOT apply; persona injection rides the existing ${AGENT_SKILLS_*} workflow fallback. Install-layout, agent-install-check, and install-time decision (kimi vs kimi-code) land in follow-up PRs; this descriptor is the EoS foundation.", "tier": "core", @@ -2456,7 +2456,7 @@ const capabilities = { "live-dom-uat": { "id": "live-dom-uat", "role": "feature", - "version": "1.12.0", + "version": "1.13.0", "title": "Live-DOM UAT", "description": "Default-off live-DOM verification (#2856). Confines browser MCP reach to one purpose-built agent (gsd-dom-verifier) that carries the browser globs in its own tools: line, registered as an additive step hook at execute:wave:post. agents/gsd-executor.md is deliberately NOT widened: for a first-party agent the static tool list is the only control that exists, no capability can grant tools to one (ADR-1244 D2), no hook kind grants tool permissions (ADR-857 D4), and there is no per-dispatch tool override. Gated by activationKey workflow.live_dom_uat (default false), so with the key off the capability resolves inactive and the hook does not render at all. NOTE on the browser profile lock: chrome-devtools-mcp holds an exclusive lock on $HOME/.cache/chrome-devtools-mcp/chrome-profile, and --isolated is a flag on the user's own MCP-server registration that GSD cannot pass. Concurrent execution waves sharing one profile will therefore collide; the step tolerates and reports that (onError: skip, never blocking) rather than pretending to coordinate a resource it does not own.", "tier": "full", @@ -2509,7 +2509,7 @@ const capabilities = { "llama-cpp": { "id": "llama-cpp", "role": "reviewer", - "version": "1.12.0", + "version": "1.13.0", "title": "llama.cpp", "description": "llama.cpp server — cross-AI /gsd:review reviewer lane only; not a GSD install target (no runtime body, no artifacts). OpenAI-compatible HTTP transport against a user-configured `review.llama_cpp_host` (POST /v1/chat/completions); model discovered via GET /v1/models piped through jq. Capability id/folder are kebab (`llama-cpp`, required by KEBAB_RE); `reviewer.slug` stays snake (`llama_cpp`) to match the shipped roster and the `review.llama_cpp_host` config key (ADR-2782's three-namespace trap).", "tier": "full", @@ -2575,7 +2575,7 @@ const capabilities = { "lm-studio": { "id": "lm-studio", "role": "reviewer", - "version": "1.12.0", + "version": "1.13.0", "title": "LM Studio", "description": "LM Studio local model server — cross-AI /gsd:review reviewer lane only; not a GSD install target (no runtime body, no artifacts). OpenAI-compatible HTTP transport against a user-configured `review.lm_studio_host` (POST /v1/chat/completions); model discovered via GET /v1/models piped through jq. Capability id/folder are kebab (`lm-studio`, required by KEBAB_RE); `reviewer.slug` stays snake (`lm_studio`) to match the shipped roster and the `review.lm_studio_host` config key (ADR-2782's three-namespace trap).", "tier": "full", @@ -2641,7 +2641,7 @@ const capabilities = { "mempalace": { "id": "mempalace", "role": "feature", - "version": "1.12.0", + "version": "1.13.0", "title": "MemPalace memory", "description": "Cross-session, cross-project memory: deliberate recall before discuss/plan and verbatim capture + temporal-KG sync at phase boundaries, via the MemPalace MCP server and CLI.", "tier": "full", @@ -2815,7 +2815,7 @@ const capabilities = { "nyquist": { "id": "nyquist", "role": "feature", - "version": "1.12.0", + "version": "1.13.0", "title": "Nyquist validation", "description": "Validation coverage audit that maps executed work back to tests and manual-only evidence.", "tier": "full", @@ -2865,7 +2865,7 @@ const capabilities = { "ollama": { "id": "ollama", "role": "reviewer", - "version": "1.12.0", + "version": "1.13.0", "title": "Ollama", "description": "Ollama local model server — cross-AI /gsd:review reviewer lane only; not a GSD install target (no runtime body, no artifacts). OpenAI-compatible HTTP transport against a user-configured `review.ollama_host` (POST /v1/chat/completions); model discovered via GET /v1/models piped through jq.", "tier": "full", @@ -2931,7 +2931,7 @@ const capabilities = { "opencode": { "id": "opencode", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "OpenCode", "description": "OpenCode — XDG-based config dir; flat commands/ + skills artifact layout; settings-json config format; no lifecycle hook registration; tier-2 support.", "tier": "core", @@ -3126,7 +3126,7 @@ const capabilities = { "pattern-mapper": { "id": "pattern-mapper", "role": "feature", - "version": "1.12.0", + "version": "1.13.0", "title": "Pattern mapping", "description": "Optional codebase-pattern mapping before planning; owns the pattern mapper agent and workflow.pattern_mapper activation key.", "tier": "full", @@ -3180,7 +3180,7 @@ const capabilities = { "pi": { "id": "pi", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "pi", "description": "pi (pi.dev) — bun-runtime programmatic-CLI; TS ExtensionAPI (registerCommand/registerTool/registerProvider/pi.on); single native-extension file at ~/.pi/agent/extensions/gsd.js (.js, not .cjs — pi's extension auto-discovery accepts only .ts/.js, #2470); no shared-settings hook surface; tier-2 support.", "tier": "core", @@ -3250,7 +3250,7 @@ const capabilities = { "profile-pipeline": { "id": "profile-pipeline", "role": "feature", - "version": "1.12.0", + "version": "1.13.0", "title": "Developer profiling pipeline", "description": "Developer behavioral profiling from Claude Code session history; scans session JSONL files, extracts and samples user messages, and generates profile artifacts (USER-PROFILE.md, dev-preferences.md, CLAUDE.md sections). Exposes eight `gsd-tools` commands: scan-sessions, extract-messages, profile-sample (pipeline phase) and write-profile, profile-questionnaire, generate-dev-preferences, generate-claude-profile, generate-claude-md (output phase). Backs the /gsd-profile-user skill and gsd-user-profiler agent.", "tier": "full", @@ -3327,7 +3327,7 @@ const capabilities = { "qwen": { "id": "qwen", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "Qwen Code", "description": "Qwen Code (Alibaba) — nested-skill artifact layout; settings-json hook surface; Claude hook event dialect; tier-2 support.", "tier": "core", @@ -3477,7 +3477,7 @@ const capabilities = { "refactor-trigger": { "id": "refactor-trigger", "role": "feature", - "version": "1.12.0", + "version": "1.13.0", "title": "Complexity-triggered refactor", "description": "Measures the complexity of the code a phase touched and, when a function crosses a configured threshold or jumps past its recorded anchor, surfaces a scoped refactor proposal at .planning/phases//-REFACTOR.md. Advisory by default — it never edits code and never blocks. Opt-in strict mode blocks /gsd-ship while a proposal is untriaged; a declined proposal is recorded in the broken-windows ledger when that capability is present. Operationalizes 'refactor early, refactor often' as continuous pressure instead of a thing you have to remember (issue #1953).", "tier": "full", @@ -3544,7 +3544,7 @@ const capabilities = { "research": { "id": "research", "role": "feature", - "version": "1.12.0", + "version": "1.13.0", "title": "Phase research", "description": "Optional phase research before planning; owns the phase researcher agent and workflow.research activation key.", "tier": "standard", @@ -3596,7 +3596,7 @@ const capabilities = { "schema-gate": { "id": "schema-gate", "role": "feature", - "version": "1.12.0", + "version": "1.13.0", "title": "Schema push detection gate", "description": "Detects ORM schema-relevant files in the phase scope during planning and injects a mandatory [BLOCKING] schema push task into the plan. Prevents false-positive verification where build/types pass because TypeScript types come from config, not the live database.", "tier": "full", @@ -3642,7 +3642,7 @@ const capabilities = { "security": { "id": "security", "role": "feature", - "version": "1.12.0", + "version": "1.13.0", "title": "Security enforcement", "description": "Threat mitigation verification and ship-time security blocking for phases with security enforcement enabled.", "tier": "full", @@ -3741,7 +3741,7 @@ const capabilities = { "tdd": { "id": "tdd", "role": "feature", - "version": "1.12.0", + "version": "1.13.0", "title": "Test-driven development", "description": "Injects TDD heuristics into the planner and enforces RED/GREEN gate compliance on type:tdd plans after execution. Owns workflow.tdd_mode; the --tdd CLI flag is the ephemeral override.", "tier": "full", @@ -3794,7 +3794,7 @@ const capabilities = { "trae": { "id": "trae", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "Trae IDE", "description": "Trae IDE — nested-skill artifact layout; no hook surface (profile-marker-only config); tier-2 support.", "tier": "core", @@ -3892,7 +3892,7 @@ const capabilities = { "ui": { "id": "ui", "role": "feature", - "version": "1.12.0", + "version": "1.13.0", "title": "UI design contracts", "description": "UI-SPEC design contract + retrospective UI audit for frontend phases.", "tier": "full", @@ -3987,7 +3987,7 @@ const capabilities = { "vscode": { "id": "vscode", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "VS Code", "description": "VS Code — Marketplace/VSIX extension; no file-projected config directory; IDE-profile reference host (active vscode.lm model, engine-owned hook bus, sandboxed globalState/workspaceState stateIO).", "tier": "core", @@ -4045,7 +4045,7 @@ const capabilities = { "windsurf": { "id": "windsurf", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "Windsurf", "description": "Windsurf (Codeium) — workspace workflow artifact layout for slash commands; Cascade native hooks.json blocking hook bus (pre_write_code, pre_run_command); tier-2 support.", "tier": "core", @@ -4137,7 +4137,7 @@ const capabilities = { "zcode": { "id": "zcode", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "ZCode", "description": "ZCode (Z.ai) — desktop Agentic Development Environment for GLM-5.2; Claude-shaped nested skills at ~/.zcode/skills//SKILL.md, slash commands, named subagents, native MCP; declarative plugin surface; profile-marker install; tier-2 community support.", "tier": "core", @@ -5560,7 +5560,7 @@ const runtimes = { "antigravity": { "id": "antigravity", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "Antigravity", "description": "Google Antigravity IDE — config/settings home nested under ~/.gemini/antigravity (probed across 1.x and 2.x layouts); global skills/agents install under ~/.gemini/config, the dir AGY scans for global discovery (#3738); Gemini hook event dialect; flat skill layout; tier-1 support.", "tier": "core", @@ -5723,7 +5723,7 @@ const runtimes = { "augment": { "id": "augment", "role": "runtime", - "version": "1.12.0", + "version": "1.13.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", @@ -5837,7 +5837,7 @@ const runtimes = { "claude": { "id": "claude", "role": "runtime", - "version": "1.12.0", + "version": "1.13.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", @@ -6018,7 +6018,7 @@ const runtimes = { "cline": { "id": "cline", "role": "runtime", - "version": "1.12.0", + "version": "1.13.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", @@ -6111,7 +6111,7 @@ const runtimes = { "codebuddy": { "id": "codebuddy", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "CodeBuddy", "description": "CodeBuddy (Tencent) — converted commands + skills artifact layout; settings-json hook surface; Claude hook event dialect; tier-2 support.", "tier": "core", @@ -6229,7 +6229,7 @@ const runtimes = { "codex": { "id": "codex", "role": "runtime", - "version": "1.12.0", + "version": "1.13.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", @@ -6405,7 +6405,7 @@ const runtimes = { "copilot": { "id": "copilot", "role": "runtime", - "version": "1.12.0", + "version": "1.13.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", @@ -6505,7 +6505,7 @@ const runtimes = { "cursor": { "id": "cursor", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "Cursor", "description": "Cursor IDE — skills-only workflow surface; hooks.json surface; Claude hook event dialect; recursive skill loader (flat nesting); tier-2 support.", "tier": "core", @@ -6674,7 +6674,7 @@ const runtimes = { "hermes": { "id": "hermes", "role": "runtime", - "version": "1.12.0", + "version": "1.13.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", @@ -6786,7 +6786,7 @@ const runtimes = { "kilo": { "id": "kilo", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "Kilo Code", "description": "Kilo Code — XDG-based config dir; global skills at ~/.kilo/skills (separate from XDG config); flat command/ + skills artifact layout; no lifecycle hook registration; tier-2 support.", "tier": "core", @@ -6916,7 +6916,7 @@ const runtimes = { "kimi": { "id": "kimi", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "Kimi CLI", "description": "Kimi CLI (Moonshot AI) — generic agents root at ~/.config/agents; skills + kimi-agents artifact layout; native config.toml [[hooks]] bus at ~/.kimi/config.toml; background dispatch; tier-2 support.", "tier": "core", @@ -7020,7 +7020,7 @@ const runtimes = { "kimi-code": { "id": "kimi-code", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "Kimi Code CLI", "description": "Kimi Code CLI (Moonshot AI, Node) — Agent Skills auto-discovered at ~/.kimi-code/skills; global AGENTS.md at ~/.kimi-code/AGENTS.md; native config.toml + [[hooks]] bus; three built-in subagents (coder/explore/plan), NO custom named subagents; background dispatch; tier-2 support. Distinct from Python kimi-cli (the 'kimi' capability) per ADR-1239 EoS — Kimi Code cannot dispatch named subagents so the kimi-agents YAML layout does NOT apply; persona injection rides the existing ${AGENT_SKILLS_*} workflow fallback. Install-layout, agent-install-check, and install-time decision (kimi vs kimi-code) land in follow-up PRs; this descriptor is the EoS foundation.", "tier": "core", @@ -7187,7 +7187,7 @@ const runtimes = { "opencode": { "id": "opencode", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "OpenCode", "description": "OpenCode — XDG-based config dir; flat commands/ + skills artifact layout; settings-json config format; no lifecycle hook registration; tier-2 support.", "tier": "core", @@ -7382,7 +7382,7 @@ const runtimes = { "pi": { "id": "pi", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "pi", "description": "pi (pi.dev) — bun-runtime programmatic-CLI; TS ExtensionAPI (registerCommand/registerTool/registerProvider/pi.on); single native-extension file at ~/.pi/agent/extensions/gsd.js (.js, not .cjs — pi's extension auto-discovery accepts only .ts/.js, #2470); no shared-settings hook surface; tier-2 support.", "tier": "core", @@ -7452,7 +7452,7 @@ const runtimes = { "qwen": { "id": "qwen", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "Qwen Code", "description": "Qwen Code (Alibaba) — nested-skill artifact layout; settings-json hook surface; Claude hook event dialect; tier-2 support.", "tier": "core", @@ -7602,7 +7602,7 @@ const runtimes = { "trae": { "id": "trae", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "Trae IDE", "description": "Trae IDE — nested-skill artifact layout; no hook surface (profile-marker-only config); tier-2 support.", "tier": "core", @@ -7700,7 +7700,7 @@ const runtimes = { "vscode": { "id": "vscode", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "VS Code", "description": "VS Code — Marketplace/VSIX extension; no file-projected config directory; IDE-profile reference host (active vscode.lm model, engine-owned hook bus, sandboxed globalState/workspaceState stateIO).", "tier": "core", @@ -7758,7 +7758,7 @@ const runtimes = { "windsurf": { "id": "windsurf", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "Windsurf", "description": "Windsurf (Codeium) — workspace workflow artifact layout for slash commands; Cascade native hooks.json blocking hook bus (pre_write_code, pre_run_command); tier-2 support.", "tier": "core", @@ -7850,7 +7850,7 @@ const runtimes = { "zcode": { "id": "zcode", "role": "runtime", - "version": "1.12.0", + "version": "1.13.0", "title": "ZCode", "description": "ZCode (Z.ai) — desktop Agentic Development Environment for GLM-5.2; Claude-shaped nested skills at ~/.zcode/skills//SKILL.md, slash commands, named subagents, native MCP; declarative plugin surface; profile-marker install; tier-2 community support.", "tier": "core", diff --git a/package-lock.json b/package-lock.json index 308587f54..0a611180a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@opengsd/gsd-core", - "version": "1.12.0", + "version": "1.13.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@opengsd/gsd-core", - "version": "1.12.0", + "version": "1.13.0", "license": "MIT", "dependencies": { "@anthropic-ai/claude-agent-sdk": "^0.2.84", diff --git a/package.json b/package.json index f999f7c20..58eadab09 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@opengsd/gsd-core", - "version": "1.12.0", + "version": "1.13.0", "description": "GSD Core is a meta-prompting, context engineering, and spec-driven development system for AI coding agents.", "main": ".opencode/plugins/gsd-core.js", "bin": { diff --git a/vscode/package.json b/vscode/package.json index 8f95b2979..bf4de8f4d 100644 --- a/vscode/package.json +++ b/vscode/package.json @@ -2,7 +2,7 @@ "name": "gsd-core-vscode", "displayName": "GSD Core", "description": "GSD orchestration engine embedded in VS Code (ADR-1239 IDE profile).", - "version": "1.12.0", + "version": "1.13.0", "publisher": "opengsd", "engines": { "vscode": "^1.105.0" From b5b9814f033b6d32810562fd4068e1f107da29ec Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 6 Sep 2026 02:09:37 +0000 Subject: [PATCH 2/2] chore: promote CHANGELOG for v1.13.0 --- .changeset/2761-bracket-read-tolerance.md | 22 -- .changeset/4123-gsd-qoder-eos-entry.md | 5 - .changeset/4213-progress-surfaces-sync.md | 5 - .changeset/agile-cranes-caper.md | 5 - .changeset/bold-otters-run.md | 5 - .changeset/bold-sloths-dance.md | 5 - .changeset/brave-eagles-greet.md | 5 - .changeset/brave-wasps-wander.md | 5 - .changeset/calm-herons-sort.md | 5 - .changeset/calm-otters-surface.md | 7 - .changeset/calm-pandas-greet.md | 5 - .changeset/calm-pumas-frolic.md | 5 - .changeset/calm-seals-chatter.md | 5 - .changeset/clever-cats-wake.md | 5 - .changeset/clever-elks-sing.md | 5 - .changeset/clever-moles-rest.md | 5 - .changeset/curious-foxes-fly.md | 7 - .changeset/curious-newts-hop.md | 5 - .changeset/daring-lynx-hum.md | 5 - .changeset/daring-newts-squeak.md | 5 - .changeset/daring-tunas-hum.md | 5 - .changeset/daring-tunas-travel.md | 5 - .changeset/eager-geese-squeak.md | 5 - .changeset/eager-orcas-chatter.md | 5 - .changeset/eager-ravens-wander.md | 5 - .changeset/eager-tunas-gather.md | 7 - .changeset/fierce-geese-hop.md | 5 - .changeset/fierce-wasps-run.md | 5 - .changeset/fierce-yaks-glide.md | 5 - .changeset/gallant-newts-squeak.md | 5 - .changeset/gallant-tunas-climb.md | 5 - .changeset/gentle-birds-dance.md | 5 - .changeset/gentle-geese-hop.md | 5 - .changeset/gentle-tunas-rest.md | 5 - .changeset/graceful-finches-wake.md | 5 - .changeset/graceful-rams-rally.md | 5 - .changeset/happy-deer-howl.md | 5 - .changeset/happy-lynx-fly.md | 5 - .changeset/happy-ravens-zip.md | 5 - .changeset/humble-newts-greet.md | 5 - .changeset/jolly-dogs-hop.md | 5 - .changeset/jolly-ravens-parade.md | 5 - .changeset/kind-finches-hum.md | 5 - .changeset/lane-effort-from-review-config.md | 5 - .changeset/lively-birds-click.md | 5 - .changeset/lucky-jays-travel.md | 5 - .changeset/lucky-lynx-cheer.md | 5 - .changeset/lucky-pandas-commit.md | 82 ------ .changeset/lucky-tigers-gather.md | 13 - .changeset/mellow-mice-jump.md | 5 - .changeset/mellow-moles-run.md | 5 - .changeset/mellow-pumas-zip.md | 5 - .changeset/mellow-seals-climb.md | 5 - .changeset/mellow-yaks-squeak.md | 5 - .changeset/merry-wasps-sprint.md | 5 - .changeset/nimble-herons-rest.md | 5 - .changeset/nimble-otters-swim.md | 5 - .changeset/nimble-quails-climb.md | 5 - .changeset/nimble-tigers-forage.md | 5 - .changeset/noble-goats-gather.md | 5 - .changeset/noble-otters-wander.md | 5 - .changeset/noble-seals-jump.md | 5 - .changeset/olive-moons-listen.md | 11 - .changeset/patient-goats-glide.md | 5 - .changeset/patient-jaguars-rally.md | 5 - .changeset/patient-orcas-tumble.md | 5 - .changeset/patient-pumas-frolic.md | 5 - .changeset/patient-ravens-cheer.md | 5 - .changeset/proud-deer-jump.md | 5 - .changeset/quick-finches-greet.md | 5 - .changeset/quick-goats-rest.md | 5 - .changeset/quiet-hounds-report.md | 5 - .changeset/quiet-otters-listen.md | 5 - .../quote-decimal-frontmatter-scalars.md | 5 - .changeset/serene-badgers-purr.md | 5 - .changeset/serene-bears-travel.md | 5 - .changeset/serene-newts-click.md | 7 - .changeset/serene-yaks-wake.md | 5 - .changeset/sharp-jaguars-run.md | 5 - .changeset/sharp-orcas-purr.md | 5 - .changeset/silly-geese-hop.md | 5 - .changeset/silly-pandas-frolic.md | 5 - .changeset/silly-rams-caper.md | 5 - ...ate-empty-field-preserve-following-line.md | 5 - .changeset/steady-birds-hum.md | 5 - .changeset/steady-outline-marker.md | 5 - .changeset/sturdy-bears-sprint.md | 5 - .changeset/sturdy-orcas-snooze.md | 5 - .changeset/sturdy-pumas-swim.md | 5 - .changeset/sunny-geese-forage.md | 5 - .changeset/sunny-ravens-leap.md | 5 - .changeset/sunny-voles-snooze.md | 5 - .changeset/tidy-badgers-fly.md | 5 - .changeset/tidy-tunas-wander.md | 5 - .changeset/vivid-cranes-march.md | 5 - .changeset/vivid-lynx-romp.md | 5 - .changeset/vivid-pumas-roam.md | 5 - .changeset/vivid-rams-rally.md | 5 - .changeset/vivid-voles-wander.md | 5 - .changeset/witty-bears-caper.md | 5 - .changeset/witty-otters-reset.md | 5 - .changeset/zesty-cranes-dance.md | 5 - .changeset/zesty-ravens-snooze.md | 5 - .changeset/zesty-seals-frolic.md | 5 - .changeset/zesty-wasps-fly.md | 5 - .changeset/zesty-yaks-tumble.md | 5 - CHANGELOG.md | 233 ++++++++++++++++++ 107 files changed, 233 insertions(+), 646 deletions(-) delete mode 100644 .changeset/2761-bracket-read-tolerance.md delete mode 100644 .changeset/4123-gsd-qoder-eos-entry.md delete mode 100644 .changeset/4213-progress-surfaces-sync.md delete mode 100644 .changeset/agile-cranes-caper.md delete mode 100644 .changeset/bold-otters-run.md delete mode 100644 .changeset/bold-sloths-dance.md delete mode 100644 .changeset/brave-eagles-greet.md delete mode 100644 .changeset/brave-wasps-wander.md delete mode 100644 .changeset/calm-herons-sort.md delete mode 100644 .changeset/calm-otters-surface.md delete mode 100644 .changeset/calm-pandas-greet.md delete mode 100644 .changeset/calm-pumas-frolic.md delete mode 100644 .changeset/calm-seals-chatter.md delete mode 100644 .changeset/clever-cats-wake.md delete mode 100644 .changeset/clever-elks-sing.md delete mode 100644 .changeset/clever-moles-rest.md delete mode 100644 .changeset/curious-foxes-fly.md delete mode 100644 .changeset/curious-newts-hop.md delete mode 100644 .changeset/daring-lynx-hum.md delete mode 100644 .changeset/daring-newts-squeak.md delete mode 100644 .changeset/daring-tunas-hum.md delete mode 100644 .changeset/daring-tunas-travel.md delete mode 100644 .changeset/eager-geese-squeak.md delete mode 100644 .changeset/eager-orcas-chatter.md delete mode 100644 .changeset/eager-ravens-wander.md delete mode 100644 .changeset/eager-tunas-gather.md delete mode 100644 .changeset/fierce-geese-hop.md delete mode 100644 .changeset/fierce-wasps-run.md delete mode 100644 .changeset/fierce-yaks-glide.md delete mode 100644 .changeset/gallant-newts-squeak.md delete mode 100644 .changeset/gallant-tunas-climb.md delete mode 100644 .changeset/gentle-birds-dance.md delete mode 100644 .changeset/gentle-geese-hop.md delete mode 100644 .changeset/gentle-tunas-rest.md delete mode 100644 .changeset/graceful-finches-wake.md delete mode 100644 .changeset/graceful-rams-rally.md delete mode 100644 .changeset/happy-deer-howl.md delete mode 100644 .changeset/happy-lynx-fly.md delete mode 100644 .changeset/happy-ravens-zip.md delete mode 100644 .changeset/humble-newts-greet.md delete mode 100644 .changeset/jolly-dogs-hop.md delete mode 100644 .changeset/jolly-ravens-parade.md delete mode 100644 .changeset/kind-finches-hum.md delete mode 100644 .changeset/lane-effort-from-review-config.md delete mode 100644 .changeset/lively-birds-click.md delete mode 100644 .changeset/lucky-jays-travel.md delete mode 100644 .changeset/lucky-lynx-cheer.md delete mode 100644 .changeset/lucky-pandas-commit.md delete mode 100644 .changeset/lucky-tigers-gather.md delete mode 100644 .changeset/mellow-mice-jump.md delete mode 100644 .changeset/mellow-moles-run.md delete mode 100644 .changeset/mellow-pumas-zip.md delete mode 100644 .changeset/mellow-seals-climb.md delete mode 100644 .changeset/mellow-yaks-squeak.md delete mode 100644 .changeset/merry-wasps-sprint.md delete mode 100644 .changeset/nimble-herons-rest.md delete mode 100644 .changeset/nimble-otters-swim.md delete mode 100644 .changeset/nimble-quails-climb.md delete mode 100644 .changeset/nimble-tigers-forage.md delete mode 100644 .changeset/noble-goats-gather.md delete mode 100644 .changeset/noble-otters-wander.md delete mode 100644 .changeset/noble-seals-jump.md delete mode 100644 .changeset/olive-moons-listen.md delete mode 100644 .changeset/patient-goats-glide.md delete mode 100644 .changeset/patient-jaguars-rally.md delete mode 100644 .changeset/patient-orcas-tumble.md delete mode 100644 .changeset/patient-pumas-frolic.md delete mode 100644 .changeset/patient-ravens-cheer.md delete mode 100644 .changeset/proud-deer-jump.md delete mode 100644 .changeset/quick-finches-greet.md delete mode 100644 .changeset/quick-goats-rest.md delete mode 100644 .changeset/quiet-hounds-report.md delete mode 100644 .changeset/quiet-otters-listen.md delete mode 100644 .changeset/quote-decimal-frontmatter-scalars.md delete mode 100644 .changeset/serene-badgers-purr.md delete mode 100644 .changeset/serene-bears-travel.md delete mode 100644 .changeset/serene-newts-click.md delete mode 100644 .changeset/serene-yaks-wake.md delete mode 100644 .changeset/sharp-jaguars-run.md delete mode 100644 .changeset/sharp-orcas-purr.md delete mode 100644 .changeset/silly-geese-hop.md delete mode 100644 .changeset/silly-pandas-frolic.md delete mode 100644 .changeset/silly-rams-caper.md delete mode 100644 .changeset/state-empty-field-preserve-following-line.md delete mode 100644 .changeset/steady-birds-hum.md delete mode 100644 .changeset/steady-outline-marker.md delete mode 100644 .changeset/sturdy-bears-sprint.md delete mode 100644 .changeset/sturdy-orcas-snooze.md delete mode 100644 .changeset/sturdy-pumas-swim.md delete mode 100644 .changeset/sunny-geese-forage.md delete mode 100644 .changeset/sunny-ravens-leap.md delete mode 100644 .changeset/sunny-voles-snooze.md delete mode 100644 .changeset/tidy-badgers-fly.md delete mode 100644 .changeset/tidy-tunas-wander.md delete mode 100644 .changeset/vivid-cranes-march.md delete mode 100644 .changeset/vivid-lynx-romp.md delete mode 100644 .changeset/vivid-pumas-roam.md delete mode 100644 .changeset/vivid-rams-rally.md delete mode 100644 .changeset/vivid-voles-wander.md delete mode 100644 .changeset/witty-bears-caper.md delete mode 100644 .changeset/witty-otters-reset.md delete mode 100644 .changeset/zesty-cranes-dance.md delete mode 100644 .changeset/zesty-ravens-snooze.md delete mode 100644 .changeset/zesty-seals-frolic.md delete mode 100644 .changeset/zesty-wasps-fly.md delete mode 100644 .changeset/zesty-yaks-tumble.md diff --git a/.changeset/2761-bracket-read-tolerance.md b/.changeset/2761-bracket-read-tolerance.md deleted file mode 100644 index 14f55e0d6..000000000 --- a/.changeset/2761-bracket-read-tolerance.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -type: Added -pr: 2867 ---- -**Bracket-style phase IDs (`[GSD.02] 05: Name`) are now recognized on the read path** — `roadmap`, `validate` and `state` previously matched only the `Phase N:` spelling and the `NN-name` directory shape, so on a project with `phase_id_convention: "bracket"` every phase was invisible: counts fell back to the on-disk directory listing, `get-phase` reported not-found, every `GSD.02-05-slug` directory was reported malformed, and a completed milestone was warned to have unstarted phases. What changes: - -- Milestone scoping recognizes the ADR-canonical `## [GSD.02] Foundation` heading, including the version-less form (no `vN.N`, no status emoji), at any heading level through `###`, and across a milestone split over two headings in either order. A sibling milestone's phases and directories are excluded either way. -- Phase directories resolve, so each bracket phase reports its real `disk_status`, `plan_count` and `summary_count` instead of `no_directory` and zeros, and `completed_phases`, `total_plans` and the progress percent count the whole milestone. `state sync` scopes its own disk scan the same way, so the percent it writes to STATE.md agrees with the read path. -- Bracket-sentinel milestones (`[GSD.999]` icebox and `[GSD.00]` pre-milestone) and the reserved `999` phase token are excluded from phase counts, while retired phases leave the denominator. `validate consistency` and `validate health` now agree on bracket icebox entries instead of one flagging what the other excludes. The deliberately asymmetric phase-0 behavior is detailed below. -- `missing_phase_details` classifies each checklist entry on its own bracket. Two entries sharing a phase token across different brackets previously shared one verdict, decided by which was written first, so a real phase listed under an icebox entry's token was silently dropped from the report. -- `phase_id_convention` resolves against the workstream being read. A workstream that declares its own convention is no longer overridden by the root config, and `--workstream foo` now agrees with `GSD_WORKSTREAM=foo`; workstream progress rollups resolve the convention instead of assuming legacy, so a bracket workstream's phase count comes from its ROADMAP rather than falling back to its directory count. -- `validate health` gains an advisory W021 for opted-in projects: one sub-check flags a phase whose bracket milestone disagrees with its enclosing section, the other flags a phase heading not yet migrated to bracket form. -- `state validate` resolves bracket phase directories, so its drift scan actually runs on a bracket project instead of reporting `no phase directory matches` — and `valid: false` — for a directory that is plainly on disk. -- The `roadmap milestone-scope` probe and the `phase add` / `add-batch` / `insert` milestone-scope guard both read bracket headings. Blind, the probe reported an empty phase set on a bracket ROADMAP before *and* after a write, so the edit-phase rollback check could never fire; and the guard accepted a description embedding `## [GSD.09] Name` — a heading that carries none of the legacy milestone markers yet terminates the window on an opted-in project, silently dropping every later phase out of the milestone scope. A project that has not opted in is unaffected in both cases. - -Every widened read engages only when the resolved `phase_id_convention` is `bracket`; a project that has not opted in compiles the same patterns it did before. `"bracket"` is a read-path opt-in until the migrator and write path land — valid values are documented in `docs/CONFIGURATION.md`. - -Two consequences of landing on top of #3185 are worth stating. First, #3185 moved the legacy heading counter onto the canonical sentinel predicate, which drops a `### Phase 0:` or `### Phase 0.5:` heading from `total_phases`; combined with this PR's mid-migration guard, that legacy-spelled heading is counted on a bracket project and not counted on one that has not opted in. A bracket-spelled bare `0` or `0.x` remains excluded. The bracket counter keeps the narrower `^0\b` rule deliberately, because the canonical predicate also swallows decimal phase IDs such as `00.1`, which is a real phase rather than milestone 0. Second, the shared phase-directory enumerator keeps its `phaseIdConvention = null` destructure default (`phase-locator.cts:375`), and `null` means "resolved, and not bracket" — the lazy resolve-from-config fires only on `undefined` (`roadmap-parser.cts:941`, `:1928`, whose own comment records that "explicit null still means 'resolved and non-bracket'"). Only four of its seventeen call sites thread a resolved convention: `milestone complete` (`milestone.cts:782`) and `state`'s three (`state.cts:979`, `:2303`, `:4672`). The remaining thirteen omit it and therefore still enumerate on the legacy reading — including `progress` (`roadmap.cts:745`), `stats` (`commands.cts:1947`, `:2302`), `phase list` and the init manager view (`init.cts`), and `state sync`'s own scope probe (`state.cts:4795`). On a bracket project those surfaces receive an unscoped or legacy-scoped directory set, not a bracket-scoped one, and their per-entry rendering is likewise unconverted (`cmdProgressRender`'s directory regex, `cmdStats`'s convention-less `extractPhaseToken(dir)` call, the init manager view's `Phase`-literal heading pattern). Widening those call sites is display- and command-surface work deferred to the epic's later PRs; this slice does not claim them. - -The archival and milestone-completion paths DO reach the widened enumerator, and deliberately so: `milestone complete` (`cmdMilestoneComplete`) and `state update-progress` (`cmdStateUpdateProgress`) both call the same shared `listMilestonePhaseDirs` this PR widens, and both now resolve and thread `phase_id_convention` explicitly at their call sites rather than relying on the enumerator's own lazy resolve-from-config default. On a project that has opted into `"bracket"`, `milestone complete` archives the milestone's real bracket-declared phase directories — the same set the read path already reports — instead of failing to recognize them; a `null` / `milestone-prefixed` project's archived set is unchanged. `state update-progress`'s reported and written percent was already correctly scoped (it derives from `buildStateFrontmatter`, which threads its own resolved convention independently); the explicit thread at its own enumerator call is single-derivation hygiene, not a behavior change, and is documented as such in-line (mutation-tested: reverting only this thread leaves every existing assertion on this command green, because the enumerator's own lazy resolve-from-config default answers the same question the explicit thread does). `cmdMilestoneComplete`'s enumerated set is pinned by a test (`tests/adr-612-bracket-phase-counting.test.cjs`, the round-11 BLOCKER block) so a future regression to the pass-all-degrade legacy reading cannot silently move what a bracket project's `milestone complete` archives without failing a test. `state update-progress`'s own call site is pinned differently, matching what it actually gates: not the reported percent, but the #3233 zero-plans no-op — a bracket milestone whose declared phases carry no plans on disk stays a no-op only when a directory that plainly does not belong to the milestone window is correctly excluded from this call site's enumerated set; swept in by a pass-all degrade, the no-op stops firing. (#2761) - -One more disk-side fix lands alongside the above. `listMilestonePhaseDirs`'s sentinel filter (`isSentinelPhaseId`) treated a bare, untagged phase directory under `phase_id_convention: "bracket"` (`0-bootstrap`, no `{CODE}.{MM}-` prefix) as sentinel milestone 0 by falling through to the legacy leading-int rule — silently dropping a real, on-disk, milestone-declared phase directory from `completed_phases`. This mirrors, on the disk side, the exact defect class the heading-side counters (`countRoadmapPhaseHeadings`, `scanMilestonePhaseIds`) already guard against for the identical bare/untagged shape: under bracket convention, milestone 0 is expressed only via an explicit bracket tag, so an untagged leading `0` is a real phase token, not a sentinel. The `999`/icebox reading stays universal. Legacy and milestone-prefixed projects are unaffected (this call site's `convention` argument is only ever `'bracket'` or unset). diff --git a/.changeset/4123-gsd-qoder-eos-entry.md b/.changeset/4123-gsd-qoder-eos-entry.md deleted file mode 100644 index bdd204c71..000000000 --- a/.changeset/4123-gsd-qoder-eos-entry.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Added -pr: 4278 ---- -**The EoS Registry now lists GSD for Qoder** — discover the independently maintained `cainiao1992/gsd-qoder` protocol-v1 host integration for Alibaba's Qoder CLI and Qoder Desktop, including exact install and uninstall commands, supported interface points, and negotiated host axes. (#4123) diff --git a/.changeset/4213-progress-surfaces-sync.md b/.changeset/4213-progress-surfaces-sync.md deleted file mode 100644 index 227e020cb..000000000 --- a/.changeset/4213-progress-surfaces-sync.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4231 ---- -**`state` verbs keep the STATE.md body Progress bar in sync with frontmatter `progress.percent`** — 13 of 15 verbs rewrote the frontmatter percent while the body bar stayed stale (issue #4213: frontmatter 75, body bar still 50), so the two surfaces silently diverged on every record-session, add-decision and milestone switch. The bar is now rewritten through one shared helper on the write seam, keeping the bold `**Progress:**` status line the target even when a free-text line above it starts with `Progress:`, and an out-of-range persisted percent renders a clamped 0-100 bar instead of crashing the write. (#4213) diff --git a/.changeset/agile-cranes-caper.md b/.changeset/agile-cranes-caper.md deleted file mode 100644 index 9675cacd4..000000000 --- a/.changeset/agile-cranes-caper.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4299 ---- -**Background waits no longer emit a red ScheduleWakeup validation error** — while a background subagent (researcher/planner/checker or the manager dashboard's dispatch) was in flight, the orchestrator could literalize "I'll wait" by calling the host's ScheduleWakeup tool with partial arguments, surfacing "`prompt` is required when `stop` is not true."; every GSD wait-instruction site now explicitly forbids wake-up scheduling. (#4079) diff --git a/.changeset/bold-otters-run.md b/.changeset/bold-otters-run.md deleted file mode 100644 index 61ae65251..000000000 --- a/.changeset/bold-otters-run.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4215 ---- -**Structural pre-pass no longer aborts for phases introduced in the repository's root commit** — Fallow uses the root commit itself when no parent exists instead of receiving an invalid parent revision. (#4183) diff --git a/.changeset/bold-sloths-dance.md b/.changeset/bold-sloths-dance.md deleted file mode 100644 index 7db5f8cce..000000000 --- a/.changeset/bold-sloths-dance.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Changed -pr: 4084 ---- -**`/gsd-review` now tells every reviewer the exact plan ids and total count, and grades coverage against them** — a review that silently covers only some of a multi-plan phase is no longer indistinguishable from one that covered every plan. (#3301) diff --git a/.changeset/brave-eagles-greet.md b/.changeset/brave-eagles-greet.md deleted file mode 100644 index 74cadb10d..000000000 --- a/.changeset/brave-eagles-greet.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4175 ---- -**Blocking guards no longer silently disable themselves when the host stalls** — the six blocking PreToolUse guards are registered (and migrated on existing installs) with a 120 s timeout instead of 5 s; Claude Code treats a timed-out hook as non-blocking, so the old budget dropped the gate exactly under load. (#3981) diff --git a/.changeset/brave-wasps-wander.md b/.changeset/brave-wasps-wander.md deleted file mode 100644 index 83433abe3..000000000 --- a/.changeset/brave-wasps-wander.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Changed -pr: 4236 ---- -Secret-file read protection moved from installer-written permission deny rules to a managed hook. The Claude Code installer no longer writes `Read(.env)` / `Read(.env.*)` / `Read(.secrets)` into `permissions.deny`, and removes those three strings (byte-equal only) from existing installs on install and uninstall — on Claude Code >= 2.1.259 any `Read()` deny rule made every `cd DIR && grep …` compound prompt for approval, even in `auto` mode. The same protection now ships as the always-on `gsd-secret-read-guard.js` PreToolUse hook (matcher `Read|Grep|Bash`; Kimi `ReadFile|Grep|Shell`; OpenCode/Kilo plugin dispatch), which denies reads of `.env`, `.env.` and `.secrets` — matched case-insensitively — via Read, Grep (explicit path or a selecting glob, judged per brace alternative) and Bash (operands, input redirects, `$( )`/backtick/`<( )` bodies, `git show :`). A shell interpreter (`bash`/`sh`/`zsh`/`dash`/`ksh`) has its script scanned however it arrives — `-c '…'`, a `<( )` file operand, a heredoc / here-string, or a pipe from a knowable `echo`/`printf` source — plus `eval`'s joined operands, a `source`/`.` process-substitution operand, and `find … | xargs cat` pipelines (upstream literal names become the sub-command's read operands). `.env.example` / `.env.sample` / `.env.template` / `.env.dist` stay readable, and existence checks (`[ -f .env ]`, `ls .env*`) pass. Documented gaps: `$VAR` indirection, shell globs, interpreter one-liners, a piped script from a non-`echo`/`printf` source (`cat gen.sh | bash`, `curl … | sh`), reads inside executed scripts, and a Grep `glob: '*'` reaching a non-gitignored `.env`. Breaking: a hand-written deny rule identical to one of the three strings is removed too; re-add it if you want both layers. Cursor, Windsurf, Cline, Copilot, Codex and ZCode have no per-tool hook matcher and are not covered (they never had the deny rules either). diff --git a/.changeset/calm-herons-sort.md b/.changeset/calm-herons-sort.md deleted file mode 100644 index b062506df..000000000 --- a/.changeset/calm-herons-sort.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4110 ---- -**Progress routing preserves decimal phase IDs** — `init progress` now orders parent and inserted phases canonically, and `smart-entry --json` returns the complete current phase token instead of truncating it to an integer. diff --git a/.changeset/calm-otters-surface.md b/.changeset/calm-otters-surface.md deleted file mode 100644 index d58208265..000000000 --- a/.changeset/calm-otters-surface.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -type: Fixed -pr: 4182 ---- -**Global Runtime Surface materialization no longer breaks after the installing package disappears** — source-dependent global installs provision manifest-owned raw command and agent corpora below `gsd-core/`, while agents-only and empty layouts receive only what their descriptors require. Source selection uses one complete provider for the whole layout, retains the complete legacy marker path, rejects corpora observed during provider selection as missing, hash-mismatched, symlink-escaped, or unexpectedly extended, and preserves local-install behavior. - -Surface materialization now stages every artifact kind before mutation and publishes the candidate surface state last. A source or staging failure therefore leaves the prior state and artifacts untouched. Fresh and upgraded Codex/Claude installs can materially change a surface using only deployed modules and the installed corpus, while an unmigrated source-less deployment fails with an install/upgrade diagnostic before changing state or artifacts. diff --git a/.changeset/calm-pandas-greet.md b/.changeset/calm-pandas-greet.md deleted file mode 100644 index 57ff01ff4..000000000 --- a/.changeset/calm-pandas-greet.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Changed -pr: 4237 ---- -**`/gsd-update` now stops when it cannot resolve an installed update target** — use the installer explicitly for a fresh install. This includes a custom `--config-dir` whose directory name matches no known runtime and has no runtime marker file or env var (previously silently defaulted to `claude`; now intentionally unresolved). (#4153) diff --git a/.changeset/calm-pumas-frolic.md b/.changeset/calm-pumas-frolic.md deleted file mode 100644 index 19bfc4170..000000000 --- a/.changeset/calm-pumas-frolic.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4325 ---- -**`todo complete` honors `--dry-run` and stops corrupting frontmatter** — the flag was accepted and silently ignored (the todo was moved, exit 0, `completed: true` reported), and the `completed:` stamp was written above the opening `---` fence so no fence-locating reader could parse the archived file. `--dry-run` now prints a preview-shaped payload (`dry_run`/`would_*`) and touches nothing; a real completion upserts `completed:` and `status: completed` inside the frontmatter block, and unknown flags fail loudly instead of being dropped. (#4096) diff --git a/.changeset/calm-seals-chatter.md b/.changeset/calm-seals-chatter.md deleted file mode 100644 index 44e431b0b..000000000 --- a/.changeset/calm-seals-chatter.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Added -pr: 3934 ---- -**Quick planning now preserves `plan:pre` guidance across revisions.** `/gsd-quick` renders one hook snapshot and reuses its planner-targeted contributions for the initial planner and `--full`/`--validate` revision planner. Non-planner contributions are omitted. Because security enforcement is enabled by default, Quick plans may now receive `` guidance unless `workflow.security_enforcement` is disabled. (#3778) diff --git a/.changeset/clever-cats-wake.md b/.changeset/clever-cats-wake.md deleted file mode 100644 index 35b6b8014..000000000 --- a/.changeset/clever-cats-wake.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4329 ---- -**`/gsd-review` no longer sweeps the run's own prompt/plan copies into `.review-diagnostics/`** — after a review, the preserved diagnostics folder is now dominated by actual evidence (reviewer reports and stderr sidecars) instead of byte-identical duplicates of the prompt, instructions, roadmap, and every plan under review. (#4097) diff --git a/.changeset/clever-elks-sing.md b/.changeset/clever-elks-sing.md deleted file mode 100644 index 18f9b188c..000000000 --- a/.changeset/clever-elks-sing.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4180 ---- -**`workflow.tdd_mode: true` now actually enforces TDD** — the RED-commit runtime gate no longer requires MVP mode, so the obvious TDD opt-in stops being silently inert on non-MVP phases; the end-of-phase TDD review escalation follows the same decoupling. (#4011) diff --git a/.changeset/clever-moles-rest.md b/.changeset/clever-moles-rest.md deleted file mode 100644 index 969c7c2cb..000000000 --- a/.changeset/clever-moles-rest.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4170 ---- -**/gsd-review no longer down-weights plan-grounded reviews for a citation shape the prompt made impossible** — each plan in the review prompt now carries a repo-relative #### path header, and the budget copies are named after their source plan id instead of a bare index, so source-grounded lanes can cite plans in a form the consensus step resolves. (#3959) diff --git a/.changeset/curious-foxes-fly.md b/.changeset/curious-foxes-fly.md deleted file mode 100644 index e55a1098d..000000000 --- a/.changeset/curious-foxes-fly.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -type: Removed -pr: 4179 ---- -**Dropped the `test:mutation:since` npm script** — it passed `--since`, which Stryker 9.x does not accept (`error: unknown option '--since'`), so it could not run at all. Nothing invoked it: the mutation gate runs the per-module matrix from `scripts/mutation-matrix.cjs` instead, so no workflow regresses. To see which modules a change puts in scope, run `node scripts/mutation-matrix.cjs --base origin/next --print`. (#4106) - - diff --git a/.changeset/curious-newts-hop.md b/.changeset/curious-newts-hop.md deleted file mode 100644 index 7e6e07236..000000000 --- a/.changeset/curious-newts-hop.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Added -pr: 4167 ---- -**Read-injection scanner advisory output now carries typed `severity` and `source` fields** — `gsd-read-injection-scanner.js`'s Read/WebFetch/WebSearch advisory (already emitting a typed `findings` array since #3523) now also includes `severity: 'LOW'|'HIGH'` and `source` (the scanned file path, URL, or query) alongside its existing `additionalContext` prose. (#3546) diff --git a/.changeset/daring-lynx-hum.md b/.changeset/daring-lynx-hum.md deleted file mode 100644 index 2ad35ea71..000000000 --- a/.changeset/daring-lynx-hum.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Changed -pr: 2558 ---- -**Every workflow now carries response-language coverage, and every directive names inter-tool narration** — previously uncovered workflows (including `/gsd-review` and lazy-loaded mode/step files) now apply a shared or inline directive, and the 44 workflows whose directive covered only "questions, prompts, and explanations" now name narration between tool calls, status updates, progress notes, and findings, so running commentary no longer stays in English beside translated answers. A CI lint (`lint:response-language`) prevents future workflows from shipping uncovered or with the weaker wording. (#2529) diff --git a/.changeset/daring-newts-squeak.md b/.changeset/daring-newts-squeak.md deleted file mode 100644 index 67bb21407..000000000 --- a/.changeset/daring-newts-squeak.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Security -pr: 4121 ---- -**Removed a critical unpatched supply-chain vulnerability from the `lint:ci` toolchain** — the `shellcheck` devDependency pulled in `decompress@4.2.1`, which carries an unpatched critical zip-slip flaw (GHSA-mp2f-45pm-3cg9); replaced with a small dependency-free downloader that fetches a pinned ShellCheck release directly and extracts it without the vulnerable extraction library. (#4120) diff --git a/.changeset/daring-tunas-hum.md b/.changeset/daring-tunas-hum.md deleted file mode 100644 index de1f17a51..000000000 --- a/.changeset/daring-tunas-hum.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Added -pr: 4277 ---- -**New `phase.tdd-applicable` query verb** — computes whether the TDD RED/GREEN/REFACTOR procedure applies to a given plan (explicit flag, plan `type: tdd` frontmatter, a task's `tdd="true"` attribute, or the `workflow.tdd_mode` config default), in one place. Also fixes `workflow.tdd_mode`, `workflow.research`, and `workflow.nyquist_validation` config keys, which never actually reached `cmdInitExecutePhase`/`cmdInitPlanPhase`/`cmdInitDebug`/`cmdInitNewMilestone` due to a dead `config.workflow` accessor. (#4273) diff --git a/.changeset/daring-tunas-travel.md b/.changeset/daring-tunas-travel.md deleted file mode 100644 index be6d2f7c5..000000000 --- a/.changeset/daring-tunas-travel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Changed -pr: 4085 ---- -**`/gsd-verify-work` re-verification no longer reopens a closed gap-closure round on an unevidenced new finding** — a Step 7 anti-pattern blocker that isn't a carried-forward gap or a regression on a file touched since the prior pass now needs a red-capable test or another concrete artifact to stay blocking; without one it's recorded as advisory instead of reverting completed work and starting another `--gaps` cycle. (#3304) diff --git a/.changeset/eager-geese-squeak.md b/.changeset/eager-geese-squeak.md deleted file mode 100644 index 1e79bc0b1..000000000 --- a/.changeset/eager-geese-squeak.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4245 ---- -**Windows CI test runs no longer hang indefinitely.** The test runner's temp-sweep protection walk used a POSIX-only termination check that never fired on a Windows drive root, spinning forever and timing out every Windows CI shard. A second, previously-masked bug in the temp-root regression test's own child-process env override (only `TMPDIR`, not `TEMP`/`TMP`) is also fixed, since Windows never reads `TMPDIR`. diff --git a/.changeset/eager-orcas-chatter.md b/.changeset/eager-orcas-chatter.md deleted file mode 100644 index d519a1a4b..000000000 --- a/.changeset/eager-orcas-chatter.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 3739 ---- -**`deferred-items.md` entries written with `*`, `+` or an ordered marker are no longer silently dropped** — the parser recognised only `- `, so a deferred list written with any other standard Markdown list marker contributed zero entries and reported as a clean zero to `audit-open`. An ordered list counts when it starts at `0.` or `1.` or continues a list already open at its level; `1)` is not a marker. Also fixed: a `status:` line inside a fenced code block indented four or more spaces — what a fence under a nested bullet looks like — was not treated as fenced, so a `status: resolved` written as documentation resolved the entry containing it; and an unclosed fence now ends with its own entry instead of hiding every entry after it. `audit-open acknowledge` reads and writes the same grammar — its line selection goes through the reader's own classifier on the headless and (since #3781) the heading-delimited shape alike — so an entry the audit surfaces under any of these markers can be acknowledged, and a heading-delimited file written with one of the newly recognised markers now surfaces its entries for `complete-milestone` to acknowledge in place, where it previously closed over them unseen. (#3702) diff --git a/.changeset/eager-ravens-wander.md b/.changeset/eager-ravens-wander.md deleted file mode 100644 index c5ce03e09..000000000 --- a/.changeset/eager-ravens-wander.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Added -pr: 4167 ---- -**Hook advisory output now carries typed reason-code fields** — `gsd-read-guard.js`'s Write/Edit advisory now includes `code: 'READ_BEFORE_EDIT'` and `fileName` alongside its existing `additionalContext` prose, so callers reading the hook's JSON no longer need to substring-match the advisory text to detect why it fired or which file it named. (#3546) diff --git a/.changeset/eager-tunas-gather.md b/.changeset/eager-tunas-gather.md deleted file mode 100644 index cc842fbf8..000000000 --- a/.changeset/eager-tunas-gather.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -type: Changed -pr: 4206 ---- -**Planner wave assignment now sequences automatic external review after internal fixes** — phases with internal review lanes defer PR creation until accepted fixes land and re-check open-time properties immediately before opening. - - diff --git a/.changeset/fierce-geese-hop.md b/.changeset/fierce-geese-hop.md deleted file mode 100644 index f5336a806..000000000 --- a/.changeset/fierce-geese-hop.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4072 ---- -**CI shard 1 no longer runs at 92-99% of its timeout cap.** The full-scope unit-test shard balancer now reserves shard 1's fixed aux-suite cost (integration/security/install/slow) before packing unit-test files onto it, instead of leaving shard 1 to carry that cost on top of an equal unit-test share. (#4070) diff --git a/.changeset/fierce-wasps-run.md b/.changeset/fierce-wasps-run.md deleted file mode 100644 index 9a4b217cc..000000000 --- a/.changeset/fierce-wasps-run.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Added -pr: 4290 ---- -Verification reports now record a deterministic content fingerprint of their covered inputs (phase PLAN/SUMMARY, mapped requirements, implementation files in the change set); `readVerificationStatus` recomputes it and reports `stale` on any mismatch, fail-closed on a missing/unreadable/confinement-escaping covered file. Legacy reports without fingerprint metadata keep the prior SUMMARY-mtime staleness check unchanged. (#4155) diff --git a/.changeset/fierce-yaks-glide.md b/.changeset/fierce-yaks-glide.md deleted file mode 100644 index ee8291e7e..000000000 --- a/.changeset/fierce-yaks-glide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4289 ---- -**`/gsd:progress --do` now routes specific commands before generic keywords, confirms the route before dispatch, and forwards only arguments the target command accepts** — freeform requests like "set up this existing codebase" or "wrap up the spike findings" no longer preempt to the wrong lifecycle command, and no command runs without your confirmation. (#4051) diff --git a/.changeset/gallant-newts-squeak.md b/.changeset/gallant-newts-squeak.md deleted file mode 100644 index b8324a379..000000000 --- a/.changeset/gallant-newts-squeak.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 3758 ---- -**Advisory plan-checker findings no longer force a replan** — Dimension 3b (undeclared same-wave coupling, #1954) is retagged to the advisory `info` tier, plan-phase accepts INFO-only checker results instead of entering the revision loop, and planners can declare deliberate coupling with a new optional `coupling_justified` plan-frontmatter field that the checker recognizes — so multi-wave phases stop paying a guaranteed extra planner pass and intentionally coupled plans converge instead of stalling. (#3724) diff --git a/.changeset/gallant-tunas-climb.md b/.changeset/gallant-tunas-climb.md deleted file mode 100644 index cbc5c02e6..000000000 --- a/.changeset/gallant-tunas-climb.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4240 ---- -**`quick-batch --resume` no longer duplicates work after a coordinator crash** — a crash between an item's executor finishing and its merge could previously cause resume to dispatch a second executor into a new worktree, silently orphaning the first one's completed work. Resume now recognizes an already-executed item and routes it straight to merge. diff --git a/.changeset/gentle-birds-dance.md b/.changeset/gentle-birds-dance.md deleted file mode 100644 index 8a0204017..000000000 --- a/.changeset/gentle-birds-dance.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4184 ---- -**`/gsd:review` --antigravity: a failed Antigravity lane's stub now carries `agy`'s stderr and no longer asserts the pre-session-stall case when a session verifiably started — a headless tool-permission denial is self-diagnosing instead of mis-signposted. (#3996) diff --git a/.changeset/gentle-geese-hop.md b/.changeset/gentle-geese-hop.md deleted file mode 100644 index 90fddac7e..000000000 --- a/.changeset/gentle-geese-hop.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 3928 ---- -**`/gsd:plan-review-convergence` finds REVIEWS.md on paths with spaces** — the reviews-file lookup was unquoted, so a project path containing a space resolved to nothing and the run aborted blaming the review agent for a file that existed. A path containing a glob metacharacter could silently resolve to a different phase's REVIEWS.md. The path is now resolved directly and quoted, and an unreadable one fails closed with an error naming the expected location. diff --git a/.changeset/gentle-tunas-rest.md b/.changeset/gentle-tunas-rest.md deleted file mode 100644 index 16c3e94a6..000000000 --- a/.changeset/gentle-tunas-rest.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4164 ---- -**Statusline no longer shows milestone complete at 0 of 0 phases** — the 0-of-0 counters a freshly-roadmapped milestone carries no longer read as every-phase-done (string truthiness made the equality vacuous); both the full and compact renderers now require a non-zero denominator. (#3945) diff --git a/.changeset/graceful-finches-wake.md b/.changeset/graceful-finches-wake.md deleted file mode 100644 index 0a3643eac..000000000 --- a/.changeset/graceful-finches-wake.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4092 ---- -**`gsd-node-runner.sh` no longer triggers a permanent, unclearable "⚠ stale hooks" warning** — it was registered in `MANAGED_HOOKS` but shipped without its `gsd-hook-version` header, so up-to-date installs always flagged it as stale. diff --git a/.changeset/graceful-rams-rally.md b/.changeset/graceful-rams-rally.md deleted file mode 100644 index 6946cb73e..000000000 --- a/.changeset/graceful-rams-rally.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4292 ---- -**`state advance-plan` no longer marks a phase complete while sibling plans are still executing** — a stale or wave-raced `Plan: X of Y` counter could write `Phase complete — ready for verification` after 1 of N plans; the decision now comes from disk (every plan summarized) and the call declines with `plans_outstanding` instead. (#4067) diff --git a/.changeset/happy-deer-howl.md b/.changeset/happy-deer-howl.md deleted file mode 100644 index ee5783142..000000000 --- a/.changeset/happy-deer-howl.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4149 ---- -**`gsd-tools commit`, `commit-to-subrepo`, and `pr-subrepo` no longer silently refuse to commit a moved submodule pointer under `diff.ignoreSubmodules=all`** — on git 2.39.x, `git commit` itself (pathspec-scoped or whole-index) consults that config the same way `git diff` does and drops the change, and `pr-subrepo`'s own change-detection probe hid the same submodule bump before it ever reached the commit step. All three commit sites, plus the `pr-subrepo` probe, now pin `diff.ignoreSubmodules=dirty` the same way the pre-existing empty-diff probe in `commit` already did. diff --git a/.changeset/happy-lynx-fly.md b/.changeset/happy-lynx-fly.md deleted file mode 100644 index dac028acf..000000000 --- a/.changeset/happy-lynx-fly.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4331 ---- -**Test machines no longer accumulate immortal 100%-CPU orphan processes when a test runner is killed mid-hang** — the prohibition-enforcement hang fixture busy-looped `while (true) {}`, so a worker orphaned by a chunk timeout, CI cancellation, or Ctrl+C burned a core indefinitely (users found orphans days old); the fixture now parks on a settling 10s timer — still hung for any enforcement bound, ~0% CPU if leaked, and guaranteed to self-terminate. (#4104) diff --git a/.changeset/happy-ravens-zip.md b/.changeset/happy-ravens-zip.md deleted file mode 100644 index a4b69fa4e..000000000 --- a/.changeset/happy-ravens-zip.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4283 ---- -**Partial `.planning` directories now route to initialization recovery** — a bootstrap interrupted after `.planning/PROJECT.md` no longer mis-routes `/gsd:progress` to between-milestones or "no project", nor `resume` to STATE.md reconstruction; both now resume `/gsd:new-project` until the missing REQUIREMENTS.md/ROADMAP.md/STATE.md exist. (#4040) diff --git a/.changeset/humble-newts-greet.md b/.changeset/humble-newts-greet.md deleted file mode 100644 index 8e2cf1294..000000000 --- a/.changeset/humble-newts-greet.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4251 ---- -**The npm-audit CI gate now retries a slow registry instead of failing on one bad moment, and reports a clear timeout error instead of a misleading JSON parse error when it does fail.** A timed-out audit call previously surfaced as `Unexpected end of JSON input` and made exactly one attempt with no retry, so any single transport hiccup against npm's registry failed a required gate. It now retries up to 3 times with backoff before failing, and any failure names the real cause. (#4250, #4260) diff --git a/.changeset/jolly-dogs-hop.md b/.changeset/jolly-dogs-hop.md deleted file mode 100644 index 971aae01a..000000000 --- a/.changeset/jolly-dogs-hop.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4185 ---- -**`/gsd-execute-phase` now runs advisory step hooks at `execute:wave:pre`** — external capabilities can refresh artifacts before executor spawning instead of silently waiting until wave end. (#4148) diff --git a/.changeset/jolly-ravens-parade.md b/.changeset/jolly-ravens-parade.md deleted file mode 100644 index 23c5cfb5c..000000000 --- a/.changeset/jolly-ravens-parade.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Added -pr: 4340 ---- -**`hooks.commit_types` config surface for `gsd-validate-commit.sh`** — projects using `hooks.community: true` can now extend the Conventional Commits type allowlist with a `hooks.commit_types` array in `.planning/config.json` (e.g. `["enhance", "enh", "revert"]`), added to rather than replacing the 10 built-in types. Configured values are validated against a safe-token pattern and the regex/error text now derive from a single source of truth. (#3811) diff --git a/.changeset/kind-finches-hum.md b/.changeset/kind-finches-hum.md deleted file mode 100644 index 906448d4d..000000000 --- a/.changeset/kind-finches-hum.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4178 ---- -**`npm run lint` no longer fails on a leftover Stryker sandbox** — `eslint.config.mjs` now ignores `.stryker-tmp/**`, the scratch directory Stryker itself, `.gitignore` and `stryker.config.mjs` already treat as disposable. A mutation run interrupted before cleanup used to leave a copy of the tree there, and linting that copy reported the path-scoped `local/*` rules as undefined — hundreds of "Definition for rule … was not found" errors on a clean branch. (#4141) diff --git a/.changeset/lane-effort-from-review-config.md b/.changeset/lane-effort-from-review-config.md deleted file mode 100644 index 4d20a9d04..000000000 --- a/.changeset/lane-effort-from-review-config.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4275 ---- -**Cross-AI reviewer lanes no longer take their reasoning effort from the plan checker** — the three lanes that carry a reasoning level on their command line (`codex`, `claude`, `opencode`) resolved it by querying the `gsd-plan-checker` agent through a hardcoded agent id, so under every shipped model profile they ran at that structural verifier's `low`, and because the rendered argument is a command-line config override it silently beat the effort configured for the reviewer CLI itself. At `low` a large plan set could end the model's turn with no final message, leaving an empty lane whose stub read as a crash. Effort is now declared per lane: set `review.effort.codex` (or `.claude`/`.opencode`), leave it unset for the lane's `high` review default, or set `inherit` to emit no argument at all and let your own CLI configuration decide. An unrecognized level falls back to the lane default instead of being forwarded, and the host still clamps the result to what it supports. The empty-output stub now names the effort the lane ran at and distinguishes a clean exit from a timeout, a crash, and a binary that never started. The nine lanes with no effort channel are unchanged: they declared no key before and emit no argument now. Resolving effort in-process also removes up to twelve subprocess spawns per review. (#4255) diff --git a/.changeset/lively-birds-click.md b/.changeset/lively-birds-click.md deleted file mode 100644 index 7c9ca3e79..000000000 --- a/.changeset/lively-birds-click.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Changed -pr: 4163 ---- -**`roadmap analyze`, `gap-checker`, and `init`'s JSON output now distinguish an unreadable phase directory from a genuinely empty one** — a new `context_scope`/`phase_dir_scope` field (`'complete'` or `'unreadable'`) sits alongside the existing `has_context`/`context_read_error` fields, so a permission or I/O failure reading a phase directory is no longer indistinguishable from a phase that simply has no context file yet. `init manager`'s previously-silent read failure (a bare empty catch) now surfaces the same signal. (#4014) diff --git a/.changeset/lucky-jays-travel.md b/.changeset/lucky-jays-travel.md deleted file mode 100644 index 7ff19fdd4..000000000 --- a/.changeset/lucky-jays-travel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4194 ---- -**`/gsd-execute-phase` crash-recovery gate now lists the crashed plan's own commits** — the safe-resume gate grepped a padded, unanchored plan scope, citing other milestones' commits and never the plan's own; all three commit-scope greps are now anchored, zero-pad-tolerant, and bounded to the current milestone tag. (#4003) diff --git a/.changeset/lucky-lynx-cheer.md b/.changeset/lucky-lynx-cheer.md deleted file mode 100644 index ecbda73a2..000000000 --- a/.changeset/lucky-lynx-cheer.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4061 ---- -**Imperative-override injection patterns now tolerate filler words** — a planted phrasing with `all of your` between the verb and `instructions` previously matched nothing; the five narrow verb patterns are replaced by one superset pattern (`ignore|disregard|forget|discard|override`, with `override` and `discard` both covered) so a sentence counts once toward the severity threshold instead of twice. The prompt-guard advisory now renders the same bounded pattern label as the read scanner instead of echoing the raw regex source. (#4016) diff --git a/.changeset/lucky-pandas-commit.md b/.changeset/lucky-pandas-commit.md deleted file mode 100644 index e360390c7..000000000 --- a/.changeset/lucky-pandas-commit.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -type: Fixed -pr: 3816 ---- -**The commit-message hook no longer blocks every heredoc-form commit** — with `hooks.community: true`, `gsd-validate-commit.sh` rejected `git commit -m "$(cat <<'EOF' … EOF)"` with `CONVENTIONAL_COMMITS_VIOLATION` whatever the message said, because its `-m` capture matches across newlines and the message's first line was the literal `$(cat <<'EOF'` rather than the subject. That opener is a standard agent-authored commit idiom, so enabling the toggle — which also carries the session-state and phase-boundary hooks — made that pattern fail every time. - -The subject is now resolved from the captured message before validation, for the canonical form: a single `-m "…"` holding one `$(cat …)` substitution, under git's default `cleanup=whitespace`. Resolution handles the delimiter spellings bash does not expand (`<<'EOF'` and `<<\EOF`, with or without `<<-`, spaced or space-free), the leading tabs `<<-` strips, CRLF line endings, and both directions of `cleanup=whitespace` — leading blank lines are skipped, and trailing whitespace on the subject is not counted against the 72-character limit. - -Everywhere the validated text could differ from the subject git actually receives, resolution is refused and the commit stays blocked exactly as it was before this change. That covers: a `-m '…'` single-quoted argument, in which bash performs no command substitution at all; a bare `<` anywhere in the value made `Current Plan: 4 — blocked on review of 2 PRs` parse as "4 of 2", conclude the phase was over, and write `Status: Phase complete — ready for verification` into the file. A trailing annotation is still accepted on both shapes (`Plan: 2 of 5 in current phase`, `Total Plans in Phase: 5 phases`), and survives the write. - -Advancing rewrites only the leading digits, so the zero-padding width and everything after it survive: `04 of 06` advances to `05 of 06`, widening to `10 of 12` rather than truncating, and the legacy pair no longer collapses `2 of 99` into a bare `3` or `04` into `5`. That holds for **each** spelling independently — a `Plan: 2 of 9` line beside a `Total Plans in Phase: 5` advances to `3 of 9`, keeping its own total, because every field is advanced from its own text rather than re-stamped with the numbers some other field supplied. The `## Current Position` section advances alongside the header for every spelling — plain, bold and pipe-table — so the two can no longer report different plans. - -A document whose two plan positions carry **different numbers** — say `Current Plan: 7` beside `Plan: 2 of 5` — is now refused with `reason: "ambiguous_plan_position"` and both candidates named, rather than advancing one and silently stamping its number onto the other. A `Plan:` line that carries no readable number at all is left exactly as authored instead of being overwritten. When the position cannot be read at all, the error names the accepted shapes rather than asserting a cause it cannot know. - -Two narrowings against the old `parseInt` behaviour, both deliberate. A trailing annotation must be separated from the number by whitespace: `Total Plans in Phase: 5 phases` parses, `5phases` no longer does — `parseInt` read that as `5`, which is the half-parse this change exists to remove. And `Plan: N` paired with a `Total Plans in Phase: M` sibling and no `Current Plan` field is not an accepted shape; it was not accepted before this change either. diff --git a/.changeset/mellow-mice-jump.md b/.changeset/mellow-mice-jump.md deleted file mode 100644 index 626c319b2..000000000 --- a/.changeset/mellow-mice-jump.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Added -pr: 4167 ---- -**Prompt-injection guard advisory output now carries a typed `findings` array** — `gsd-prompt-guard.js`'s `.planning/` write-scan advisory now emits `findings: [{ruleId, match}]` records (mirroring the pattern `gsd-read-injection-scanner.js` already ships) alongside its existing `additionalContext` prose, rendered through a single mapper so the two can never drift. (#3546) diff --git a/.changeset/mellow-moles-run.md b/.changeset/mellow-moles-run.md deleted file mode 100644 index 76bc57f1a..000000000 --- a/.changeset/mellow-moles-run.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Added -pr: 4147 ---- -**`/gsd:plan-phase` now warns when RESEARCH.md/PATTERNS.md predate CONTEXT.md's newest decisions** — a new deterministic pre-check compares each artifact's git commit time against CONTEXT.md's before plan-phase silently reuses it; opt into blocking with `workflow.context_drift_action: block`. (#3348) diff --git a/.changeset/mellow-pumas-zip.md b/.changeset/mellow-pumas-zip.md deleted file mode 100644 index 6fc53d4eb..000000000 --- a/.changeset/mellow-pumas-zip.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4149 ---- -**`/gsd-pause-work` phase/spike/sketch detection now works on macOS** — the #4112 fix removed a shell-syntax bug but left a GNU-only `grep -oP` that macOS's BSD grep silently fails on, so detection resolved to empty. A new lint (`lint-portable-grep`) now catches this class of GNU-only-grep-flag defect in workflow markdown before it merges. (#4112) diff --git a/.changeset/mellow-seals-climb.md b/.changeset/mellow-seals-climb.md deleted file mode 100644 index 46aa6ab77..000000000 --- a/.changeset/mellow-seals-climb.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4284 ---- -**TDD dispatch now correctly embeds `tdd.md` only when a plan is actually TDD** — both executor dispatch backends previously referenced an unassigned `${TDD_APPLICABLE}` placeholder, so the RED/GREEN/REFACTOR procedure could silently be dropped for a real TDD plan or embedded for a non-TDD one with no error. Both backends now resolve TDD-applicability via the single `phase.tdd-applicable` predicate and fail closed if it cannot be resolved, rather than guessing. (#4264, #4265, #4266, #3800) diff --git a/.changeset/mellow-yaks-squeak.md b/.changeset/mellow-yaks-squeak.md deleted file mode 100644 index bf5f64095..000000000 --- a/.changeset/mellow-yaks-squeak.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Added -pr: 4190 ---- -**`quick-batch` core primitives** — new internal library for batching several quick tasks together: collision-safe ID preallocation, a versioned `BATCH.json` manifest, dependency-DAG + file-overlap wave scheduling, resumable state, and exactly-once STATE.md completion. Not yet reachable from any command — the `quick-batch` command itself lands in a later phase. diff --git a/.changeset/merry-wasps-sprint.md b/.changeset/merry-wasps-sprint.md deleted file mode 100644 index 2da8a0e96..000000000 --- a/.changeset/merry-wasps-sprint.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Added -pr: 4160 ---- -**`review.models.cursor` now pins the Cursor reviewer lane's model** — the lane previously discarded any configured model because it declared no `--model` flag; it now injects one exactly like the `codex` lane. (#3653) diff --git a/.changeset/nimble-herons-rest.md b/.changeset/nimble-herons-rest.md deleted file mode 100644 index f68f1e07c..000000000 --- a/.changeset/nimble-herons-rest.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4295 ---- -**TDD dispatch pointers now cite the tdd.md sections that actually carry the material they promise** — the RED/GREEN/REFACTOR pointer in both `execute-plan.md` and `agents/gsd-executor.md` cited a single section for the commit-scope contract, fail-fast rule, and error handling, but only the commit-scope contract lived there; each is now cited correctly. `agents/gsd-executor.md`'s plan-level gate-enforcement rules, previously restated in full alongside `tdd.md`'s own copy, now point at `tdd.md` as the single owner. (#4267, #4269) diff --git a/.changeset/nimble-otters-swim.md b/.changeset/nimble-otters-swim.md deleted file mode 100644 index 76fb1c7e1..000000000 --- a/.changeset/nimble-otters-swim.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4207 ---- -**A full test run can no longer exhaust the system temp filesystem** — the runner now scopes every fixture's temp tree under one per-run root, sweeps it between chunks, fails fast with a named culprit when residue persists, and removes it on exit; previously leaked fixture trees accumulated unbounded until tmpfs `/tmp` filled and the failure surfaced as unrelated `EDQUOT`/`-122` errors. (#4020) diff --git a/.changeset/nimble-quails-climb.md b/.changeset/nimble-quails-climb.md deleted file mode 100644 index e8722d8da..000000000 --- a/.changeset/nimble-quails-climb.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4301 ---- -**`phase.complete` no longer skips to the positionally-last phase on mixed-grammar roadmaps** — completing a phase now advances to the lowest outstanding phase even when the roadmap's rows use the dash form (`- [ ] **Phase N — Name**`); previously only colon-form rows were visible to next-phase selection, so a later phase.add-ingested phase could win and jump `current_phase` seventeen phases ahead. (#4078) diff --git a/.changeset/nimble-tigers-forage.md b/.changeset/nimble-tigers-forage.md deleted file mode 100644 index 5d42e05df..000000000 --- a/.changeset/nimble-tigers-forage.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Added -pr: 4345 ---- -**Reviews-mode disposition records now have a canonical shape** — planning a phase with `/gsd-plan-phase --reviews` writes accepted/deferred review findings into PLAN.md under one `## Review Dispositions Ledger` section instead of each planner run improvising its own format. Entries are grouped per review round and cite REVIEWS.md lines as `L##@{sha}` so a reference still resolves after the next round rewrites the file. (#3806) diff --git a/.changeset/noble-goats-gather.md b/.changeset/noble-goats-gather.md deleted file mode 100644 index 5b2e0423d..000000000 --- a/.changeset/noble-goats-gather.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4117 ---- -**Codex installs no longer ship a hook that cannot load** — with `--codex`, `gsd-context-monitor.js` was staged without the `hooks/lib/` helpers it requires, so it failed with a missing-module error at load, before its own error handling, on every event Codex registers it for. The install still reported success, so the only symptom was a Codex session erroring on each prompt. The helpers a Codex-bundled hook needs are now derived from what the staged scripts actually require, followed through helpers that require other helpers, rather than from a hand-maintained list that could not keep up: the same list had gone stale once already, which is how this broke. Helpers no Codex hook requires are still not shipped, and a hook whose helper is genuinely missing from the source now fails the install loudly instead of installing something that cannot run. Windsurf had the same gap, found in review: both Cascade guards require `hooks/lib/` helpers at load and a fresh `--windsurf` install staged neither, so every `pre_write_code` and `pre_run_command` event failed the same way. Windsurf is now wired onto the same derivation, and its installed guards are executed by the tests rather than only checked for existence. Full-bundle runtimes and Cursor are unaffected — Cursor's staged set is byte-identical. (#4087) (#4098) diff --git a/.changeset/noble-otters-wander.md b/.changeset/noble-otters-wander.md deleted file mode 100644 index bb5517634..000000000 --- a/.changeset/noble-otters-wander.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Added -pr: 4159 ---- -**`workflow.code_review_point` config to run code review per-wave instead of once per phase** — set it to `execute:wave:post` and the automatic code-review step registers at each completed wave instead of at the end of the phase, scoped to what changed since the phase's prior review. Defaults to `execute:post` (today's behavior, unchanged). diff --git a/.changeset/noble-seals-jump.md b/.changeset/noble-seals-jump.md deleted file mode 100644 index 47e95bb5f..000000000 --- a/.changeset/noble-seals-jump.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4349 ---- -**The #3889 chunk-timeout tests now keep testing the timeout diagnostic regardless of the Node line's test-runner shutdown behavior** — the hang fixture returned a never-settling promise that holds no event-loop handle, so whether the chunk actually hung (and got killed by the per-chunk timeout, exercising the diagnostic) was decided by the runtime: on Node 24/26 the runner happens to hold the loop open, but on other lines the child exits on its own in ~60ms and the two timeout assertions silently assert nothing, failing later as a confusing 72ms chunk failure. The fixture now parks on a settling 10s timer (the #4104 idiom): the hang is a property of the fixture on every runtime, it stays ~0% CPU while parked, and it self-terminates if orphaned; a new regression guard pins that property (still hanging past the chunk bound, natural exit). Behavior on Node 24 (the CI/bench matrix line) is unchanged. (#4105) diff --git a/.changeset/olive-moons-listen.md b/.changeset/olive-moons-listen.md deleted file mode 100644 index 6e5442318..000000000 --- a/.changeset/olive-moons-listen.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -type: Fixed -pr: 3879 ---- -**`/gsd-audit-uat` now surfaces a `gaps_found` verification report's frontmatter debt instead of dropping the phase entirely** — a `*-VERIFICATION.md` whose status is `gaps_found` reported zero items, so the file never entered the results and its phase disappeared from the report. `cmdAuditUat` admitted both non-passing statuses, then `parseVerificationItems` honoured only `human_needed` and returned an empty array for the other, standing on a comment that deferred to `plan-phase --gaps` — a different command the audit never reaches. - -Entries already closed are skipped on **both** statuses, so a `human_needed` file whose entries are mostly resolved no longer over-reports either. Closure is read from the parsed fields, so a `truth:` whose text merely mentions "resolution:" is not mistaken for a closed entry. - -What counts as closed follows the key. A `gaps:` entry closes on `status: resolved` and nothing else, matching the rule the `## Gaps` markdown reader already applies, so the same authored entry cannot read closed in one reader and open in the other. A `human_verification:` entry also closes on a bare `resolution:` field, because verifier-written entries record closure that way — but only where no `status:` contradicts it. An entry reading `status: failed` alongside a `resolution:` note is reported, not dropped. - -Scope, stated precisely: this covers gaps recorded in a report's **frontmatter**. A report authored to the template's `## Gaps Summary` prose shape (`gsd-core/templates/verification-report.md`) records its gaps in the body, and those are still not counted. (#3850) diff --git a/.changeset/patient-goats-glide.md b/.changeset/patient-goats-glide.md deleted file mode 100644 index 384a07d65..000000000 --- a/.changeset/patient-goats-glide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Added -pr: 4167 ---- -**Workflow guard advisory output now carries a typed `code` field** — `gsd-workflow-guard.js`'s off-workflow-edit advisory now includes `code: 'WORKFLOW_ADVISORY'` alongside its existing `additionalContext` prose, distinguishing it from the hook's separate force-add block leg (`code: 'WORKTREE_AGENT_FORCE_ADD_FORBIDDEN'`) without substring-matching either message. (#3546) diff --git a/.changeset/patient-jaguars-rally.md b/.changeset/patient-jaguars-rally.md deleted file mode 100644 index 75605916e..000000000 --- a/.changeset/patient-jaguars-rally.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4228 ---- -**Non-TDD executor dispatches no longer embed the full RED/GREEN/REFACTOR protocol three times over** — the cycle is stated once in the canonical `gsd-core/references/tdd.md`, consumers carry pointers, and both dispatch paths load the reference only when the dispatch is actually TDD. (#3990) diff --git a/.changeset/patient-orcas-tumble.md b/.changeset/patient-orcas-tumble.md deleted file mode 100644 index 8b2acddc1..000000000 --- a/.changeset/patient-orcas-tumble.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4322 ---- -**STATE.md progress counters are no longer silently regressed on projects whose asserted milestone has no matching ROADMAP heading** — under the milestone-unbounded (or ROADMAP-absent) condition, every resyncing `state.*` write kept `progress.total_phases` at its stored value but clobbered `completed_phases`, `total_plans`, and `completed_plans` with the under-scoped phase-directory scan; all four counters are now withheld together and keep their stored values. (#4094) diff --git a/.changeset/patient-pumas-frolic.md b/.changeset/patient-pumas-frolic.md deleted file mode 100644 index 8117c1da2..000000000 --- a/.changeset/patient-pumas-frolic.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Added -pr: 4246 ---- -**Two new ESLint rules catch the #4220 Windows CI hang bug class at author time.** `local/require-full-tmpdir-triad` flags a `TMPDIR` environment override (direct or in a child-process `env:` literal) missing `TEMP`/`TMP` — Node never reads `TMPDIR` on Windows. `local/no-unbounded-dirname-walk` flags a `dirname()` ancestor-walk loop with no fixed-point termination guard, which spins forever at a Windows drive root. (#4244) diff --git a/.changeset/patient-ravens-cheer.md b/.changeset/patient-ravens-cheer.md deleted file mode 100644 index 15a84340c..000000000 --- a/.changeset/patient-ravens-cheer.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4311 ---- -**Codex skill edits are backed up on update** — `gsd-file-manifest.json` skills paths now resolve at the runtime's real skills root (`~/.agents/skills`), so user modifications to Codex skills are detected, backed up to `gsd-local-patches/`, and verified by the reapply gate instead of being silently overwritten. (#4086) diff --git a/.changeset/proud-deer-jump.md b/.changeset/proud-deer-jump.md deleted file mode 100644 index bac028b2d..000000000 --- a/.changeset/proud-deer-jump.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4288 ---- -**`verify plan-structure` now flags quantitative acceptance criteria that are traps at HEAD** — plans whose criteria used an exact `grep -c` count, a bulk "all N tests were observed failing" claim, an unquoted $VAR in command position, `wc` output compared by string equality, or a relative `HEAD~N` git anchor passed verification while the criterion was unsatisfiable or vacuous before any work began. (#4024) diff --git a/.changeset/quick-finches-greet.md b/.changeset/quick-finches-greet.md deleted file mode 100644 index 12206f0b4..000000000 --- a/.changeset/quick-finches-greet.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Added -pr: 4083 ---- -**Reviewer lane timeouts can now be configured per-lane** — declare `timeoutConfigKey` on a reviewer lane manifest (nine of the twelve shipped lanes now do, via `review.timeouts.`) to override its frozen wall-clock timeout floor from `.planning/config.json`, instead of being stuck with a value that was right for one repository and wrong for another. For the antigravity lane, its native `agy --print-timeout` flag now derives from the same configured value instead of a second hardcoded literal. (#3274) diff --git a/.changeset/quick-goats-rest.md b/.changeset/quick-goats-rest.md deleted file mode 100644 index cefc8bbb5..000000000 --- a/.changeset/quick-goats-rest.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4004 ---- -`gsd-tools verify artifacts` and `verify key-links` no longer report a phase as fully verified when its `must_haves` block was authored entirely as prose bullets. A block whose items are all bare strings (no checkable `path:`/`from:` entry) is now reported as `invalid` with `total: 0` instead of a silent all-passed GREEN over zero checks, so a phase with no verifiable acceptance evidence can no longer read green. A block that mixes a prose bullet with a real entry is unaffected — the string is skipped and the verdict follows the checkable entry. (#3956) diff --git a/.changeset/quiet-hounds-report.md b/.changeset/quiet-hounds-report.md deleted file mode 100644 index 7d84ce077..000000000 --- a/.changeset/quiet-hounds-report.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 3859 ---- -**A scoped `commit --files` call whose named files are already committed and unmodified now reports `nothing_to_commit` instead of a failed commit carrying your pre-commit hook's rejection message.** The empty-diff case used to reach `git commit`, where a rejecting hook fires before git can report "nothing to commit" — so callers were handed `commit_failed` and a gate message that was true about the repository and irrelevant to the call. Genuine rejections still report `commit_failed` with the hook's message, and `--amend`, missing named paths, and merges or cherry-picks in progress are unchanged. A modified path under `git update-index --assume-unchanged` is still committed exactly as before: `git commit -- ` reads the working tree directly, so the guard compares that content against `HEAD` and stands aside rather than dropping content you named. One further outcome does change: naming a submodule whose work tree is dirty but whose recorded commit has not moved now reports `nothing_to_commit` rather than `commit_failed`, because nothing would have landed. (#3776) diff --git a/.changeset/quiet-otters-listen.md b/.changeset/quiet-otters-listen.md deleted file mode 100644 index 26fade20e..000000000 --- a/.changeset/quiet-otters-listen.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 3916 ---- -**Plan revision no longer treats a checker's fix suggestion as an order** — checker findings fused "what property failed" with "how to fix it" into one `fix_hint` and rendered every hint under a "must fix" heading, so a contract-following planner applied the hint literally even when a smaller mechanism satisfied the same property, or when the hint contradicted a locked decision — with no channel to report the conflict and every attempt burning a revision iteration. Issues now carry a binding `required_property` plus its evidence, `fix_hint` is marked non-binding everywhere it appears, satisfying a blocker through a smaller valid alternative counts as addressing it, and a hint that conflicts with a locked decision, capability guidance, or an existing plan constraint returns `REVISION_CONFLICT` — routed to user choice or the configured plan-review convergence loop without consuming retry budget. Applied across the plan-checker, the UI-spec checker, the shared planner-revision and generic revision-loop contracts, and the plan-phase, quick, ui-phase, verify-work gap-plan and plan-review-convergence flows; the drifted `suggested_fix`, `finding` and `affected_field` field names are reconciled to the plan-checker schema. A conflict never spends retry budget, and a conflict repeating the same `required_property` escalates as a stall so the un-counted path stays bounded. Blockers still block, severity still gates, and the iteration caps and stall escalation still fire. (#3771) diff --git a/.changeset/quote-decimal-frontmatter-scalars.md b/.changeset/quote-decimal-frontmatter-scalars.md deleted file mode 100644 index ef50f1c88..000000000 --- a/.changeset/quote-decimal-frontmatter-scalars.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4165 ---- -**Decimal-shaped frontmatter scalars (e.g. a `22.10` phase id) are now quoted on write**, so a spec-compliant YAML reader preserves them as the exact string instead of reloading `22.10` as the float `22.1` — which collided with `22.1`, a different phase. Exponent, hex, octal and binary forms are quoted likewise. All-digit values (integer counts and zero-padded ids like `02`) stay unquoted as a deliberate scoped trade-off; `gsd_state_version` is now written `"1.0"`, matching the quoted form in the STATE.md template. (#4053) diff --git a/.changeset/serene-badgers-purr.md b/.changeset/serene-badgers-purr.md deleted file mode 100644 index 01f7f9046..000000000 --- a/.changeset/serene-badgers-purr.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4216 ---- -**Legacy Quick Tasks tables migrate automatically** — a STATE.md Quick Tasks table in a pre-registry column format (which `quick-tasks-append` rejects) is now repaired onto the canonical schema by the new `quick-tasks-migrate` command, run automatically before the first append in `/gsd-quick` and `/gsd-fast`; lossless (unmapped columns keep their data in Description), silent no-op when canonical or absent. (#3730) diff --git a/.changeset/serene-bears-travel.md b/.changeset/serene-bears-travel.md deleted file mode 100644 index 367f3aac1..000000000 --- a/.changeset/serene-bears-travel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Added -pr: 4343 ---- -**Executor commits now refuse to land on the planning repo's default/protected branch** — the pre-commit guard in the executor agent widened to run in every isolation mode (not just Claude Code worktrees) and now resolves the repository's actual default branch instead of a hardcoded five-name list, with a new `git.allow_default_branch_commits` config escape hatch for projects that intentionally execute on their default branch. (#3819) diff --git a/.changeset/serene-newts-click.md b/.changeset/serene-newts-click.md deleted file mode 100644 index 4ab5bfd0a..000000000 --- a/.changeset/serene-newts-click.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -type: Added -pr: 4336 ---- -**`query audit-uat` now segments its summary by milestone.** The JSON output adds `summary.current_milestone: {files, items}` and `summary.archived: {files, items, by_milestone}`, so a consumer can read current-vs-archived UAT/verification debt directly instead of re-deriving the `archived_milestone` filter itself. Existing fields (`total_items`, `total_files`, `parse_gap_files`, `by_category`, `by_phase`) are unchanged. (#3783) - - diff --git a/.changeset/serene-yaks-wake.md b/.changeset/serene-yaks-wake.md deleted file mode 100644 index 48f25d92b..000000000 --- a/.changeset/serene-yaks-wake.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4307 ---- -**`verify codebase-drift` no longer misclassifies non-ASCII paths as unmapped drift** — with git's default `core.quotepath`, C-quoted diff paths garbled `affected_paths`/`elements` and flagged documented directories as `new_dir`. Paths are now decoded before classification. (#4081) diff --git a/.changeset/sharp-jaguars-run.md b/.changeset/sharp-jaguars-run.md deleted file mode 100644 index bf7f33638..000000000 --- a/.changeset/sharp-jaguars-run.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4229 ---- -**`claude plugin validate --strict` now runs in CI and covers `agents/`** — a dedicated test.yml job provisions the claude CLI so the C2 tier is a real gate, and the validation fixture includes the agents/ tree the CLI validates by convention. (#3751) diff --git a/.changeset/sharp-orcas-purr.md b/.changeset/sharp-orcas-purr.md deleted file mode 100644 index 9fb71ebfd..000000000 --- a/.changeset/sharp-orcas-purr.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4116 ---- -**`/gsd:review` no longer misdispatches or undercounts reviewer lanes under zsh** — a shell word-splitting bug collapsed multiple selected reviewers onto one bogus iteration when the workflow's dispatch, gate-check, and plan-coverage logic ran under zsh (the macOS default shell); all affected sites across gsd-core/workflows/*.md are fixed, and a new ShellCheck + structural lint gate catches this bug class in CI going forward. (#4109) diff --git a/.changeset/silly-geese-hop.md b/.changeset/silly-geese-hop.md deleted file mode 100644 index 251368f11..000000000 --- a/.changeset/silly-geese-hop.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4281 ---- -Forward Codex adaptive per-agent model and reasoning-effort routing through supported spawn_agent fields while preserving inheritance fallback for older schemas. (#4270) diff --git a/.changeset/silly-pandas-frolic.md b/.changeset/silly-pandas-frolic.md deleted file mode 100644 index 0c5d1fdea..000000000 --- a/.changeset/silly-pandas-frolic.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4158 ---- -**`/gsd-quick` research dispatch uses the researcher persona and model tier** — the quick flow's research step no longer injects the planner persona and planner model into `gsd-phase-researcher`; `init quick` now emits `researcher_model` and the workflow resolves `AGENT_SKILLS_RESEARCHER`, matching `/gsd-plan-phase`. (#3936) diff --git a/.changeset/silly-rams-caper.md b/.changeset/silly-rams-caper.md deleted file mode 100644 index 6eb691b6b..000000000 --- a/.changeset/silly-rams-caper.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Added -pr: 4212 ---- -**`/gsd-quick-batch` batches several quick-shaped tasks together** — one coordinator plans, dispatches, and merges N /gsd-quick-shaped items in a single run (planner/researcher/checker/executor/verifier leaves per item, deterministic wave dispatch and merge, resumable via --resume). Supports --jobs auto|N, --validate, --research, and --file. Use it instead of running /gsd-quick N times when the tasks are independent or lightly interdependent. diff --git a/.changeset/state-empty-field-preserve-following-line.md b/.changeset/state-empty-field-preserve-following-line.md deleted file mode 100644 index ddab005b1..000000000 --- a/.changeset/state-empty-field-preserve-following-line.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4021 ---- -**Updating an empty STATE.md field no longer silently deletes the line beneath it.** When a body field such as `**Status:**` had no value after the colon, `gsd-tools state update` consumed the following line break and overwrote the entire next line — e.g. `**Current Plan:** 2 of 5` vanished with exit 0 and no warning. `stateReplaceField`'s bold and plain patterns now confine the label-to-value gap to same-line whitespace (`[ \t]*` instead of `\s*`), matching the read side, and write a single separating space when the label line had none. The following line is preserved byte-for-byte; pipe-table replacements and non-empty replacements whose label-to-value separator is ordinary space/tab whitespace are unchanged. (#4010) diff --git a/.changeset/steady-birds-hum.md b/.changeset/steady-birds-hum.md deleted file mode 100644 index e2817b6d1..000000000 --- a/.changeset/steady-birds-hum.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4279 ---- -**TDD executor now requires intentional RED evidence before GREEN** — a RED-phase test command that exits nonzero no longer authorizes production edits unless the persisted evidence record shows the TARGET test failing a real assertion. Syntax errors, zero-test discovery, fixture crashes, parser errors, and unrelated assertions classify as INVALID_RED and block GREEN. (#3770) diff --git a/.changeset/steady-outline-marker.md b/.changeset/steady-outline-marker.md deleted file mode 100644 index 90154b4a1..000000000 --- a/.changeset/steady-outline-marker.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4125 ---- -**`/gsd-plan-phase --chunked`'s outline resume-check no longer has a syntax error** — the `### 8.5.1 Outline Phase` step's resume-detection block had an empty `then` clause (only a comment, no command), which is invalid under both bash and zsh if executed literally. (#4113) diff --git a/.changeset/sturdy-bears-sprint.md b/.changeset/sturdy-bears-sprint.md deleted file mode 100644 index 9903cd78d..000000000 --- a/.changeset/sturdy-bears-sprint.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4318 ---- -**`state advance-plan` no longer strands you when `## Current Position` has lost its labeled plan-position lines** — the failure now returns reason `plan_position_unreadable` with the phase directory's on-disk plan/summary counts and the exact labeled lines to re-insert, instead of a bare unparseable error with no recovery path. (#4093) diff --git a/.changeset/sturdy-orcas-snooze.md b/.changeset/sturdy-orcas-snooze.md deleted file mode 100644 index d90d983e8..000000000 --- a/.changeset/sturdy-orcas-snooze.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4173 ---- -**Fixed the coverage gate OOM-crashing on every push to `next`.** The scripts/ coverage-floor check invoked c8's `check-coverage` subcommand, whose handler silently drops the async-merge flag even when it's passed (unlike its `report` sibling, which honors it) — the same OOM class as #4068, but this third script slipped through that fix because adding the flag alone wasn't enough here. Routing the check through `c8 report --check-coverage` instead makes the async-merge flag actually take effect, so coverage now merges incrementally instead of loading every shard's raw data into memory at once and blowing the 8GB CI heap ceiling. (#4172) diff --git a/.changeset/sturdy-pumas-swim.md b/.changeset/sturdy-pumas-swim.md deleted file mode 100644 index c6ddaf4f9..000000000 --- a/.changeset/sturdy-pumas-swim.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4157 ---- -**`state resolve-blocker`, `state update-progress`, `state record-session`, `roadmap update-plan-progress`, and `roadmap annotate-dependencies` now report the real reason for a no-op** — declining paths named the wrong condition, discarded already-computed values, or (in two cases) falsely reported success when nothing changed; all now report accurately and emit a `[gsd-tools] WARNING:` stderr disclosure. (#3957) diff --git a/.changeset/sunny-geese-forage.md b/.changeset/sunny-geese-forage.md deleted file mode 100644 index 81c3e9933..000000000 --- a/.changeset/sunny-geese-forage.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4274 ---- -**Antigravity CLI global skills: corrected the host-integration matrix evidence and pinned the CLI-only install path** — a live `agy` 1.1.17 probe showed the CLI discovers global skills in `~/.gemini/config/skills/` and silently drops everything under its configHome; the runtime layout was already fixed by #3738, and the matrix no longer cites the disproven blog claim while a new test pins the CLI-only probe branch so the silent-drop class cannot regress. (#3747) diff --git a/.changeset/sunny-ravens-leap.md b/.changeset/sunny-ravens-leap.md deleted file mode 100644 index 262b817cc..000000000 --- a/.changeset/sunny-ravens-leap.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4174 ---- -**TDD Audit no longer reads a git trailer token git cannot parse** — the trailer token is renamed gate_status → gate-status, so the per-commit gate trail becomes machine-readable the moment a producer starts writing it; previously every commit read as missing and the section self-suppressed silently. (#3962) diff --git a/.changeset/sunny-voles-snooze.md b/.changeset/sunny-voles-snooze.md deleted file mode 100644 index a060ad7f0..000000000 --- a/.changeset/sunny-voles-snooze.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4140 ---- -**`/gsd-pause-work` no longer fails on its first step** — the Context Detection step's phase/spike/sketch lookups used a $(( construct that POSIX `sh`/dash rejects as a hard syntax error (bash/zsh happened to tolerate it via an undocumented fallback). (#4112) diff --git a/.changeset/tidy-badgers-fly.md b/.changeset/tidy-badgers-fly.md deleted file mode 100644 index 9047ef0c6..000000000 --- a/.changeset/tidy-badgers-fly.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Added -pr: 4156 ---- -**Edge-completeness probe requirements accept an optional `text_en` field** — spec-phase Step 5.5 can now populate an explicit English translation for non-English SPEC requirements, which the shape classifier reads in preference to `text` (`text_en ?? text`). This replaces the #2773 doc-only convention where `text` silently carried the translation; `text` now always keeps the requirement's own wording. (#3717) diff --git a/.changeset/tidy-tunas-wander.md b/.changeset/tidy-tunas-wander.md deleted file mode 100644 index d13c6f16c..000000000 --- a/.changeset/tidy-tunas-wander.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Changed -pr: 4238 ---- -Allow configured agent tool grants to augment installed agent definitions across supported runtimes. diff --git a/.changeset/vivid-cranes-march.md b/.changeset/vivid-cranes-march.md deleted file mode 100644 index 49d8679de..000000000 --- a/.changeset/vivid-cranes-march.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 3953 ---- -**`/gsd-plan-phase` no longer hard-blocks on a CONTEXT.md whose decision titles wrap** — a `` bullet whose bold lead-in runs across a line break is now read as the one decision it is, instead of counting as an unparseable bullet that forced the decision-coverage gate to `could-not-parse`. diff --git a/.changeset/vivid-lynx-romp.md b/.changeset/vivid-lynx-romp.md deleted file mode 100644 index b464cd9d3..000000000 --- a/.changeset/vivid-lynx-romp.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4177 ---- -**Completing a phase no longer jumps backwards into an archived milestone** — on newest-milestone-first roadmaps the collapsed archive below the active milestone leaked into the current-milestone window, so an unchecked phase from a closed milestone could win the next-phase scan. (#3982) diff --git a/.changeset/vivid-pumas-roam.md b/.changeset/vivid-pumas-roam.md deleted file mode 100644 index 2c3ca5a80..000000000 --- a/.changeset/vivid-pumas-roam.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4313 ---- -**Update-check cache is now published atomically** — the statusline update segment no longer intermittently goes blank when several runtimes (Claude Code, Codex, Cursor, ...) share one machine. (#4091) diff --git a/.changeset/vivid-rams-rally.md b/.changeset/vivid-rams-rally.md deleted file mode 100644 index 515a581af..000000000 --- a/.changeset/vivid-rams-rally.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4188 ---- -**ZCode installs: command `` @-refs now resolve to `~/.zcode/gsd-core/` instead of the Claude copy** — the installer's runtime rewrite pass had no ZCode case, so every generated command loaded the Claude runtime's workflow copy and the ZCode-adapted core was never read. Re-running the installer repairs existing installs. (#4002) diff --git a/.changeset/vivid-voles-wander.md b/.changeset/vivid-voles-wander.md deleted file mode 100644 index 332e470c6..000000000 --- a/.changeset/vivid-voles-wander.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Added -pr: 4346 ---- -**Opt-in concurrent per-plan planners in chunked mode** — `/gsd-plan-phase --chunked` can now dispatch the per-plan planner Tasks within one outline Wave concurrently instead of one at a time, via `planning.chunked_parallel` (default `false`). Gated on the runtime's negotiated dispatch capacity, so hosts that cannot usefully background multiple agents stay serial regardless of the setting. (#3777) diff --git a/.changeset/witty-bears-caper.md b/.changeset/witty-bears-caper.md deleted file mode 100644 index ea3d28193..000000000 --- a/.changeset/witty-bears-caper.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4102 ---- -**Plan-coverage manifest miscounted multi-plan reviews under zsh** — the count and bullet list were derived by re-splitting an unquoted string, which bash word-splits by default but zsh does not, so reviews with 2+ plans collapsed onto one manifest entry. (#4099) diff --git a/.changeset/witty-otters-reset.md b/.changeset/witty-otters-reset.md deleted file mode 100644 index 0260dc61a..000000000 --- a/.changeset/witty-otters-reset.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 3808 ---- -**A context compaction no longer permanently disables context-warning escalation** — the monitor's per-session warn state survived `PreCompact`, so after a session's first CRITICAL the immediate-first-warning and WARNING→CRITICAL escalation rules were dead for the rest of the run, and the #1974 resume breadcrumb kept describing the wrong near-miss. A compaction now clears that state, deletes the statusline reading that produced it, and writes a compaction watermark so a reading the statusline re-creates mid-compaction — the old value under a fresh timestamp — is dropped instead of trusted. Escalation and the immediate-first-warning rule are live again on the next cycle. Two bounds on that, both deliberate: readings are suppressed for the 60-second window after a compaction starts plus any accepted clock skew, so first recovery is the watermark plus 61 seconds with no skew and plus 66 seconds for a watermark at the +5s skew limit, because a mid-compaction statusline render is indistinguishable from a genuine post-compaction reading, so a compaction outlasting that window can still surface one stale reading; and the reset is best-effort, degrading to the previous narrowing rather than failing the compaction if the filesystem refuses it. All three of the monitor's per-session files in the temp directory — the statusline bridge, the warn sentinel and the compaction watermark — are now read through one hardened path that refuses anything that is not a plain, bounded regular file, closing a symlink-follow and stall exposure on the bridge read that runs for every tool call. The watermark is read for its shape and sanity, not its writer: a plain regular file planted at the path is honored for at most one window plus the skew, the same bounded residual the warn sentinel already carries. (#3709) diff --git a/.changeset/zesty-cranes-dance.md b/.changeset/zesty-cranes-dance.md deleted file mode 100644 index 8473f2c4a..000000000 --- a/.changeset/zesty-cranes-dance.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4230 ---- -**Executor commit claims are measured, not narrated** — the executor records the pre-plan HEAD and derives `commits:` from `git rev-list` (HALT if code sits uncommitted), `/gsd:verify-work` reconciles the claim against git with the same instrument and flags a mismatch as a BLOCKER, and HANDOFF's `uncommitted_files` comes from `git status --porcelain`. (#3968) diff --git a/.changeset/zesty-ravens-snooze.md b/.changeset/zesty-ravens-snooze.md deleted file mode 100644 index 3062c4341..000000000 --- a/.changeset/zesty-ravens-snooze.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4356 ---- -**Fixed a silent CI failure in the raw-coverage test shards.** `test:coverage:unit:raw` (used by test.yml's sharded lane and release.yml's rc/finalize jobs) could OOM-crash after the test suite itself passed cleanly, showing no error beyond a bare non-zero exit code. diff --git a/.changeset/zesty-seals-frolic.md b/.changeset/zesty-seals-frolic.md deleted file mode 100644 index 2546352e9..000000000 --- a/.changeset/zesty-seals-frolic.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 4181 ---- -**Code-review scope no longer balloons on repos with past milestones** — the diff base for a phase now derives from the phase directory own first commit instead of a milestone-blind commit-subject grep that selected the OLDEST same-numbered phase in history. A 7-file phase could review 3388 files at downgraded depth. All three derivation sites move in lockstep. (#3995) diff --git a/.changeset/zesty-wasps-fly.md b/.changeset/zesty-wasps-fly.md deleted file mode 100644 index bd143b71a..000000000 --- a/.changeset/zesty-wasps-fly.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Fixed -pr: 3744 ---- -**`phase complete` now warns when the ROADMAP `**Requirements**:` line under-selects REQ-IDs** — a range (`REQ-01 … REQ-05`), a glued `;` or `:` delimiter (`REQ-01; REQ-02`), and any non-placeholder wording that selects nothing (`Deferred`, `N/A`) all marked fewer requirements than the line names while still reporting `requirements_updated: true` with zero warnings, and each now emits a warning naming what was selected and what was skipped, carrying a machine-readable kind, without expanding ranges or changing which IDs get marked. (#3697) diff --git a/.changeset/zesty-yaks-tumble.md b/.changeset/zesty-yaks-tumble.md deleted file mode 100644 index d03b47bac..000000000 --- a/.changeset/zesty-yaks-tumble.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Added -pr: 4167 ---- -**Context monitor advisory output now carries a typed `severity` field** — `gsd-context-monitor.js`'s context-budget advisory now includes `severity: 'warning'|'critical'` alongside its existing `additionalContext` prose, so callers can branch on severity without regex-matching the rendered warning text. (#3546) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5436db55a..6d0cf6fa5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,239 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). ## [Unreleased] +## [1.13.0] - 2026-09-06 + +### Added + +- **Bracket-style phase IDs (`[GSD.02] 05: Name`) are now recognized on the read path** — `roadmap`, `validate` and `state` previously matched only the `Phase N:` spelling and the `NN-name` directory shape, so on a project with `phase_id_convention: "bracket"` every phase was invisible: counts fell back to the on-disk directory listing, `get-phase` reported not-found, every `GSD.02-05-slug` directory was reported malformed, and a completed milestone was warned to have unstarted phases. What changes: + + - Milestone scoping recognizes the ADR-canonical `## [GSD.02] Foundation` heading, including the version-less form (no `vN.N`, no status emoji), at any heading level through `###`, and across a milestone split over two headings in either order. A sibling milestone's phases and directories are excluded either way. + - Phase directories resolve, so each bracket phase reports its real `disk_status`, `plan_count` and `summary_count` instead of `no_directory` and zeros, and `completed_phases`, `total_plans` and the progress percent count the whole milestone. `state sync` scopes its own disk scan the same way, so the percent it writes to STATE.md agrees with the read path. + - Bracket-sentinel milestones (`[GSD.999]` icebox and `[GSD.00]` pre-milestone) and the reserved `999` phase token are excluded from phase counts, while retired phases leave the denominator. `validate consistency` and `validate health` now agree on bracket icebox entries instead of one flagging what the other excludes. The deliberately asymmetric phase-0 behavior is detailed below. + - `missing_phase_details` classifies each checklist entry on its own bracket. Two entries sharing a phase token across different brackets previously shared one verdict, decided by which was written first, so a real phase listed under an icebox entry's token was silently dropped from the report. + - `phase_id_convention` resolves against the workstream being read. A workstream that declares its own convention is no longer overridden by the root config, and `--workstream foo` now agrees with `GSD_WORKSTREAM=foo`; workstream progress rollups resolve the convention instead of assuming legacy, so a bracket workstream's phase count comes from its ROADMAP rather than falling back to its directory count. + - `validate health` gains an advisory W021 for opted-in projects: one sub-check flags a phase whose bracket milestone disagrees with its enclosing section, the other flags a phase heading not yet migrated to bracket form. + - `state validate` resolves bracket phase directories, so its drift scan actually runs on a bracket project instead of reporting `no phase directory matches` — and `valid: false` — for a directory that is plainly on disk. + - The `roadmap milestone-scope` probe and the `phase add` / `add-batch` / `insert` milestone-scope guard both read bracket headings. Blind, the probe reported an empty phase set on a bracket ROADMAP before *and* after a write, so the edit-phase rollback check could never fire; and the guard accepted a description embedding `## [GSD.09] Name` — a heading that carries none of the legacy milestone markers yet terminates the window on an opted-in project, silently dropping every later phase out of the milestone scope. A project that has not opted in is unaffected in both cases. + + Every widened read engages only when the resolved `phase_id_convention` is `bracket`; a project that has not opted in compiles the same patterns it did before. `"bracket"` is a read-path opt-in until the migrator and write path land — valid values are documented in `docs/CONFIGURATION.md`. + + Two consequences of landing on top of #3185 are worth stating. First, #3185 moved the legacy heading counter onto the canonical sentinel predicate, which drops a `### Phase 0:` or `### Phase 0.5:` heading from `total_phases`; combined with this PR's mid-migration guard, that legacy-spelled heading is counted on a bracket project and not counted on one that has not opted in. A bracket-spelled bare `0` or `0.x` remains excluded. The bracket counter keeps the narrower `^0\b` rule deliberately, because the canonical predicate also swallows decimal phase IDs such as `00.1`, which is a real phase rather than milestone 0. Second, the shared phase-directory enumerator keeps its `phaseIdConvention = null` destructure default (`phase-locator.cts:375`), and `null` means "resolved, and not bracket" — the lazy resolve-from-config fires only on `undefined` (`roadmap-parser.cts:941`, `:1928`, whose own comment records that "explicit null still means 'resolved and non-bracket'"). Only four of its seventeen call sites thread a resolved convention: `milestone complete` (`milestone.cts:782`) and `state`'s three (`state.cts:979`, `:2303`, `:4672`). The remaining thirteen omit it and therefore still enumerate on the legacy reading — including `progress` (`roadmap.cts:745`), `stats` (`commands.cts:1947`, `:2302`), `phase list` and the init manager view (`init.cts`), and `state sync`'s own scope probe (`state.cts:4795`). On a bracket project those surfaces receive an unscoped or legacy-scoped directory set, not a bracket-scoped one, and their per-entry rendering is likewise unconverted (`cmdProgressRender`'s directory regex, `cmdStats`'s convention-less `extractPhaseToken(dir)` call, the init manager view's `Phase`-literal heading pattern). Widening those call sites is display- and command-surface work deferred to the epic's later PRs; this slice does not claim them. + + The archival and milestone-completion paths DO reach the widened enumerator, and deliberately so: `milestone complete` (`cmdMilestoneComplete`) and `state update-progress` (`cmdStateUpdateProgress`) both call the same shared `listMilestonePhaseDirs` this PR widens, and both now resolve and thread `phase_id_convention` explicitly at their call sites rather than relying on the enumerator's own lazy resolve-from-config default. On a project that has opted into `"bracket"`, `milestone complete` archives the milestone's real bracket-declared phase directories — the same set the read path already reports — instead of failing to recognize them; a `null` / `milestone-prefixed` project's archived set is unchanged. `state update-progress`'s reported and written percent was already correctly scoped (it derives from `buildStateFrontmatter`, which threads its own resolved convention independently); the explicit thread at its own enumerator call is single-derivation hygiene, not a behavior change, and is documented as such in-line (mutation-tested: reverting only this thread leaves every existing assertion on this command green, because the enumerator's own lazy resolve-from-config default answers the same question the explicit thread does). `cmdMilestoneComplete`'s enumerated set is pinned by a test (`tests/adr-612-bracket-phase-counting.test.cjs`, the round-11 BLOCKER block) so a future regression to the pass-all-degrade legacy reading cannot silently move what a bracket project's `milestone complete` archives without failing a test. `state update-progress`'s own call site is pinned differently, matching what it actually gates: not the reported percent, but the #3233 zero-plans no-op — a bracket milestone whose declared phases carry no plans on disk stays a no-op only when a directory that plainly does not belong to the milestone window is correctly excluded from this call site's enumerated set; swept in by a pass-all degrade, the no-op stops firing. (#2761) + + One more disk-side fix lands alongside the above. `listMilestonePhaseDirs`'s sentinel filter (`isSentinelPhaseId`) treated a bare, untagged phase directory under `phase_id_convention: "bracket"` (`0-bootstrap`, no `{CODE}.{MM}-` prefix) as sentinel milestone 0 by falling through to the legacy leading-int rule — silently dropping a real, on-disk, milestone-declared phase directory from `completed_phases`. This mirrors, on the disk side, the exact defect class the heading-side counters (`countRoadmapPhaseHeadings`, `scanMilestonePhaseIds`) already guard against for the identical bare/untagged shape: under bracket convention, milestone 0 is expressed only via an explicit bracket tag, so an untagged leading `0` is a real phase token, not a sentinel. The `999`/icebox reading stays universal. Legacy and milestone-prefixed projects are unaffected (this call site's `convention` argument is only ever `'bracket'` or unset). (#2867) +- **The EoS Registry now lists GSD for Qoder** — discover the independently maintained `cainiao1992/gsd-qoder` protocol-v1 host integration for Alibaba's Qoder CLI and Qoder Desktop, including exact install and uninstall commands, supported interface points, and negotiated host axes. (#4123) (#4278) +- **Quick planning now preserves `plan:pre` guidance across revisions.** `/gsd-quick` renders one hook snapshot and reuses its planner-targeted contributions for the initial planner and `--full`/`--validate` revision planner. Non-planner contributions are omitted. Because security enforcement is enabled by default, Quick plans may now receive `` guidance unless `workflow.security_enforcement` is disabled. (#3778) (#3934) +- **Read-injection scanner advisory output now carries typed `severity` and `source` fields** — `gsd-read-injection-scanner.js`'s Read/WebFetch/WebSearch advisory (already emitting a typed `findings` array since #3523) now also includes `severity: 'LOW'|'HIGH'` and `source` (the scanned file path, URL, or query) alongside its existing `additionalContext` prose. (#3546) (#4167) +- **New `phase.tdd-applicable` query verb** — computes whether the TDD RED/GREEN/REFACTOR procedure applies to a given plan (explicit flag, plan `type: tdd` frontmatter, a task's `tdd="true"` attribute, or the `workflow.tdd_mode` config default), in one place. Also fixes `workflow.tdd_mode`, `workflow.research`, and `workflow.nyquist_validation` config keys, which never actually reached `cmdInitExecutePhase`/`cmdInitPlanPhase`/`cmdInitDebug`/`cmdInitNewMilestone` due to a dead `config.workflow` accessor. (#4273) (#4277) +- **Hook advisory output now carries typed reason-code fields** — `gsd-read-guard.js`'s Write/Edit advisory now includes `code: 'READ_BEFORE_EDIT'` and `fileName` alongside its existing `additionalContext` prose, so callers reading the hook's JSON no longer need to substring-match the advisory text to detect why it fired or which file it named. (#3546) (#4167) +- Verification reports now record a deterministic content fingerprint of their covered inputs (phase PLAN/SUMMARY, mapped requirements, implementation files in the change set); `readVerificationStatus` recomputes it and reports `stale` on any mismatch, fail-closed on a missing/unreadable/confinement-escaping covered file. Legacy reports without fingerprint metadata keep the prior SUMMARY-mtime staleness check unchanged. (#4155) (#4290) +- **`hooks.commit_types` config surface for `gsd-validate-commit.sh`** — projects using `hooks.community: true` can now extend the Conventional Commits type allowlist with a `hooks.commit_types` array in `.planning/config.json` (e.g. `["enhance", "enh", "revert"]`), added to rather than replacing the 10 built-in types. Configured values are validated against a safe-token pattern and the regex/error text now derive from a single source of truth. (#3811) (#4340) +- **Prompt-injection guard advisory output now carries a typed `findings` array** — `gsd-prompt-guard.js`'s `.planning/` write-scan advisory now emits `findings: [{ruleId, match}]` records (mirroring the pattern `gsd-read-injection-scanner.js` already ships) alongside its existing `additionalContext` prose, rendered through a single mapper so the two can never drift. (#3546) (#4167) +- **`/gsd:plan-phase` now warns when RESEARCH.md/PATTERNS.md predate CONTEXT.md's newest decisions** — a new deterministic pre-check compares each artifact's git commit time against CONTEXT.md's before plan-phase silently reuses it; opt into blocking with `workflow.context_drift_action: block`. (#3348) (#4147) +- **`quick-batch` core primitives** — new internal library for batching several quick tasks together: collision-safe ID preallocation, a versioned `BATCH.json` manifest, dependency-DAG + file-overlap wave scheduling, resumable state, and exactly-once STATE.md completion. Not yet reachable from any command — the `quick-batch` command itself lands in a later phase. (#4190) +- **`review.models.cursor` now pins the Cursor reviewer lane's model** — the lane previously discarded any configured model because it declared no `--model` flag; it now injects one exactly like the `codex` lane. (#3653) (#4160) +- **Reviews-mode disposition records now have a canonical shape** — planning a phase with `/gsd-plan-phase --reviews` writes accepted/deferred review findings into PLAN.md under one `## Review Dispositions Ledger` section instead of each planner run improvising its own format. Entries are grouped per review round and cite REVIEWS.md lines as `L##@{sha}` so a reference still resolves after the next round rewrites the file. (#3806) (#4345) +- **`workflow.code_review_point` config to run code review per-wave instead of once per phase** — set it to `execute:wave:post` and the automatic code-review step registers at each completed wave instead of at the end of the phase, scoped to what changed since the phase's prior review. Defaults to `execute:post` (today's behavior, unchanged). (#4159) +- **Workflow guard advisory output now carries a typed `code` field** — `gsd-workflow-guard.js`'s off-workflow-edit advisory now includes `code: 'WORKFLOW_ADVISORY'` alongside its existing `additionalContext` prose, distinguishing it from the hook's separate force-add block leg (`code: 'WORKTREE_AGENT_FORCE_ADD_FORBIDDEN'`) without substring-matching either message. (#3546) (#4167) +- **Two new ESLint rules catch the #4220 Windows CI hang bug class at author time.** `local/require-full-tmpdir-triad` flags a `TMPDIR` environment override (direct or in a child-process `env:` literal) missing `TEMP`/`TMP` — Node never reads `TMPDIR` on Windows. `local/no-unbounded-dirname-walk` flags a `dirname()` ancestor-walk loop with no fixed-point termination guard, which spins forever at a Windows drive root. (#4244) (#4246) +- **Reviewer lane timeouts can now be configured per-lane** — declare `timeoutConfigKey` on a reviewer lane manifest (nine of the twelve shipped lanes now do, via `review.timeouts.`) to override its frozen wall-clock timeout floor from `.planning/config.json`, instead of being stuck with a value that was right for one repository and wrong for another. For the antigravity lane, its native `agy --print-timeout` flag now derives from the same configured value instead of a second hardcoded literal. (#3274) (#4083) +- **Executor commits now refuse to land on the planning repo's default/protected branch** — the pre-commit guard in the executor agent widened to run in every isolation mode (not just Claude Code worktrees) and now resolves the repository's actual default branch instead of a hardcoded five-name list, with a new `git.allow_default_branch_commits` config escape hatch for projects that intentionally execute on their default branch. (#3819) (#4343) +- **`query audit-uat` now segments its summary by milestone.** The JSON output adds `summary.current_milestone: {files, items}` and `summary.archived: {files, items, by_milestone}`, so a consumer can read current-vs-archived UAT/verification debt directly instead of re-deriving the `archived_milestone` filter itself. Existing fields (`total_items`, `total_files`, `parse_gap_files`, `by_category`, `by_phase`) are unchanged. (#3783) (#4336) +- **`/gsd-quick-batch` batches several quick-shaped tasks together** — one coordinator plans, dispatches, and merges N /gsd-quick-shaped items in a single run (planner/researcher/checker/executor/verifier leaves per item, deterministic wave dispatch and merge, resumable via --resume). Supports --jobs auto|N, --validate, --research, and --file. Use it instead of running /gsd-quick N times when the tasks are independent or lightly interdependent. (#4212) +- **Edge-completeness probe requirements accept an optional `text_en` field** — spec-phase Step 5.5 can now populate an explicit English translation for non-English SPEC requirements, which the shape classifier reads in preference to `text` (`text_en ?? text`). This replaces the #2773 doc-only convention where `text` silently carried the translation; `text` now always keeps the requirement's own wording. (#3717) (#4156) +- **Opt-in concurrent per-plan planners in chunked mode** — `/gsd-plan-phase --chunked` can now dispatch the per-plan planner Tasks within one outline Wave concurrently instead of one at a time, via `planning.chunked_parallel` (default `false`). Gated on the runtime's negotiated dispatch capacity, so hosts that cannot usefully background multiple agents stay serial regardless of the setting. (#3777) (#4346) +- **Context monitor advisory output now carries a typed `severity` field** — `gsd-context-monitor.js`'s context-budget advisory now includes `severity: 'warning'|'critical'` alongside its existing `additionalContext` prose, so callers can branch on severity without regex-matching the rendered warning text. (#3546) (#4167) + +### Changed + +- **`/gsd-review` now tells every reviewer the exact plan ids and total count, and grades coverage against them** — a review that silently covers only some of a multi-plan phase is no longer indistinguishable from one that covered every plan. (#3301) (#4084) +- Secret-file read protection moved from installer-written permission deny rules to a managed hook. The Claude Code installer no longer writes `Read(.env)` / `Read(.env.*)` / `Read(.secrets)` into `permissions.deny`, and removes those three strings (byte-equal only) from existing installs on install and uninstall — on Claude Code >= 2.1.259 any `Read()` deny rule made every `cd DIR && grep …` compound prompt for approval, even in `auto` mode. The same protection now ships as the always-on `gsd-secret-read-guard.js` PreToolUse hook (matcher `Read|Grep|Bash`; Kimi `ReadFile|Grep|Shell`; OpenCode/Kilo plugin dispatch), which denies reads of `.env`, `.env.` and `.secrets` — matched case-insensitively — via Read, Grep (explicit path or a selecting glob, judged per brace alternative) and Bash (operands, input redirects, `$( )`/backtick/`<( )` bodies, `git show :`). A shell interpreter (`bash`/`sh`/`zsh`/`dash`/`ksh`) has its script scanned however it arrives — `-c '…'`, a `<( )` file operand, a heredoc / here-string, or a pipe from a knowable `echo`/`printf` source — plus `eval`'s joined operands, a `source`/`.` process-substitution operand, and `find … | xargs cat` pipelines (upstream literal names become the sub-command's read operands). `.env.example` / `.env.sample` / `.env.template` / `.env.dist` stay readable, and existence checks (`[ -f .env ]`, `ls .env*`) pass. Documented gaps: `$VAR` indirection, shell globs, interpreter one-liners, a piped script from a non-`echo`/`printf` source (`cat gen.sh | bash`, `curl … | sh`), reads inside executed scripts, and a Grep `glob: '*'` reaching a non-gitignored `.env`. Breaking: a hand-written deny rule identical to one of the three strings is removed too; re-add it if you want both layers. Cursor, Windsurf, Cline, Copilot, Codex and ZCode have no per-tool hook matcher and are not covered (they never had the deny rules either). (#4236) +- **`/gsd-update` now stops when it cannot resolve an installed update target** — use the installer explicitly for a fresh install. This includes a custom `--config-dir` whose directory name matches no known runtime and has no runtime marker file or env var (previously silently defaulted to `claude`; now intentionally unresolved). (#4153) (#4237) +- **Every workflow now carries response-language coverage, and every directive names inter-tool narration** — previously uncovered workflows (including `/gsd-review` and lazy-loaded mode/step files) now apply a shared or inline directive, and the 44 workflows whose directive covered only "questions, prompts, and explanations" now name narration between tool calls, status updates, progress notes, and findings, so running commentary no longer stays in English beside translated answers. A CI lint (`lint:response-language`) prevents future workflows from shipping uncovered or with the weaker wording. (#2529) (#2558) +- **`/gsd-verify-work` re-verification no longer reopens a closed gap-closure round on an unevidenced new finding** — a Step 7 anti-pattern blocker that isn't a carried-forward gap or a regression on a file touched since the prior pass now needs a red-capable test or another concrete artifact to stay blocking; without one it's recorded as advisory instead of reverting completed work and starting another `--gaps` cycle. (#3304) (#4085) +- **Planner wave assignment now sequences automatic external review after internal fixes** — phases with internal review lanes defer PR creation until accepted fixes land and re-check open-time properties immediately before opening. (#4206) +- **`roadmap analyze`, `gap-checker`, and `init`'s JSON output now distinguish an unreadable phase directory from a genuinely empty one** — a new `context_scope`/`phase_dir_scope` field (`'complete'` or `'unreadable'`) sits alongside the existing `has_context`/`context_read_error` fields, so a permission or I/O failure reading a phase directory is no longer indistinguishable from a phase that simply has no context file yet. `init manager`'s previously-silent read failure (a bare empty catch) now surfaces the same signal. (#4014) (#4163) +- Allow configured agent tool grants to augment installed agent definitions across supported runtimes. (#4238) + +### Removed + +- **Dropped the `test:mutation:since` npm script** — it passed `--since`, which Stryker 9.x does not accept (`error: unknown option '--since'`), so it could not run at all. Nothing invoked it: the mutation gate runs the per-module matrix from `scripts/mutation-matrix.cjs` instead, so no workflow regresses. To see which modules a change puts in scope, run `node scripts/mutation-matrix.cjs --base origin/next --print`. (#4106) (#4179) + +### Fixed + +- **`state` verbs keep the STATE.md body Progress bar in sync with frontmatter `progress.percent`** — 13 of 15 verbs rewrote the frontmatter percent while the body bar stayed stale (issue #4213: frontmatter 75, body bar still 50), so the two surfaces silently diverged on every record-session, add-decision and milestone switch. The bar is now rewritten through one shared helper on the write seam, keeping the bold `**Progress:**` status line the target even when a free-text line above it starts with `Progress:`, and an out-of-range persisted percent renders a clamped 0-100 bar instead of crashing the write. (#4213) (#4231) +- **Background waits no longer emit a red ScheduleWakeup validation error** — while a background subagent (researcher/planner/checker or the manager dashboard's dispatch) was in flight, the orchestrator could literalize "I'll wait" by calling the host's ScheduleWakeup tool with partial arguments, surfacing "`prompt` is required when `stop` is not true."; every GSD wait-instruction site now explicitly forbids wake-up scheduling. (#4079) (#4299) +- **Structural pre-pass no longer aborts for phases introduced in the repository's root commit** — Fallow uses the root commit itself when no parent exists instead of receiving an invalid parent revision. (#4183) (#4215) +- **Blocking guards no longer silently disable themselves when the host stalls** — the six blocking PreToolUse guards are registered (and migrated on existing installs) with a 120 s timeout instead of 5 s; Claude Code treats a timed-out hook as non-blocking, so the old budget dropped the gate exactly under load. (#3981) (#4175) +- **Progress routing preserves decimal phase IDs** — `init progress` now orders parent and inserted phases canonically, and `smart-entry --json` returns the complete current phase token instead of truncating it to an integer. (#4110) +- **Global Runtime Surface materialization no longer breaks after the installing package disappears** — source-dependent global installs provision manifest-owned raw command and agent corpora below `gsd-core/`, while agents-only and empty layouts receive only what their descriptors require. Source selection uses one complete provider for the whole layout, retains the complete legacy marker path, rejects corpora observed during provider selection as missing, hash-mismatched, symlink-escaped, or unexpectedly extended, and preserves local-install behavior. + + Surface materialization now stages every artifact kind before mutation and publishes the candidate surface state last. A source or staging failure therefore leaves the prior state and artifacts untouched. Fresh and upgraded Codex/Claude installs can materially change a surface using only deployed modules and the installed corpus, while an unmigrated source-less deployment fails with an install/upgrade diagnostic before changing state or artifacts. (#4182) +- **`todo complete` honors `--dry-run` and stops corrupting frontmatter** — the flag was accepted and silently ignored (the todo was moved, exit 0, `completed: true` reported), and the `completed:` stamp was written above the opening `---` fence so no fence-locating reader could parse the archived file. `--dry-run` now prints a preview-shaped payload (`dry_run`/`would_*`) and touches nothing; a real completion upserts `completed:` and `status: completed` inside the frontmatter block, and unknown flags fail loudly instead of being dropped. (#4096) (#4325) +- **`/gsd-review` no longer sweeps the run's own prompt/plan copies into `.review-diagnostics/`** — after a review, the preserved diagnostics folder is now dominated by actual evidence (reviewer reports and stderr sidecars) instead of byte-identical duplicates of the prompt, instructions, roadmap, and every plan under review. (#4097) (#4329) +- **`workflow.tdd_mode: true` now actually enforces TDD** — the RED-commit runtime gate no longer requires MVP mode, so the obvious TDD opt-in stops being silently inert on non-MVP phases; the end-of-phase TDD review escalation follows the same decoupling. (#4011) (#4180) +- **/gsd-review no longer down-weights plan-grounded reviews for a citation shape the prompt made impossible** — each plan in the review prompt now carries a repo-relative #### path header, and the budget copies are named after their source plan id instead of a bare index, so source-grounded lanes can cite plans in a form the consensus step resolves. (#3959) (#4170) +- **Windows CI test runs no longer hang indefinitely.** The test runner's temp-sweep protection walk used a POSIX-only termination check that never fired on a Windows drive root, spinning forever and timing out every Windows CI shard. A second, previously-masked bug in the temp-root regression test's own child-process env override (only `TMPDIR`, not `TEMP`/`TMP`) is also fixed, since Windows never reads `TMPDIR`. (#4245) +- **`deferred-items.md` entries written with `*`, `+` or an ordered marker are no longer silently dropped** — the parser recognised only `- `, so a deferred list written with any other standard Markdown list marker contributed zero entries and reported as a clean zero to `audit-open`. An ordered list counts when it starts at `0.` or `1.` or continues a list already open at its level; `1)` is not a marker. Also fixed: a `status:` line inside a fenced code block indented four or more spaces — what a fence under a nested bullet looks like — was not treated as fenced, so a `status: resolved` written as documentation resolved the entry containing it; and an unclosed fence now ends with its own entry instead of hiding every entry after it. `audit-open acknowledge` reads and writes the same grammar — its line selection goes through the reader's own classifier on the headless and (since #3781) the heading-delimited shape alike — so an entry the audit surfaces under any of these markers can be acknowledged, and a heading-delimited file written with one of the newly recognised markers now surfaces its entries for `complete-milestone` to acknowledge in place, where it previously closed over them unseen. (#3702) (#3739) +- **CI shard 1 no longer runs at 92-99% of its timeout cap.** The full-scope unit-test shard balancer now reserves shard 1's fixed aux-suite cost (integration/security/install/slow) before packing unit-test files onto it, instead of leaving shard 1 to carry that cost on top of an equal unit-test share. (#4070) (#4072) +- **`/gsd:progress --do` now routes specific commands before generic keywords, confirms the route before dispatch, and forwards only arguments the target command accepts** — freeform requests like "set up this existing codebase" or "wrap up the spike findings" no longer preempt to the wrong lifecycle command, and no command runs without your confirmation. (#4051) (#4289) +- **Advisory plan-checker findings no longer force a replan** — Dimension 3b (undeclared same-wave coupling, #1954) is retagged to the advisory `info` tier, plan-phase accepts INFO-only checker results instead of entering the revision loop, and planners can declare deliberate coupling with a new optional `coupling_justified` plan-frontmatter field that the checker recognizes — so multi-wave phases stop paying a guaranteed extra planner pass and intentionally coupled plans converge instead of stalling. (#3724) (#3758) +- **`quick-batch --resume` no longer duplicates work after a coordinator crash** — a crash between an item's executor finishing and its merge could previously cause resume to dispatch a second executor into a new worktree, silently orphaning the first one's completed work. Resume now recognizes an already-executed item and routes it straight to merge. (#4240) +- **`/gsd:review` --antigravity: a failed Antigravity lane's stub now carries `agy`'s stderr and no longer asserts the pre-session-stall case when a session verifiably started — a headless tool-permission denial is self-diagnosing instead of mis-signposted. (#3996) (#4184) +- **`/gsd:plan-review-convergence` finds REVIEWS.md on paths with spaces** — the reviews-file lookup was unquoted, so a project path containing a space resolved to nothing and the run aborted blaming the review agent for a file that existed. A path containing a glob metacharacter could silently resolve to a different phase's REVIEWS.md. The path is now resolved directly and quoted, and an unreadable one fails closed with an error naming the expected location. (#3928) +- **Statusline no longer shows milestone complete at 0 of 0 phases** — the 0-of-0 counters a freshly-roadmapped milestone carries no longer read as every-phase-done (string truthiness made the equality vacuous); both the full and compact renderers now require a non-zero denominator. (#3945) (#4164) +- **`gsd-node-runner.sh` no longer triggers a permanent, unclearable "⚠ stale hooks" warning** — it was registered in `MANAGED_HOOKS` but shipped without its `gsd-hook-version` header, so up-to-date installs always flagged it as stale. (#4092) +- **`state advance-plan` no longer marks a phase complete while sibling plans are still executing** — a stale or wave-raced `Plan: X of Y` counter could write `Phase complete — ready for verification` after 1 of N plans; the decision now comes from disk (every plan summarized) and the call declines with `plans_outstanding` instead. (#4067) (#4292) +- **`gsd-tools commit`, `commit-to-subrepo`, and `pr-subrepo` no longer silently refuse to commit a moved submodule pointer under `diff.ignoreSubmodules=all`** — on git 2.39.x, `git commit` itself (pathspec-scoped or whole-index) consults that config the same way `git diff` does and drops the change, and `pr-subrepo`'s own change-detection probe hid the same submodule bump before it ever reached the commit step. All three commit sites, plus the `pr-subrepo` probe, now pin `diff.ignoreSubmodules=dirty` the same way the pre-existing empty-diff probe in `commit` already did. (#4149) +- **Test machines no longer accumulate immortal 100%-CPU orphan processes when a test runner is killed mid-hang** — the prohibition-enforcement hang fixture busy-looped `while (true) {}`, so a worker orphaned by a chunk timeout, CI cancellation, or Ctrl+C burned a core indefinitely (users found orphans days old); the fixture now parks on a settling 10s timer — still hung for any enforcement bound, ~0% CPU if leaked, and guaranteed to self-terminate. (#4104) (#4331) +- **Partial `.planning` directories now route to initialization recovery** — a bootstrap interrupted after `.planning/PROJECT.md` no longer mis-routes `/gsd:progress` to between-milestones or "no project", nor `resume` to STATE.md reconstruction; both now resume `/gsd:new-project` until the missing REQUIREMENTS.md/ROADMAP.md/STATE.md exist. (#4040) (#4283) +- **The npm-audit CI gate now retries a slow registry instead of failing on one bad moment, and reports a clear timeout error instead of a misleading JSON parse error when it does fail.** A timed-out audit call previously surfaced as `Unexpected end of JSON input` and made exactly one attempt with no retry, so any single transport hiccup against npm's registry failed a required gate. It now retries up to 3 times with backoff before failing, and any failure names the real cause. (#4250, #4260) (#4251) +- **`/gsd-execute-phase` now runs advisory step hooks at `execute:wave:pre`** — external capabilities can refresh artifacts before executor spawning instead of silently waiting until wave end. (#4148) (#4185) +- **`npm run lint` no longer fails on a leftover Stryker sandbox** — `eslint.config.mjs` now ignores `.stryker-tmp/**`, the scratch directory Stryker itself, `.gitignore` and `stryker.config.mjs` already treat as disposable. A mutation run interrupted before cleanup used to leave a copy of the tree there, and linting that copy reported the path-scoped `local/*` rules as undefined — hundreds of "Definition for rule … was not found" errors on a clean branch. (#4141) (#4178) +- **Cross-AI reviewer lanes no longer take their reasoning effort from the plan checker** — the three lanes that carry a reasoning level on their command line (`codex`, `claude`, `opencode`) resolved it by querying the `gsd-plan-checker` agent through a hardcoded agent id, so under every shipped model profile they ran at that structural verifier's `low`, and because the rendered argument is a command-line config override it silently beat the effort configured for the reviewer CLI itself. At `low` a large plan set could end the model's turn with no final message, leaving an empty lane whose stub read as a crash. Effort is now declared per lane: set `review.effort.codex` (or `.claude`/`.opencode`), leave it unset for the lane's `high` review default, or set `inherit` to emit no argument at all and let your own CLI configuration decide. An unrecognized level falls back to the lane default instead of being forwarded, and the host still clamps the result to what it supports. The empty-output stub now names the effort the lane ran at and distinguishes a clean exit from a timeout, a crash, and a binary that never started. The nine lanes with no effort channel are unchanged: they declared no key before and emit no argument now. Resolving effort in-process also removes up to twelve subprocess spawns per review. (#4255) (#4275) +- **`/gsd-execute-phase` crash-recovery gate now lists the crashed plan's own commits** — the safe-resume gate grepped a padded, unanchored plan scope, citing other milestones' commits and never the plan's own; all three commit-scope greps are now anchored, zero-pad-tolerant, and bounded to the current milestone tag. (#4003) (#4194) +- **Imperative-override injection patterns now tolerate filler words** — a planted phrasing with `all of your` between the verb and `instructions` previously matched nothing; the five narrow verb patterns are replaced by one superset pattern (`ignore|disregard|forget|discard|override`, with `override` and `discard` both covered) so a sentence counts once toward the severity threshold instead of twice. The prompt-guard advisory now renders the same bounded pattern label as the read scanner instead of echoing the raw regex source. (#4016) (#4061) +- **The commit-message hook no longer blocks every heredoc-form commit** — with `hooks.community: true`, `gsd-validate-commit.sh` rejected `git commit -m "$(cat <<'EOF' … EOF)"` with `CONVENTIONAL_COMMITS_VIOLATION` whatever the message said, because its `-m` capture matches across newlines and the message's first line was the literal `$(cat <<'EOF'` rather than the subject. That opener is a standard agent-authored commit idiom, so enabling the toggle — which also carries the session-state and phase-boundary hooks — made that pattern fail every time. + + The subject is now resolved from the captured message before validation, for the canonical form: a single `-m "…"` holding one `$(cat …)` substitution, under git's default `cleanup=whitespace`. Resolution handles the delimiter spellings bash does not expand (`<<'EOF'` and `<<\EOF`, with or without `<<-`, spaced or space-free), the leading tabs `<<-` strips, CRLF line endings, and both directions of `cleanup=whitespace` — leading blank lines are skipped, and trailing whitespace on the subject is not counted against the 72-character limit. + + Everywhere the validated text could differ from the subject git actually receives, resolution is refused and the commit stays blocked exactly as it was before this change. That covers: a `-m '…'` single-quoted argument, in which bash performs no command substitution at all; a bare `<` anywhere in the value made `Current Plan: 4 — blocked on review of 2 PRs` parse as "4 of 2", conclude the phase was over, and write `Status: Phase complete — ready for verification` into the file. A trailing annotation is still accepted on both shapes (`Plan: 2 of 5 in current phase`, `Total Plans in Phase: 5 phases`), and survives the write. + + Advancing rewrites only the leading digits, so the zero-padding width and everything after it survive: `04 of 06` advances to `05 of 06`, widening to `10 of 12` rather than truncating, and the legacy pair no longer collapses `2 of 99` into a bare `3` or `04` into `5`. That holds for **each** spelling independently — a `Plan: 2 of 9` line beside a `Total Plans in Phase: 5` advances to `3 of 9`, keeping its own total, because every field is advanced from its own text rather than re-stamped with the numbers some other field supplied. The `## Current Position` section advances alongside the header for every spelling — plain, bold and pipe-table — so the two can no longer report different plans. + + A document whose two plan positions carry **different numbers** — say `Current Plan: 7` beside `Plan: 2 of 5` — is now refused with `reason: "ambiguous_plan_position"` and both candidates named, rather than advancing one and silently stamping its number onto the other. A `Plan:` line that carries no readable number at all is left exactly as authored instead of being overwritten. When the position cannot be read at all, the error names the accepted shapes rather than asserting a cause it cannot know. + + Two narrowings against the old `parseInt` behaviour, both deliberate. A trailing annotation must be separated from the number by whitespace: `Total Plans in Phase: 5 phases` parses, `5phases` no longer does — `parseInt` read that as `5`, which is the half-parse this change exists to remove. And `Plan: N` paired with a `Total Plans in Phase: M` sibling and no `Current Plan` field is not an accepted shape; it was not accepted before this change either. (#3791) +- **`/gsd-pause-work` phase/spike/sketch detection now works on macOS** — the #4112 fix removed a shell-syntax bug but left a GNU-only `grep -oP` that macOS's BSD grep silently fails on, so detection resolved to empty. A new lint (`lint-portable-grep`) now catches this class of GNU-only-grep-flag defect in workflow markdown before it merges. (#4112) (#4149) +- **TDD dispatch now correctly embeds `tdd.md` only when a plan is actually TDD** — both executor dispatch backends previously referenced an unassigned `${TDD_APPLICABLE}` placeholder, so the RED/GREEN/REFACTOR procedure could silently be dropped for a real TDD plan or embedded for a non-TDD one with no error. Both backends now resolve TDD-applicability via the single `phase.tdd-applicable` predicate and fail closed if it cannot be resolved, rather than guessing. (#4264, #4265, #4266, #3800) (#4284) +- **TDD dispatch pointers now cite the tdd.md sections that actually carry the material they promise** — the RED/GREEN/REFACTOR pointer in both `execute-plan.md` and `agents/gsd-executor.md` cited a single section for the commit-scope contract, fail-fast rule, and error handling, but only the commit-scope contract lived there; each is now cited correctly. `agents/gsd-executor.md`'s plan-level gate-enforcement rules, previously restated in full alongside `tdd.md`'s own copy, now point at `tdd.md` as the single owner. (#4267, #4269) (#4295) +- **A full test run can no longer exhaust the system temp filesystem** — the runner now scopes every fixture's temp tree under one per-run root, sweeps it between chunks, fails fast with a named culprit when residue persists, and removes it on exit; previously leaked fixture trees accumulated unbounded until tmpfs `/tmp` filled and the failure surfaced as unrelated `EDQUOT`/`-122` errors. (#4020) (#4207) +- **`phase.complete` no longer skips to the positionally-last phase on mixed-grammar roadmaps** — completing a phase now advances to the lowest outstanding phase even when the roadmap's rows use the dash form (`- [ ] **Phase N — Name**`); previously only colon-form rows were visible to next-phase selection, so a later phase.add-ingested phase could win and jump `current_phase` seventeen phases ahead. (#4078) (#4301) +- **Codex installs no longer ship a hook that cannot load** — with `--codex`, `gsd-context-monitor.js` was staged without the `hooks/lib/` helpers it requires, so it failed with a missing-module error at load, before its own error handling, on every event Codex registers it for. The install still reported success, so the only symptom was a Codex session erroring on each prompt. The helpers a Codex-bundled hook needs are now derived from what the staged scripts actually require, followed through helpers that require other helpers, rather than from a hand-maintained list that could not keep up: the same list had gone stale once already, which is how this broke. Helpers no Codex hook requires are still not shipped, and a hook whose helper is genuinely missing from the source now fails the install loudly instead of installing something that cannot run. Windsurf had the same gap, found in review: both Cascade guards require `hooks/lib/` helpers at load and a fresh `--windsurf` install staged neither, so every `pre_write_code` and `pre_run_command` event failed the same way. Windsurf is now wired onto the same derivation, and its installed guards are executed by the tests rather than only checked for existence. Full-bundle runtimes and Cursor are unaffected — Cursor's staged set is byte-identical. (#4087) (#4098) (#4117) +- **The #3889 chunk-timeout tests now keep testing the timeout diagnostic regardless of the Node line's test-runner shutdown behavior** — the hang fixture returned a never-settling promise that holds no event-loop handle, so whether the chunk actually hung (and got killed by the per-chunk timeout, exercising the diagnostic) was decided by the runtime: on Node 24/26 the runner happens to hold the loop open, but on other lines the child exits on its own in ~60ms and the two timeout assertions silently assert nothing, failing later as a confusing 72ms chunk failure. The fixture now parks on a settling 10s timer (the #4104 idiom): the hang is a property of the fixture on every runtime, it stays ~0% CPU while parked, and it self-terminates if orphaned; a new regression guard pins that property (still hanging past the chunk bound, natural exit). Behavior on Node 24 (the CI/bench matrix line) is unchanged. (#4105) (#4349) +- **`/gsd-audit-uat` now surfaces a `gaps_found` verification report's frontmatter debt instead of dropping the phase entirely** — a `*-VERIFICATION.md` whose status is `gaps_found` reported zero items, so the file never entered the results and its phase disappeared from the report. `cmdAuditUat` admitted both non-passing statuses, then `parseVerificationItems` honoured only `human_needed` and returned an empty array for the other, standing on a comment that deferred to `plan-phase --gaps` — a different command the audit never reaches. + + Entries already closed are skipped on **both** statuses, so a `human_needed` file whose entries are mostly resolved no longer over-reports either. Closure is read from the parsed fields, so a `truth:` whose text merely mentions "resolution:" is not mistaken for a closed entry. + + What counts as closed follows the key. A `gaps:` entry closes on `status: resolved` and nothing else, matching the rule the `## Gaps` markdown reader already applies, so the same authored entry cannot read closed in one reader and open in the other. A `human_verification:` entry also closes on a bare `resolution:` field, because verifier-written entries record closure that way — but only where no `status:` contradicts it. An entry reading `status: failed` alongside a `resolution:` note is reported, not dropped. + + Scope, stated precisely: this covers gaps recorded in a report's **frontmatter**. A report authored to the template's `## Gaps Summary` prose shape (`gsd-core/templates/verification-report.md`) records its gaps in the body, and those are still not counted. (#3850) (#3879) +- **Non-TDD executor dispatches no longer embed the full RED/GREEN/REFACTOR protocol three times over** — the cycle is stated once in the canonical `gsd-core/references/tdd.md`, consumers carry pointers, and both dispatch paths load the reference only when the dispatch is actually TDD. (#3990) (#4228) +- **STATE.md progress counters are no longer silently regressed on projects whose asserted milestone has no matching ROADMAP heading** — under the milestone-unbounded (or ROADMAP-absent) condition, every resyncing `state.*` write kept `progress.total_phases` at its stored value but clobbered `completed_phases`, `total_plans`, and `completed_plans` with the under-scoped phase-directory scan; all four counters are now withheld together and keep their stored values. (#4094) (#4322) +- **Codex skill edits are backed up on update** — `gsd-file-manifest.json` skills paths now resolve at the runtime's real skills root (`~/.agents/skills`), so user modifications to Codex skills are detected, backed up to `gsd-local-patches/`, and verified by the reapply gate instead of being silently overwritten. (#4086) (#4311) +- **`verify plan-structure` now flags quantitative acceptance criteria that are traps at HEAD** — plans whose criteria used an exact `grep -c` count, a bulk "all N tests were observed failing" claim, an unquoted $VAR in command position, `wc` output compared by string equality, or a relative `HEAD~N` git anchor passed verification while the criterion was unsatisfiable or vacuous before any work began. (#4024) (#4288) +- `gsd-tools verify artifacts` and `verify key-links` no longer report a phase as fully verified when its `must_haves` block was authored entirely as prose bullets. A block whose items are all bare strings (no checkable `path:`/`from:` entry) is now reported as `invalid` with `total: 0` instead of a silent all-passed GREEN over zero checks, so a phase with no verifiable acceptance evidence can no longer read green. A block that mixes a prose bullet with a real entry is unaffected — the string is skipped and the verdict follows the checkable entry. (#3956) (#4004) +- **A scoped `commit --files` call whose named files are already committed and unmodified now reports `nothing_to_commit` instead of a failed commit carrying your pre-commit hook's rejection message.** The empty-diff case used to reach `git commit`, where a rejecting hook fires before git can report "nothing to commit" — so callers were handed `commit_failed` and a gate message that was true about the repository and irrelevant to the call. Genuine rejections still report `commit_failed` with the hook's message, and `--amend`, missing named paths, and merges or cherry-picks in progress are unchanged. A modified path under `git update-index --assume-unchanged` is still committed exactly as before: `git commit -- ` reads the working tree directly, so the guard compares that content against `HEAD` and stands aside rather than dropping content you named. One further outcome does change: naming a submodule whose work tree is dirty but whose recorded commit has not moved now reports `nothing_to_commit` rather than `commit_failed`, because nothing would have landed. (#3776) (#3859) +- **Plan revision no longer treats a checker's fix suggestion as an order** — checker findings fused "what property failed" with "how to fix it" into one `fix_hint` and rendered every hint under a "must fix" heading, so a contract-following planner applied the hint literally even when a smaller mechanism satisfied the same property, or when the hint contradicted a locked decision — with no channel to report the conflict and every attempt burning a revision iteration. Issues now carry a binding `required_property` plus its evidence, `fix_hint` is marked non-binding everywhere it appears, satisfying a blocker through a smaller valid alternative counts as addressing it, and a hint that conflicts with a locked decision, capability guidance, or an existing plan constraint returns `REVISION_CONFLICT` — routed to user choice or the configured plan-review convergence loop without consuming retry budget. Applied across the plan-checker, the UI-spec checker, the shared planner-revision and generic revision-loop contracts, and the plan-phase, quick, ui-phase, verify-work gap-plan and plan-review-convergence flows; the drifted `suggested_fix`, `finding` and `affected_field` field names are reconciled to the plan-checker schema. A conflict never spends retry budget, and a conflict repeating the same `required_property` escalates as a stall so the un-counted path stays bounded. Blockers still block, severity still gates, and the iteration caps and stall escalation still fire. (#3771) (#3916) +- **Decimal-shaped frontmatter scalars (e.g. a `22.10` phase id) are now quoted on write**, so a spec-compliant YAML reader preserves them as the exact string instead of reloading `22.10` as the float `22.1` — which collided with `22.1`, a different phase. Exponent, hex, octal and binary forms are quoted likewise. All-digit values (integer counts and zero-padded ids like `02`) stay unquoted as a deliberate scoped trade-off; `gsd_state_version` is now written `"1.0"`, matching the quoted form in the STATE.md template. (#4053) (#4165) +- **Legacy Quick Tasks tables migrate automatically** — a STATE.md Quick Tasks table in a pre-registry column format (which `quick-tasks-append` rejects) is now repaired onto the canonical schema by the new `quick-tasks-migrate` command, run automatically before the first append in `/gsd-quick` and `/gsd-fast`; lossless (unmapped columns keep their data in Description), silent no-op when canonical or absent. (#3730) (#4216) +- **`verify codebase-drift` no longer misclassifies non-ASCII paths as unmapped drift** — with git's default `core.quotepath`, C-quoted diff paths garbled `affected_paths`/`elements` and flagged documented directories as `new_dir`. Paths are now decoded before classification. (#4081) (#4307) +- **`claude plugin validate --strict` now runs in CI and covers `agents/`** — a dedicated test.yml job provisions the claude CLI so the C2 tier is a real gate, and the validation fixture includes the agents/ tree the CLI validates by convention. (#3751) (#4229) +- **`/gsd:review` no longer misdispatches or undercounts reviewer lanes under zsh** — a shell word-splitting bug collapsed multiple selected reviewers onto one bogus iteration when the workflow's dispatch, gate-check, and plan-coverage logic ran under zsh (the macOS default shell); all affected sites across gsd-core/workflows/*.md are fixed, and a new ShellCheck + structural lint gate catches this bug class in CI going forward. (#4109) (#4116) +- Forward Codex adaptive per-agent model and reasoning-effort routing through supported spawn_agent fields while preserving inheritance fallback for older schemas. (#4270) (#4281) +- **`/gsd-quick` research dispatch uses the researcher persona and model tier** — the quick flow's research step no longer injects the planner persona and planner model into `gsd-phase-researcher`; `init quick` now emits `researcher_model` and the workflow resolves `AGENT_SKILLS_RESEARCHER`, matching `/gsd-plan-phase`. (#3936) (#4158) +- **Updating an empty STATE.md field no longer silently deletes the line beneath it.** When a body field such as `**Status:**` had no value after the colon, `gsd-tools state update` consumed the following line break and overwrote the entire next line — e.g. `**Current Plan:** 2 of 5` vanished with exit 0 and no warning. `stateReplaceField`'s bold and plain patterns now confine the label-to-value gap to same-line whitespace (`[ \t]*` instead of `\s*`), matching the read side, and write a single separating space when the label line had none. The following line is preserved byte-for-byte; pipe-table replacements and non-empty replacements whose label-to-value separator is ordinary space/tab whitespace are unchanged. (#4010) (#4021) +- **TDD executor now requires intentional RED evidence before GREEN** — a RED-phase test command that exits nonzero no longer authorizes production edits unless the persisted evidence record shows the TARGET test failing a real assertion. Syntax errors, zero-test discovery, fixture crashes, parser errors, and unrelated assertions classify as INVALID_RED and block GREEN. (#3770) (#4279) +- **`/gsd-plan-phase --chunked`'s outline resume-check no longer has a syntax error** — the `### 8.5.1 Outline Phase` step's resume-detection block had an empty `then` clause (only a comment, no command), which is invalid under both bash and zsh if executed literally. (#4113) (#4125) +- **`state advance-plan` no longer strands you when `## Current Position` has lost its labeled plan-position lines** — the failure now returns reason `plan_position_unreadable` with the phase directory's on-disk plan/summary counts and the exact labeled lines to re-insert, instead of a bare unparseable error with no recovery path. (#4093) (#4318) +- **Fixed the coverage gate OOM-crashing on every push to `next`.** The scripts/ coverage-floor check invoked c8's `check-coverage` subcommand, whose handler silently drops the async-merge flag even when it's passed (unlike its `report` sibling, which honors it) — the same OOM class as #4068, but this third script slipped through that fix because adding the flag alone wasn't enough here. Routing the check through `c8 report --check-coverage` instead makes the async-merge flag actually take effect, so coverage now merges incrementally instead of loading every shard's raw data into memory at once and blowing the 8GB CI heap ceiling. (#4172) (#4173) +- **`state resolve-blocker`, `state update-progress`, `state record-session`, `roadmap update-plan-progress`, and `roadmap annotate-dependencies` now report the real reason for a no-op** — declining paths named the wrong condition, discarded already-computed values, or (in two cases) falsely reported success when nothing changed; all now report accurately and emit a `[gsd-tools] WARNING:` stderr disclosure. (#3957) (#4157) +- **Antigravity CLI global skills: corrected the host-integration matrix evidence and pinned the CLI-only install path** — a live `agy` 1.1.17 probe showed the CLI discovers global skills in `~/.gemini/config/skills/` and silently drops everything under its configHome; the runtime layout was already fixed by #3738, and the matrix no longer cites the disproven blog claim while a new test pins the CLI-only probe branch so the silent-drop class cannot regress. (#3747) (#4274) +- **TDD Audit no longer reads a git trailer token git cannot parse** — the trailer token is renamed gate_status → gate-status, so the per-commit gate trail becomes machine-readable the moment a producer starts writing it; previously every commit read as missing and the section self-suppressed silently. (#3962) (#4174) +- **`/gsd-pause-work` no longer fails on its first step** — the Context Detection step's phase/spike/sketch lookups used a $(( construct that POSIX `sh`/dash rejects as a hard syntax error (bash/zsh happened to tolerate it via an undocumented fallback). (#4112) (#4140) +- **`/gsd-plan-phase` no longer hard-blocks on a CONTEXT.md whose decision titles wrap** — a `` bullet whose bold lead-in runs across a line break is now read as the one decision it is, instead of counting as an unparseable bullet that forced the decision-coverage gate to `could-not-parse`. (#3953) +- **Completing a phase no longer jumps backwards into an archived milestone** — on newest-milestone-first roadmaps the collapsed archive below the active milestone leaked into the current-milestone window, so an unchecked phase from a closed milestone could win the next-phase scan. (#3982) (#4177) +- **Update-check cache is now published atomically** — the statusline update segment no longer intermittently goes blank when several runtimes (Claude Code, Codex, Cursor, ...) share one machine. (#4091) (#4313) +- **ZCode installs: command `` @-refs now resolve to `~/.zcode/gsd-core/` instead of the Claude copy** — the installer's runtime rewrite pass had no ZCode case, so every generated command loaded the Claude runtime's workflow copy and the ZCode-adapted core was never read. Re-running the installer repairs existing installs. (#4002) (#4188) +- **Plan-coverage manifest miscounted multi-plan reviews under zsh** — the count and bullet list were derived by re-splitting an unquoted string, which bash word-splits by default but zsh does not, so reviews with 2+ plans collapsed onto one manifest entry. (#4099) (#4102) +- **A context compaction no longer permanently disables context-warning escalation** — the monitor's per-session warn state survived `PreCompact`, so after a session's first CRITICAL the immediate-first-warning and WARNING→CRITICAL escalation rules were dead for the rest of the run, and the #1974 resume breadcrumb kept describing the wrong near-miss. A compaction now clears that state, deletes the statusline reading that produced it, and writes a compaction watermark so a reading the statusline re-creates mid-compaction — the old value under a fresh timestamp — is dropped instead of trusted. Escalation and the immediate-first-warning rule are live again on the next cycle. Two bounds on that, both deliberate: readings are suppressed for the 60-second window after a compaction starts plus any accepted clock skew, so first recovery is the watermark plus 61 seconds with no skew and plus 66 seconds for a watermark at the +5s skew limit, because a mid-compaction statusline render is indistinguishable from a genuine post-compaction reading, so a compaction outlasting that window can still surface one stale reading; and the reset is best-effort, degrading to the previous narrowing rather than failing the compaction if the filesystem refuses it. All three of the monitor's per-session files in the temp directory — the statusline bridge, the warn sentinel and the compaction watermark — are now read through one hardened path that refuses anything that is not a plain, bounded regular file, closing a symlink-follow and stall exposure on the bridge read that runs for every tool call. The watermark is read for its shape and sanity, not its writer: a plain regular file planted at the path is honored for at most one window plus the skew, the same bounded residual the warn sentinel already carries. (#3709) (#3808) +- **Executor commit claims are measured, not narrated** — the executor records the pre-plan HEAD and derives `commits:` from `git rev-list` (HALT if code sits uncommitted), `/gsd:verify-work` reconciles the claim against git with the same instrument and flags a mismatch as a BLOCKER, and HANDOFF's `uncommitted_files` comes from `git status --porcelain`. (#3968) (#4230) +- **Fixed a silent CI failure in the raw-coverage test shards.** `test:coverage:unit:raw` (used by test.yml's sharded lane and release.yml's rc/finalize jobs) could OOM-crash after the test suite itself passed cleanly, showing no error beyond a bare non-zero exit code. (#4356) +- **Code-review scope no longer balloons on repos with past milestones** — the diff base for a phase now derives from the phase directory own first commit instead of a milestone-blind commit-subject grep that selected the OLDEST same-numbered phase in history. A 7-file phase could review 3388 files at downgraded depth. All three derivation sites move in lockstep. (#3995) (#4181) +- **`phase complete` now warns when the ROADMAP `**Requirements**:` line under-selects REQ-IDs** — a range (`REQ-01 … REQ-05`), a glued `;` or `:` delimiter (`REQ-01; REQ-02`), and any non-placeholder wording that selects nothing (`Deferred`, `N/A`) all marked fewer requirements than the line names while still reporting `requirements_updated: true` with zero warnings, and each now emits a warning naming what was selected and what was skipped, carrying a machine-readable kind, without expanding ranges or changing which IDs get marked. (#3697) (#3744) + +### Security + +- **Removed a critical unpatched supply-chain vulnerability from the `lint:ci` toolchain** — the `shellcheck` devDependency pulled in `decompress@4.2.1`, which carries an unpatched critical zip-slip flaw (GHSA-mp2f-45pm-3cg9); replaced with a small dependency-free downloader that fetches a pinned ShellCheck release directly and extracts it without the vulnerable extraction library. (#4120) (#4121) + ## [1.12.0] - 2026-08-30 ### Added