Files
msd-core/CHANGELOG.md
2026-06-09 17:48:37 +00:00

42 KiB
Raw Blame History

Changelog

All notable changes to GSD will be documented in this file.

Format follows Keep a Changelog.

Unreleased

[1.4.3] - 2026-06-09

Fixed

  • Fix --reapply verifier false-positives on post-#604-rename installs caused by two gaps in pristine-baseline handling:

Gap 1 (verify-reapply-patches.cjs): when backup-meta.json records a pristine_hash for a file but gsd-pristine/ has no corresponding snapshot on disk, the verifier fell to over-broad mode (every upstream-changed line treated as a user-added requirement) and produced FAIL_USER_LINES_MISSING false positives. Fix: return advisory OK_NO_BASELINE reason (non-blocking, exit 0) when a recorded hash is present but the pristine file is absent — the verifier cannot reason correctly without a baseline and must not block.

Gap 2 (new migration 004-prune-stale-pristine-snapshots): migration 003 removed legacy get-shit-done/ runtime files but left gsd-pristine/get-shit-done/ orphan snapshots in place. Those stale snapshots referenced get-shit-done/... key paths that no longer match the active gsd-core/... layout, contributing to FAIL_INSTALLED_MISSING false reports. Fix: add a new migration (not editing 003, to preserve its checksum) that removes all files under gsd-pristine/get-shit-done/. (#934) (#937)

  • /gsd-update changelog preview no longer silently fails — the installer now copies scripts/changeset/ and scripts/lib/ into the runtime config dir so $GSD_DIR/scripts/changeset/cli.cjs resolves at runtime; update.md was updated to use the correct installed path and to surface an explicit error if the CLI is missing rather than swallowing it. (#938)
  • plan-review-convergence now runs gsd-plan-phase inline instead of inside Agent() — both sites that previously wrapped gsd-plan-phase in Agent() (initial planning + replan loop) have been changed to bare Skill() calls at depth 0. On Claude Code, a depth-1 Agent has no Agent tool, so a wrapped plan-phase could never spawn gsd-planner or gsd-plan-checker — the replan loop silently failed to produce a revised plan whenever HIGH concerns were found. Running plan-phase inline from the depth-0 orchestrator (which retains the Agent tool) restores the full planner→checker sub-agent chain. A new structural guard test (bug-936-no-nested-spawner-wrap.test.cjs) statically scans all workflow files and fails if any workflow wraps a spawner orchestrator in Agent() without a RUNTIME != claude carve-out, preventing regression. (#936) (#939)

[1.4.2] - 2026-06-09

Fixed

  • /gsd-plan-phase, /gsd-execute-phase, /gsd-autonomous no longer carry context: fork — these are spawning orchestrators; a forked subagent context has no Agent tool, preventing them from spawning the subagents they require. effort: xhigh is preserved. Fixes /gsd:autonomous halting with "running as a forked subagent" on 1.4.1 (#921). Also replaces the introspection-based Agent-availability check in plan-phase's <runtime_compatibility> block with an attempt-based gate: the workflow now always attempts the Agent() call and only stops if a real tool-unavailable error is returned, eliminating false-negative aborts in top-level sessions (#922). (#921)
  • gsd-context-monitor.js now echoes the actual invoking hook event name — instead of hardcoding hookEventName: "PostToolUse" (or "AfterTool" for Gemini), the hook reads data.hook_event_name from the stdin payload and falls back to the runtime heuristic only when the field is absent or blank; this fixes Claude Code rejecting hook output with "expected Stop but got PostToolUse" when the monitor is invoked by the Stop, SubagentStop, or PreCompact hooks registered in PR #821. (#925) (#926)

[1.4.1] - 2026-06-09

Changed

  • Added no-drift guard tests (tests/issue-57-runtime-install-no-drift.test.cjs) that protect the Runtime Install Policy Module boundary (ADR-58) and the explicit Runtime Config Adapter Registry (#60). They fail loudly when supported-runtime metadata is added to an installer call site (allRuntimes, the interactive runtimeMap menu) without a matching registry adapter entry, or when config-mutation dispatch escapes the registry's declared install surfaces — catching reintroduction of the scattered per-runtime branching those seams removed. (#867)

Fixed

  • profile-pipeline temp output now lands under the reaped GSD temp root. cmdExtractMessages and cmdProfileSample previously created their output directories directly in os.tmpdir() root (gsd-pipeline-* / gsd-profile-*), which reapStaleTempFiles never scans (it only scans GSD_TEMP_DIR = os.tmpdir()/gsd). The directories accumulated forever. Both sites now call ensureGsdTempDir() and create under GSD_TEMP_DIR. Also adds missing after/afterEach teardown to four test fixtures that leaked gsd-* temp dirs on every npm test run. (#866) (#879)
  • gsd_run launcher shim now probes all non-Claude runtime homes before failing. The shim's last-resort detection previously stopped at $HOME/.claude, causing a false-positive fatal error on every non-Claude runtime (Hermes, Cursor, Codex, Copilot, Windsurf, Augment, Trae, Qwen, CodeBuddy, Cline, Grok, Antigravity, OpenCode, Kilo) when RUNTIME_DIR was unset and gsd-tools was not on PATH. The snippet now probes each runtime's config directory (respecting HERMES_HOME, CURSOR_CONFIG_DIR, CODEX_HOME, etc. with sensible $HOME-relative defaults) before emitting the install error. (#903)
  • validate health and validate consistency no longer emit false-positive W007 warnings for projects using checklist-style ROADMAP.md phases. buildRoadmapPhaseVariants() in src/validate.cts previously used only a heading-style regex (## Phase N: name), silently ignoring the supported checklist format (- [x] **Phase N: name**). This caused every on-disk phase directory to trigger W007 ("exists on disk but not in ROADMAP.md") when the project's ROADMAP used checklist-only notation. The fix adds a second regex pass mirroring the existing buildNotStartedPhaseVariants() approach. Additionally, cmdValidateConsistency() in src/verify.cts had a duplicate inline heading-only regex with the same gap — refactored to delegate to buildRoadmapPhaseVariants() (DRY). (#892) (#893)
  • init execute-phase and cmdCommit now produce correct branch_name when project_code is set — the {phase} substitution in phase_branch_template now calls normalizePhaseName(), stripping the project-code prefix and zero-padding the number, so the generated branch is e.g. gsd/phase-01-foundation instead of gsd/phase-CK-01-foundation. Both the execute-phase output path (src/init.cts) and the pre-execution commit path (src/commands.cts) are fixed. (#904) (#904)
  • syncStateFrontmatter no longer strips current_phase, current_phase_name, current_plan, and progress from STATE.md — when body annotations are absent (e.g. after an agent rewrites the body), the existing frontmatter values for those scalars are now preserved, mirroring the fallback already applied in cmdStateJson. (#905) (#905)
  • Top-level Claude Code /gsd-plan-phase now always spawns the researcher/planner/plan-checker agents instead of collapsing them inline — a <runtime_compatibility> block after </available_agent_types> makes the Agent-availability requirement explicit and documents that the workflow fails-closed (stops with a clear log message) in genuinely Agent-less contexts; seven "ORCHESTRATOR RULE — CODEX RUNTIME" labels are renamed to "ALL RUNTIMES" so the guard applies universally; execute-phase.md scopes its existing "Other runtimes" inline-fallback prose to non-Claude contexts, preserving the #853 backgrounded-agent behaviour. (#913) (#913)
  • /gsd-manager and /gsd-autonomous --interactive no longer silently skip worktree isolation and independent verification on Claude Code. They dispatched plan/execute as background agents, but a backgrounded Claude Code agent has no Agent/Task tool and cannot spawn the nested executors, plan-checker, or verifier — so isolation and verification silently never ran. Both workflows now resolve the runtime and run plan/execute inline on Claude Code; background dispatch is kept on runtimes that support nested subagents. (#863)
  • Installer no longer leaks gsd-cmd-rewrites-* temp directories. Each install that emitted slash commands left one fs.mkdtempSync directory under the system temp root; on tmpfs /tmp hosts these accumulated and consumed RAM-backed storage. installRuntimeArtifacts() now removes the temp copy in a finally once command files are copied. (#862)
  • Corrected the installer --help profile skill counts: core now shows 8 (was 7) and standard shows 14 (was 13), both derived from PROFILES so they can't drift again; the full line drops the stale hardcoded 66 for all skills. (#834) (#847)

[1.4.0] - 2026-06-08

Added

  • Research is now cached, curated-first, and code-governed — a content-addressed Research Store (per-source TTL), a single provider waterfall with confidence tiers, and registry-API package legitimacy replace the per-agent prose waterfall and the slopcheck bolt-on. (#664) Confidence is now verification-evidence-driven: provider identity alone no longer yields HIGH; HIGH requires ground-truth corroboration (e.g. legitimacyVerdict: 'OK'), authority alone caps at MEDIUM, and SLOP caps at LOW. (#664)
  • /gsd:plan-phase now accepts a --granularity <coarse|standard|fine> flag to override the configured planning granularity for a single invocation. The flag takes precedence over granularities.planning, top-level granularity, and planning.granularity config. Invalid values are rejected. (#703) (#750)
  • gsd-core can now be installed as a native Claude Code plugin — a new .claude-plugin/plugin.json manifest enables installing gsd-core via claude plugin install or the zero-friction ~/.claude/skills/ auto-load path (gsd-core@skills-dir), with slash commands auto-namespaced as /gsd-core:<command> (e.g. /gsd-core:plan-phase) and lifecycle management via claude plugin enable|disable|update. gsd-core's always-on guard and update hooks are wired for the plugin path through hooks/hooks.json using ${CLAUDE_PLUGIN_ROOT}. This is additive — the existing npm / file-copy installer is unchanged. (#797)
  • Installer pre-populates permissions.allow/deny for Claude Code — fresh Claude Code installs now receive GSD's known-safe tool-call patterns (Bash(npx gsd-core *), Read(.planning/*), Write(.planning/*), Read(STATE.md), Write(STATE.md)) in settings.json out of the box, eliminating first-run approval prompts. A deny block for credential files (Read(.env), Read(.env.*), Read(.secrets)) is also added for defense-in-depth. The merge is additive and idempotent; existing user-set entries are preserved. Uninstall removes only GSD-owned entries. (#768) (#819)

Added: register newly-available Claude Code lifecycle hooks — SubagentStop, Stop, PreCompact (all wired to gsd-context-monitor for context-headroom warnings), and FileChanged (matcher: config.json, wired to new gsd-config-reload.js hook that hot-reloads .planning/config.json context mid-session). Also updates hooks/hooks.json (plugin manifest) and managed-hooks-registry for drift-guard coverage (#770). (#821)

  • Gemini installs now register three additional hook events — BeforeAgent, AfterAgent, and BeforeModel — wired to gsd-context-monitor.js for per-turn context headroom tracking. Previously only SessionStart, BeforeTool, and AfterTool were registered. The installer also detects hooksConfig.enabled: false in the user's Gemini settings.json and emits a clear warning, surfacing the silent failure mode where all hooks are registered but never execute. (#776) (#829)
  • Cross-runtime command enrichment in the installer. Gemini CLI commands now use native {{args}} interpolation (translated from Claude's $ARGUMENTS) so typed arguments interpolate into the prompt body, and /gsd:progress injects live project state via a fixed, injection-safe !{cat .planning/STATE.md 2>/dev/null} shell block. Qwen Code skills now carry a numeric priority field so the most-used main-loop workflows (new-project, plan-phase, execute-phase, …) surface first in the /skills list. The OpenCode per-command model/agent/subtask enrichment was evaluated and intentionally not implemented — model would reintroduce the ProviderModelNotFoundError regression that the converter deliberately guards against for non-Anthropic providers (#1156), subtask/agent change execution semantics for GSD's interactive commands, and variant is not in the OpenCode command schema. (#778) (#825)
  • Emit native on-demand skills (skills/<name>/SKILL.md) for the OpenCode-family runtimes (OpenCode and Kilo) at install time, in addition to the existing flat command/ and file-based agents/ surfaces. OpenCode and Kilo share a config schema and both discover skills from skills/<name>/SKILL.md; the installer now stages each GSD command as a skill with minimal, spec-compliant frontmatter (name matching the directory, description 1–1024 chars) via a shared OpenCode-family skill writer. Skills respect the active install profile (core/minimal stage only their subset) and are removed on uninstall. (#784) (#810)
  • gsd install --cursor now writes .cursor/commands/gsd-<name>.md in addition to the existing .cursor/skills/ surface. Cursor 1.6 introduced plain-markdown slash commands (no frontmatter) in .cursor/commands/; they appear in the / menu in the Agent input. Each command file is generated from the same source as the skill but with frontmatter stripped and Cursor-specific content transforms applied (convertClaudeCommandToCursorCommand). The skills surface is unchanged — both surfaces are written on every install. (#803)
  • The GitHub Copilot installer now reaches lifecycle-hook and instruction parity with other first-class runtimes. It emits a self-contained sessionStart hook config (.github/hooks/gsd-session.json for local installs, ~/.copilot/hooks/gsd-session.json for global) and writes AGENTS.md at the repository root (which Copilot CLI reads as primary instructions) alongside copilot-instructions.md. The hook is an inline command hook with no separate script file, so it cannot dangle. Both artifacts are removed — with user-authored content preserved — on --uninstall. (#786) (#804)
  • Elevate the Cline runtime to hook parity. The installer now emits the Cline .clinerules/ directory form (.clinerules/gsd.md) instead of a single .clinerules file, adds a .clinerules/hooks/PreToolUse lifecycle hook (Cline v3.36+ JSON stdin → {cancel,errorMessage,contextModification} protocol; guards .planning/ artifacts and fails open), and merges GSD instructions into the cross-tool global ~/.agents/AGENTS.md target on global installs. A legacy single-file .clinerules is migrated to the directory form in place, and --uninstall removes the new artifacts and strips the GSD block from ~/.agents/AGENTS.md. (#787) (#803)
  • Qwen Code installs now register three additional hook events that Qwen Code supports beyond Claude Code: SubagentStop, Stop, and PreCompact — all wired to gsd-context-monitor.js for context headroom tracking at subagent completion, model stop, and pre-compaction. These events are Qwen-only; Claude Code installs are unchanged. UserPromptSubmit is deferred: gsd-prompt-guard exits unless tool_name is Write|Edit, making it a no-op for that payload shape. (#788) (#807)
  • CodeBuddy (Tencent) installs now emit /gsd-* slash commands. A --codebuddy install writes commands/gsd-<name>.md files to ~/.codebuddy/commands/ so GSD workflows are invokable from CodeBuddy's / menu (/gsd-phase, /gsd-ship, etc.), matching the integration depth of other fully-elevated runtimes (#789). The existing skills/gsd-<name>/SKILL.md files are now emitted with user-invocable: false so they stay out of the / menu — the commands surface is the single / entry point (no duplicate entries) and skills remain available for model invocation. Subagents (~/.codebuddy/agents/) were already emitted and are unchanged. Uninstall removes the gsd-* command files while preserving user-owned commands. No mcp.json is written — gsd ships no MCP server and CodeBuddy's mcp.json only registers external MCP servers.
(#830)
  • Augment installs now emit slash command definitions alongside skills. A global --augment install writes commands/gsd-<name>.md files to ~/.augment/commands/ in addition to the existing skills/gsd-<name>/SKILL.md files, matching the integration depth of other fully-elevated runtimes and allowing Auggie users to invoke GSD as slash commands (/gsd-phase, /gsd-ship, etc.) without manual configuration (#790). Content rewrites (path normalisation and Augment-specific branding) are applied at install time. Uninstall removes the gsd-* command files while preserving user-owned commands. mcpServers registration is explicitly excluded — gsd ships no MCP server and does not register third-party servers. (#801)
  • Issues are now checked for duplicates when opened: a no-LLM title-similarity check posts a challenge comment and applies a possible-duplicate label when a new issue closely matches existing open ones. Flagged issues that go unanswered for 24h are auto-closed as duplicates (reply, or react 👎 to the bot comment, to keep one open); a reply clears the label and routes to needs-maintainer-review. (#836) (#843)
  • Cursor now receives GSD lifecycle hooks via .cursor/hooks.json — a sessionStart hook injects the current workflow state as context at session start, and a postToolUse hook nudges the agent to update .planning/ after write-class operations, bringing Cursor to baseline hook parity with Gemini and Claude Code. (#777)
  • Gemini CLI extension package — gsd-core now ships a gemini-extension.json manifest (plus a GEMINI.md context payload) at the repository root, so Gemini CLI users can install, update, and remove GSD through Gemini's own extension lifecycle: gemini extensions install https://github.com/open-gsd/gsd-core, gemini extensions update gsd-core, gemini extensions uninstall gsd-core, and gemini extensions link <path> for local dev. The extension is discoverable in gemini extensions list and loads GSD's operating context into every session. Additive — the existing npx gsd-core --gemini installer (which provides the /gsd:* slash commands) is unchanged. (#775) (#775)
  • New agent_skills_security.trusted_global_roots config — opt-in allowlist of trusted root directories so symlinked global: agent skills whose real path resolves outside the default skills dir (e.g. ~/.claude/skills) are accepted; default [] is byte-identical and preserves the symlink-escape guard. (#754)
  • Added /gsd-update --next (alias --rc) to install or refresh from the @next RC dist-tag (ADR #660). A new parse_update_channel workflow step resolves the channel from $ARGUMENTS; the version check and all three npx install invocations thread $TAG instead of hardcoding @latest. When --next is used the version-comparison output gains a Channel: next (RC) banner so the user knows they are leaving the stable line; omitting the flag keeps @latest behavior byte-for-byte unchanged. check-latest-version.cjs gains ALLOWED_TAGS, buildViewArgs, and resolveTag exports, with an allowlist guard (enforced at both the CLI and function boundary) that rejects any dist-tag other than latest/next. (#815) (#839)

Changed

  • /gsd:plan-phase --research-phase <N> now auto-uses an existing RESEARCH.md instead of prompting update/view/skip. When research already exists and neither --research nor --view is passed, it emits a one-line notice and exits cleanly, matching the promptless behavior of standard /gsd:plan-phase <N>. Pass --research to force-refresh or --view to print the existing research. (#159) (#718)
  • Retire the installer's one-off runtime directory helpers (getGlobalDir/getOpencodeGlobalDir/getKiloGlobalDir) and consolidate per-runtime global config-dir resolution onto the single canonical projection runtime-homes:getGlobalConfigDir, extended with the --config-dir override and the opencode/kilo *_CONFIG file-path precedence. Behavior-preserving across all 15 install runtimes. (#56) (#802)
  • Make per-runtime config-mutation dispatch in the installer explicit: a new runtime config adapter registry maps each supported runtime to a typed config intent (install surface, shared-settings gate, finish-phase permission writer), and install()/finishInstall() dispatch by resolved intent instead of inline runtime === '...' branching. Behavior-preserving; unknown runtimes now fail loudly. (#60) (#795)
  • Verification status routing is now owned by a single queryable seam — ship.md and execute-phase.md both consume gsd_run query verification.status instead of re-deriving the passed/gaps_found/human_needed routing independently; the query returns next_action and next_command so per-status prose no longer needs to be kept in sync across files. This also fixes the broad-grep status misread in execute-phase.md where a body status: line (in a code block or copied artifact) could concatenate with the frontmatter value and misroute a valid passed phase; a parity test fails if a new verifier status value lacks a route. (#651) (#755)
  • Agent color: frontmatter now uses Claude Code's documented named colors (red/blue/green/yellow/purple/orange/pink/cyan) instead of hex values or the undocumented magenta, so the intended per-agent TUI color differentiation renders reliably across the Claude Code runtime. Display-only metadata; no behavior change. (#771) (#823)
  • Codex installs now register three additional stable hook events (SubagentStart, Stop, PostToolUse) wired to gsd-context-monitor.js, matching the full event coverage available since Codex CLI stabilised these hooks. The SessionStart hook entry gains a commandWindows field on Windows installs so the .cmd shim is used for native execution (Git Bash/MSYS cannot POSIX-exec node.exe directly). Both new-event registration and uninstall paths handle the flat { "EventName": [...] } and nested { "hooks": { "EventName": [...] } } hooks.json shapes. gsd-context-monitor.js and its Windows .cmd sibling are added to the managed-hook allowlist so idempotent re-runs de-duplicate entries correctly. (#772) (#827)
  • Codex CLI installs now emit two enrichments per agent and skill. Agent TOML enrichment: light-tier agents (haiku-equivalent, routingTier: "light" in model-catalog.json) get service_tier = "flex" and model_verbosity = "low" appended to their agent TOML, telling the Codex scheduler to use the flex tier (lower cost, background processing) and suppress verbose token output. Skill TUI chip: each installed gsd-* skill directory now receives an agents/openai.yaml file with interface.display_name and interface.short_description, making the skill appear in the Codex /skills picker with a human-readable name and description drawn from the skill's existing short-description frontmatter. Both enrichments are additive and backward-compatible with Codex CLI ≥ 0.130.0. (#774) (#828)
  • Cline global installs now emit skills, not just rules: gsd writes skills to ~/.cline/skills/<name>/SKILL.md for Cline ≥ v3.48.0 (see Cline skills docs), in addition to the existing .clinerules file. Each SKILL.md carries name/description frontmatter (agentskills.io) with paths rewritten to the .cline/ convention. Local installs remain .clinerules-only. The .clinerules rules file continues to be emitted for compatibility, and upgrading over an existing rules-only install emits the new skills on the next run. (#809)
  • Workflow size budget now measures bytes, not lines (#717). tests/workflow-size-budget.test.cjs re-bases its tier ceilings (XL/LARGE/DEFAULT) from line counts to byte counts — deterministic, no tokenizer, and matching the unit vendors bound on (Codex's 32,768-byte project_doc_max_bytes cap). The #597 tighten-only ratchet and per-file semantics are unchanged; the budget's caching-independent quality rationale (context rot / attention budget) is now documented. (#719)
  • The gsd-verifier agent no longer re-runs the full workspace test suite once per must-have during Step 7b spot-checks — it enumerates tests to prove existence and runs a single named test to prove a pass, invoking the full suite at most once per verification. (#753)
  • /gsd-plan-phase, /gsd-execute-phase, /gsd-autonomous now run in an isolated forked context on Claude Code — context: fork in skill frontmatter protects the main session's context budget. These three heavy skills also declare effort: xhigh; quick-status skills /gsd-progress and /gsd-stats declare effort: low. The installer preserves both fields when converting commands to Claude SKILL.md files. Runtimes that do not recognise these fields silently ignore them — no behaviour change on non-Claude runtimes. (#769)
  • /gsd:plan-phase and /gsd:execute-phase no longer eagerly load MVP-only guidance on non-MVP runs — the MVP planner rules, user-story template, Walking-Skeleton template, and MVP+TDD halt-report reference are now Read lazily by the planner/executor only when MVP / Walking-Skeleton / MVP+TDD mode is active, in both the workflow files and the gsd-planner/gsd-executor agent definitions, instead of being @-imported into every run. Behaviour is unchanged; non-MVP planning/execution simply carries less context. (#720) (#746)

Automated codex exec invocations in the review workflow now include --ephemeral (no session-state accumulation across automated/CI runs) and --dangerously-bypass-hook-trust (skip hook-trust prompts for hooks managed by gsd-core itself). These flags apply only to the non-interactive reviewer invocations in gsd-core/workflows/review.md. (#773) (#824)

  • Codex slash-command conversion no longer corrupts inline-wrapped /gsd-… file paths — the install-time converter now identifies a real /gsd-<command> mention by positive boundaries (opening delimiter + no path continuation) instead of an unbounded preceding-character denylist, closing the path-corruption class (#637 → #704) by construction while still converting legitimate backtick-wrapped mentions. (#747)
  • The release pipeline now automatically runs changeset render during the finalize job, promoting .changeset/ fragments into a dated CHANGELOG.md section before publishing — previously a manual step that was routinely skipped (leaving v1.3.0 and v1.3.1 unpromoted, #690). A new --allow-empty flag prevents the verify gate from hard-failing on no-change releases by emitting a dated heading with a _No notable changes._ placeholder when there are zero fragments. (#715)

Fixed

  • /gsd-review --cursor now actually invokes the Cursor agent. Detection probes the cursor-agent headless binary instead of the cursor IDE launcher, the invocation calls the single cursor-agent binary in print mode (not the two-token cursor agent, which the IDE treats as a file path), and the review prompt is passed as a file-path argument rather than piped to stdin (which cursor-agent -p ignores). On failure the captured stderr is surfaced instead of a silent empty result. (#686)
  • No more "gsd-core" console-window flash on Windows. Every gsd-core child process now passes windowsHide: true: the context monitor's record-session spawn, the execGit / execNpm / execTool helpers in shell-command-projection, the gsd-worktree-path-guard and gsd-workflow-guard hook git probes, check-command-router's git log call, and the roadmap-upgrade git status/rev-parse/reset/clean calls — matching the existing gsd-check-update spawn. execNpm (which uses shell: true → cmd.exe and runs on every SessionStart, i.e. every /clear) and the worktree-path guard (which runs on every Edit/Write in a worktree) were the most visible offenders. No behavior change on macOS/Linux, where the flag is ignored. (#688)
  • /gsd-review --agy no longer hangs the whole review on large prompts. On a big, file-path-rich prompt Antigravity's agy -p agentic Cascade can loop on its code_search/grep steps and never converge. The invocation now passes agy's own --print-timeout flag (its native print-mode cap) so a stalled run self-terminates through the tool's own mechanism; on a non-zero exit any partial output is discarded so the existing transcript fallback / "review failed" stub take over. (#689)
  • The roadmap parser now resolves fresh phases of the current milestone in multi-milestone roadmaps. extractCurrentMilestone() scoped the current-milestone window to its ## Phases checklist subsection and stopped at the milestone's own ## Milestone … (Phase Details) heading, so the ### Phase N: detail headers fell out of scope. Any command backed by the parser — init.phase-op (and therefore /gsd:discuss-phase and /gsd:plan-phase), state, roadmap list, and validate health (W006) — could not resolve phases of any milestone after the first until a .planning/phases/ directory already existed, blocking discuss/plan. The parser now also includes the current milestone's (Phase Details) section in scope, anchored to the selected milestone's version token so sibling sub-milestones do not cross-pollinate. (#730) (#748)
  • getGlobalSkillsBase('kilo') now resolves to ~/.kilo/skills — where Kilo Code actually discovers global skills — instead of ~/.config/kilo/skills. Per Kilo Code docs, global skills live in the .kilo directory within HOME (~/.kilo/skills/), independent of the XDG-based config dir at ~/.config/kilo. The kilo.jsonc config dir (~/.config/kilo) and the command/ path used by the installer are correct and unchanged. Blast radius: this corrects the resolved skills-base path used by doctor/status checks and agent-skills-block resolution (init.cjs); the installer writes commands (not skills) for Kilo, so no files were previously being written to the wrong location. (#806)
  • Honor the COPILOT_HOME environment variable when resolving the GitHub Copilot global config directory. Previously a global --copilot install ignored COPILOT_HOME and wrote all artifacts (skills, agents, copilot-instructions.md, the session hook) to ~/.copilot even when the user had relocated their Copilot home, making them undiscoverable by Copilot CLI. Resolution now follows --config-dir > COPILOT_CONFIG_DIR > COPILOT_HOME > ~/.copilot, mirroring the existing CODEX_HOME handling. Uninstall uses the same resolver and stays symmetric. (#812) (#814)
  • Release version bumps now keep runtime manifest versions in sync — .claude-plugin/plugin.json and gemini-extension.json are stamped to match package.json on every npm version, unblocking RC/finalize releases. New version-bearing manifests must be registered in scripts/sync-manifest-versions.cjs (enforced by a regression test). (#845)
  • npx @opengsd/gsd-core upgrades no longer abort with "applied migration checksum changed" — an already-applied installer migration whose recorded checksum drifted (e.g. a shipped body was edited) is now detected and reconciled automatically on the next install, instead of hard-failing the upgrade. Replaces the published-checksum allowlist with general self-healing recovery plus a CI baseline lock. (#675)
  • /gsd-import, /gsd-plan-review-convergence, and /gsd-spec-phase now run on global installs — these workflows resolve gsd-tools via the runtime launcher instead of a hardcoded $HOME path, so they no longer falsely report the tool as "not found" (and stop short) when only a global/shim install is present and no project-local runtime exists. (#642)
  • Worktree wave-cleanup no longer fails when the phase SUMMARY is committed — rescueSummaryArtifacts no longer copies an already-committed SUMMARY into the main checkout, which previously caused git merge --no-ff to abort with a permanent merge_failed (#706). (#709)
  • Phase execution no longer halts with exit 42 (worktree base mismatch) when run on a branch diverged from the default branch (#683). Claude Code forks worktree-isolated executors off the repository default branch (origin/HEAD), so running /gsd-execute-phase on an unmerged milestone/feature branch left every executor without the phase's plan files and tripped the worktree-branch-check guard (100% reproducible, all OSes). Execute-phase now detects this before dispatch and automatically degrades to sequential execution on the main working tree, recommending the permanent fix worktree.baseRef:"head". Both fresh installs and upgrades of GSD Core set worktree.baseRef:"head" in .claude/settings.local.json automatically (no-clobber) when workflow.use_worktrees is enabled (the default); gsd-tools worktree set-baseref remains available for manual use (e.g. after toggling worktrees on later). The exit 42 guard remains as a backstop. (#749)
  • Codex install no longer corrupts launcher paths — shell path segments like ${VAR}/gsd-core/ and $(cmd)/gsd-local-patches are no longer rewritten into a literal $gsd-core token during Codex markdown conversion (#704). (#710)
  • /gsd:surface no longer corrupts installed skill paths — re-surfacing (profile/enable/disable/reset) now applies the same per-runtime path rewrites as install, so SKILL.md bodies keep the correct install target instead of reverting to the converter's default ~/.claude paths. (#817)
  • /gsd:graphify, /gsd:import, and planning agents now resolve gsd-tools on global/shim-only installs — agent and command surfaces that invoked a hardcoded $HOME/.claude/...gsd-tools.cjs path now route through the resolved gsd_run launcher, so the step no longer reports the tool "not found" when there is no project-local runtime. (#707)
  • /gsd:surface no longer mis-names or orphans runtime command files — re-surfacing now writes the same gsd--prefixed command filenames as a fresh install for flat command dirs (Cursor, Augment, OpenCode, Kilo) and preserves user-authored command files instead of deleting them. (#822)
  • /gsd:update reliably previews release notes again — promotes the 1.3.x changelog into dated [1.3.0]/[1.3.1] sections, stops deleting the temp changelog before the human-readable render (no more (changelog unavailable)), and adds a release gate that blocks publishing a version whose CHANGELOG.md section was never promoted. (#694)

Security

  • gsd-tools config-set prototype-pollution guard hardened and regression-tested. The guard that blocks __proto__, prototype, and constructor segments in dotted config keys now uses inline literal comparisons at each property-write site (instead of a pre-loop Set check), so CodeQL's js/prototype-pollution-utility analysis recognises it as a sanitising barrier and code-scanning alert #26 clears. Runtime behaviour is unchanged from #663. Added regression tests that drive schema-valid dynamic-prefix keys (agent_skills.__proto__, agent_skills.constructor, features.__proto__, review.models.constructor) all the way to the guard — these reach setConfigValue past the schema gate and were previously the guard's only untested attack surface. (#751) (#752)
  • Hardened roadmap-phase parsing and config writes — resolved ReDoS in phase-heading/plan-filename regexes (validate/verify/commands/phase), blocked prototype-pollution through dotted config keys in config-set, and pinned qs >= 6.15.2 (DoS advisory). (#665)

1.3.1 - 2026-06-04

Security

  • Bumped hono to clear a moderate npm advisory carried transitively in the dependency tree. (#670)

Fixed

  • Installer-migration checksum drift no longer blocks upgrades — the updater now self-heals when a shipped migration's recorded checksum has drifted, reconciling the stored checksum instead of aborting. Restores upgrades across all OSes after shipped migration bodies were edited in a prior release. (#670)

1.3.0 - 2026-06-04

Added

  • Vertical MVP Slice mode — --mvp flag on /gsd-plan-phase switches the planner from horizontal layer decomposition to vertical feature-slice decomposition (UI→API→DB in one task sequence). On Phase 1 of a new project with no prior phase summaries, also emits SKELETON.md via Walking Skeleton mode. Composable with --tdd: --mvp --tdd produces vertical slices where every behavior-adding task starts with a failing test. Phase-level persistence via **Mode:** mvp in ROADMAP.md applies --mvp automatically without the flag. (#78)
  • /gsd-mvp-phase command — guided MVP planning: prompts for a user story (As a / I want to / So that), runs SPIDR story-splitting check (Spike/Paths/Interfaces/Data/Rules axes), writes **Mode:** mvp to ROADMAP.md, then delegates to /gsd-plan-phase. (#78)
  • MVP-aware UAT framing in verify-phase — when a phase has mode: mvp, the verifier generates a user-flow-first UAT script (walks the feature as a user would) before any technical checks. (#78)
  • MVP progress and stats display — progress and stats commands show Walking Skeleton completion status and per-feature-slice status lines for MVP-mode phases. (#78)
  • Six MVP reference files — planner-mvp-mode.md, skeleton-template.md, user-story-template.md, spidr-splitting.md, execute-mvp-tdd.md, verify-mvp-mode.md — loaded by the planner, executor, and verifier agents when MVP mode is active. (#78)
  • Milestone-prefixed phase ID convention (M-NN) for globally unique phase IDs within a project (#39)
  • getMilestoneFromPhaseId() and getPhaseDirFromPhaseId() helpers in core.cjs (#39)
  • W021 validation rule: fires when a phase ID's integer prefix mismatches its enclosing milestone section (#39)
  • gsd-tools roadmap validate subcommand for convention compliance checking (#39)
  • gsd-tools roadmap upgrade --convention milestone-prefixed migration tool (dry-run by default, --apply to mutate) (#39)
  • phase_id_convention config field (null | 'milestone-prefixed' | 'free-form'), defaults to null (legacy free-form, no breaking change) (#39)

Fixed

  • isDirInMilestone now correctly matches M-NN-style phase directories against milestone-prefixed ROADMAP headings (#39)
  • searchPhaseInContent heading regex now tolerates [bracket-token] scope prefix (e.g., ### [GSD] Phase 2-01:) (#39)
  • README version guidance now uses npm/package metadata as the source of truth — README, localized READMEs, and the docs index no longer present archived release-note or canary-stream numbers as the current GSD Core package version. (#545)

1.2.0 - 2026-05-31

1.2.0 is the current stable @opengsd/gsd-core release. It resumes the public package line after the release-version validation recovery documented in ADR 218 and makes @opengsd/gsd-core / gsd-core the canonical package and CLI identity.

Added

  • Plan-vs-codebase drift guard — plan review can verify generated plans against live source symbols before execution so hallucinated files, APIs, or commands are caught earlier. (#487)
  • Single Package Identity seam — package name, CLI identity, update checks, and installer identity are centralized so @opengsd/gsd-core stays consistent across runtime surfaces. (#499, #517, #521)
  • Cross-provider effort controls and fast-mode-aware routing — model-effort selection works across providers and can adjust routing for faster workflows. (#463)
  • Current public docs and install identity — README/docs now advertise GSD Core, @opengsd/gsd-core, and the gsd-core binary as the canonical user-facing surface. (#519, #523, #540)

Changed

  • SDK shim retired from installer/runtime docs — workflows now route through gsd-tools; dead SDK-shim verification and stale SDK-generated banners were removed. (#522, #515, #510)
  • Release numbering recovered at 1.2.0 — leading-zero release inputs are invalid and duplicate-version checks fail early before publish work begins. See ADR 218.
  • CI/test selection is more precise — affected-test selection now widens docs/test-impact correctly and avoids under-testing relevant PRs. (#495)

Fixed

  • Planning writes are more reliable — phase completion writes are transactional and no longer corrupt milestone progress counters. (#465, #514)
  • Roadmap and milestone parsing no longer leak stale phase details into active milestone state. (#513)
  • /gsd:update detects local Antigravity .agent installs and repo-local Claude installs correctly. (#512, #476)
  • Package identity registration no longer regresses update/runtime detection. (#521)

Legacy Release History

Release notes for every version published before the project was renamed to @opengsd/gsd-core — the retired get-shit-done-cc / get-shit-done-redux lineage, versions 1.0.0 → 1.42.x plus pre-release and canary builds — have been rolled up into a single archive:

➡️ docs/RELEASE-NOTES-LEGACY.md

Those legacy 1.x numbers belong to the previous package line and predate the current @opengsd/gsd-core versioning, which restarts at 1.0.0. They are preserved verbatim-in-spirit (condensed) in the archive and intentionally kept out of this file so the two version streams cannot collide.