Compare commits

...

3 Commits

Author SHA1 Message Date
Lex Christopherson
201b8f1a05 1.36.0 2026-04-14 08:26:26 -06:00
Lex Christopherson
73c7281a36 docs: update changelog and README for v1.36.0
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 08:26:17 -06:00
Gabriel Rodrigues Garcia
e6e33602c3 fix(init): ignore archived phases from prior milestones sharing a phase number (#2186)
When a new milestone reuses a phase number that exists in an archived
milestone (e.g., v2.0 Phase 2 while v1.0-phases/02-old-feature exists),
findPhaseInternal falls through to the archive and returns the old
phase. init plan-phase and init execute-phase then emitted archived
values for phase_dir, phase_slug, has_context, has_research, and
*_path fields, while phase_req_ids came from the current ROADMAP —
producing a silent inconsistency that pointed downstream agents at a
shipped phase from a previous milestone.

cmdInitPhaseOp already guarded against this (see lines 617-642);
apply the same guard in cmdInitPlanPhase, cmdInitExecutePhase, and
cmdInitVerifyWork: if findPhaseInternal returns an archived match
and the current ROADMAP.md has the phase, discard the archived
phaseInfo so the ROADMAP fallback path produces clean values.

Adds three regression tests covering plan-phase, execute-phase, and
verify-work under the shared-number scenario.
2026-04-13 10:59:11 -04:00
6 changed files with 180 additions and 18 deletions

View File

@@ -6,18 +6,77 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
## [Unreleased]
## [1.36.0] - 2026-04-14
### Added
- **`@gsd-build/sdk` — Phase 1 typed query foundation** — Registry-based `gsd-sdk query` command, classified errors (`GSDQueryError`), and unit-tested handlers under `sdk/src/query/` (state, roadmap, phase lifecycle, init, config, validation, and related domains). Implements incremental SDK-first migration scope approved in #2083; builds on validated work from #2007 / `feat/sdk-foundation` without migrating workflows or removing `gsd-tools.cjs` in this phase.
- **Flow diagram directive for phase researcher** — `gsd-phase-researcher` now enforces data-flow architecture diagrams instead of file-listing diagrams. Language-agnostic directive added to agent prompt and research template. (#2139)
### Fixed
- **SDK query layer (PR review hardening)** — `commit-to-subrepo` uses realpath-aware path containment and sanitized commit messages; `state.planned-phase` uses the STATE.md lockfile; `verifyKeyLinks` mitigates ReDoS on frontmatter patterns; frontmatter handlers resolve paths under the real project root; phase directory names reject `..` and separators; `gsd-sdk` restores strict CLI parsing by stripping `--pick` before `parseArgs`; `QueryRegistry.commands()` for enumeration; `todoComplete` uses static error imports.
- **`/gsd-graphify` integration** — Knowledge graph for planning agents, enabling richer context connections between project artifacts (#2164)
- **`gsd-pattern-mapper` agent** — Codebase pattern analysis agent for identifying recurring patterns and conventions (#1861)
- **`@gsd-build/sdk` — Phase 1 typed query foundation** — Registry-based `gsd-sdk query` command with classified errors and unit-tested handlers for state, roadmap, phase lifecycle, init, config, and validation (#2118)
- **Opt-in TDD pipeline mode** — `tdd_mode` exposed in init JSON with `--tdd` flag override for test-driven development workflows (#2119, #2124)
- **Stale/orphan worktree detection (W017)** — `validate-health` now detects stale and orphan worktrees (#2175)
- **Seed scanning in new-milestone** — Planted seeds are scanned during milestone step 2.5 for automatic surfacing (#2177)
- **Artifact audit gate** — Open artifact auditing for milestone close and phase verify (#2157, #2158, #2160)
- **`/gsd-quick` and `/gsd-thread` subcommands** — Added list/status/resume/close subcommands (#2159)
- **Debug skill dispatch and session manager** — Sub-orchestrator for `/gsd-debug` sessions (#2154)
- **Project skills awareness** — 9 GSD agents now discover and use project-scoped skills (#2152)
- **`/gsd-debug` session management** — TDD gate, reasoning checkpoint, and security hardening (#2146)
- **Context-window-aware prompt thinning** — Automatic prompt size reduction for sub-200K models (#1978)
- **SDK `--ws` flag** — Workstream-aware execution support (#1884)
- **`/gsd-extract-learnings` command** — Phase knowledge capture workflow (#1873)
- **Cross-AI execution hook** — Step 2.5 in execute-phase for external AI integration (#1875)
- **Ship workflow external review hook** — External code review command hook in ship workflow
- **Plan bounce hook** — Optional external refinement step (12.5) in plan-phase workflow
- **Cursor CLI self-detection** — Cursor detection and REVIEWS.md template for `/gsd-review` (#1960)
- **Architectural Responsibility Mapping** — Added to phase-researcher pipeline (#1988, #2103)
- **Configurable `claude_md_path`** — Custom CLAUDE.md path setting (#2010, #2102)
- **`/gsd-skill-manifest` command** — Pre-compute skill discovery for faster session starts (#2101)
- **`--dry-run` mode and resolved blocker pruning** — State management improvements (#1970)
- **State prune command** — Prune unbounded section growth in STATE.md (#1970)
- **Global skills support** — Support `~/.claude/skills/` in `agent_skills` config (#1992)
- **Context exhaustion auto-recording** — Hooks auto-record session state on context exhaustion (#1974)
- **Metrics table pruning** — Auto-prune on phase complete for STATE.md metrics (#2087, #2120)
- **Flow diagram directive for phase researcher** — Data-flow architecture diagrams enforced (#2139, #2147)
### Changed
- **Planner context-cost sizing** — Replaced time-based reasoning with context-cost sizing and multi-source coverage audit (#2091, #2092, #2114)
- **`/gsd-next` prior-phase completeness scan** — Replaced consecutive-call counter with completeness scan (#2097)
- **Inline execution for small plans** — Default to inline execution, skip subagent overhead for small plans (#1979)
- **Prior-phase context optimization** — Limited to 3 most recent phases and includes `Depends on` phases (#1969)
- **Non-technical owner adaptation** — `discuss-phase` adapts gray area language for non-technical owners via USER-PROFILE.md (#2125, #2173)
- **Agent specs standardization** — Standardized `required_reading` patterns across agent specs (#2176)
- **CI upgrades** — GitHub Actions upgraded to Node 22+ runtimes; release pipeline fixes (#2128, #1956)
- **Branch cleanup workflow** — Auto-delete on merge + weekly sweep (#2051)
- **SDK query follow-up** — Expanded mutation commands, PID-liveness lock cleanup, depth-bounded JSON search, and comprehensive unit tests
- **SDK query follow-up (tests, docs, registry)** — Expanded `QUERY_MUTATION_COMMANDS` for event emission; stale lock cleanup uses PID liveness (`process.kill(pid, 0)`) when a lock file exists; `searchJsonEntries` is depth-bounded (`MAX_JSON_SEARCH_DEPTH`); removed unnecessary `readdirSync`/`Dirent` casts across query handlers; added `sdk/src/query/QUERY-HANDLERS.md` (error vs `{ data.error }`, mutations, locks, intel limits); unit tests for intel, profile, uat, skills, summary, websearch, workstream, registry vs `QUERY_MUTATION_COMMANDS`, and frontmatter extract/splice round-trip.
### Fixed
- **Init ignores archived phases** — Archived phases from prior milestones sharing a phase number no longer interfere (#2186)
- **UAT file listing** — Removed `head -5` truncation from verify-work (#2172)
- **Intel status relative time** — Display relative time correctly (#2132)
- **Codex hook install** — Copy hook files to Codex install target (#2153, #2166)
- **Phase add-batch duplicate prevention** — Prevents duplicate phase numbers on parallel invocations (#2165, #2170)
- **Stale hooks warning** — Show contextual warning for dev installs with stale hooks (#2162)
- **Worktree submodule skip** — Skip worktree isolation when `.gitmodules` detected (#2144)
- **Worktree STATE.md backup** — Use `cp` instead of `git-show` (#2143)
- **Bash hooks staleness check** — Add missing bash hooks to `MANAGED_HOOKS` (#2141)
- **Code-review parser fix** — Fix SUMMARY.md parser section-reset for top-level keys (#2142)
- **Backlog phase exclusion** — Exclude 999.x backlog phases from next-phase and all_complete (#2135)
- **Frontmatter regex anchor** — Anchor `extractFrontmatter` regex to file start (#2133)
- **Qwen Code install paths** — Eliminate Claude reference leaks (#2112)
- **Plan bounce default** — Correct `plan_bounce_passes` default from 1 to 2
- **GSD temp directory** — Use dedicated temp subdirectory for GSD temp files (#1975, #2100)
- **Workspace path quoting** — Quote path variables in workspace next-step examples (#2096)
- **Answer validation loop** — Carve out Other+empty exception from retry loop (#2093)
- **Test race condition** — Add `before()` hook to bug-1736 test (#2099)
- **Qwen Code path replacement** — Dedicated path replacement branches and finishInstall labels (#2082)
- **Global skill symlink guard** — Tests and empty-name handling for config (#1992)
- **Context exhaustion hook defects** — Three blocking defects fixed (#1974)
- **State disk scan cache** — Invalidate disk scan cache in writeStateMd (#1967)
- **State frontmatter caching** — Cache buildStateFrontmatter disk scan per process (#1967)
- **Grep anchor and threshold guard** — Correct grep anchor and add threshold=0 guard (#1979)
- **Atomic write coverage** — Extend atomicWriteFileSync to milestone, phase, and frontmatter (#1972)
- **Health check optimization** — Merge four readdirSync passes into one (#1973)
- **SDK query layer hardening** — Realpath-aware path containment, ReDoS mitigation, strict CLI parsing, phase directory sanitization (#2118)
- **Prompt injection scan** — Allowlist plan-phase.md
## [1.35.0] - 2026-04-10
@@ -1907,7 +1966,9 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
- YOLO mode for autonomous execution
- Interactive mode with checkpoints
[Unreleased]: https://github.com/gsd-build/get-shit-done/compare/v1.34.2...HEAD
[Unreleased]: https://github.com/gsd-build/get-shit-done/compare/v1.36.0...HEAD
[1.36.0]: https://github.com/gsd-build/get-shit-done/releases/tag/v1.36.0
[1.35.0]: https://github.com/gsd-build/get-shit-done/releases/tag/v1.35.0
[1.34.2]: https://github.com/gsd-build/get-shit-done/releases/tag/v1.34.2
[1.34.1]: https://github.com/gsd-build/get-shit-done/releases/tag/v1.34.1
[1.34.0]: https://github.com/gsd-build/get-shit-done/releases/tag/v1.34.0

View File

@@ -89,13 +89,14 @@ People who want to describe what they want and have it built correctly — witho
Built-in quality gates catch real problems: schema drift detection flags ORM changes missing migrations, security enforcement anchors verification to threat models, and scope reduction detection prevents the planner from silently dropping your requirements.
### v1.34.0 Highlights
### v1.36.0 Highlights
- **Gates taxonomy** — 4 canonical gate types (pre-flight, revision, escalation, abort) wired into plan-checker and verifier agents
- **Shell hooks fix** — `hooks/*.sh` files are now correctly included in the npm package, eliminating startup hook errors on fresh installs
- **Post-merge hunk verification** — `reapply-patches` detects silently dropped hunks after three-way merge
- **detectConfigDir fix** — Claude Code users no longer see false "update available" warnings when multiple runtimes are installed
- **3 bug fixes** — Milestone backlog preservation, detectConfigDir priority, and npm package manifest
- **Knowledge graph integration** — `/gsd-graphify` brings knowledge graphs to planning agents for richer context connections
- **SDK typed query foundation** — Registry-based `gsd-sdk query` command with classified errors and handlers for state, roadmap, phase lifecycle, and config
- **TDD pipeline mode** — Opt-in test-driven development workflow with `--tdd` flag
- **Context-window-aware prompt thinning** — Automatic prompt size reduction for sub-200K models
- **Project skills awareness** — 9 GSD agents now discover and use project-scoped skills
- **30+ bug fixes** — Worktree safety, state management, installer paths, and health check optimizations
---

View File

@@ -58,6 +58,16 @@ function cmdInitExecutePhase(cwd, phase, raw, options = {}) {
const roadmapPhase = getRoadmapPhaseInternal(cwd, phase);
// If findPhaseInternal matched an archived phase from a prior milestone, but
// the phase exists in the current milestone's ROADMAP.md, ignore the archive
// match — we are initializing a new phase in the current milestone that
// happens to share a number with an archived one. Without this, phase_dir,
// phase_slug and related fields would point at artifacts from a previous
// milestone.
if (phaseInfo?.archived && roadmapPhase?.found) {
phaseInfo = null;
}
// Fallback to ROADMAP.md if no phase directory exists yet
if (!phaseInfo && roadmapPhase?.found) {
const phaseName = roadmapPhase.phase_name;
@@ -181,6 +191,16 @@ function cmdInitPlanPhase(cwd, phase, raw, options = {}) {
const roadmapPhase = getRoadmapPhaseInternal(cwd, phase);
// If findPhaseInternal matched an archived phase from a prior milestone, but
// the phase exists in the current milestone's ROADMAP.md, ignore the archive
// match — we are planning a new phase in the current milestone that happens
// to share a number with an archived one. Without this, phase_dir,
// phase_slug, has_context and has_research would point at artifacts from a
// previous milestone.
if (phaseInfo?.archived && roadmapPhase?.found) {
phaseInfo = null;
}
// Fallback to ROADMAP.md if no phase directory exists yet
if (!phaseInfo && roadmapPhase?.found) {
const phaseName = roadmapPhase.phase_name;
@@ -552,6 +572,16 @@ function cmdInitVerifyWork(cwd, phase, raw) {
const config = loadConfig(cwd);
let phaseInfo = findPhaseInternal(cwd, phase);
// If findPhaseInternal matched an archived phase from a prior milestone, but
// the phase exists in the current milestone's ROADMAP.md, ignore the archive
// match — same pattern as cmdInitPhaseOp.
if (phaseInfo?.archived) {
const roadmapPhase = getRoadmapPhaseInternal(cwd, phase);
if (roadmapPhase?.found) {
phaseInfo = null;
}
}
// Fallback to ROADMAP.md if no phase directory exists yet
if (!phaseInfo) {
const roadmapPhase = getRoadmapPhaseInternal(cwd, phase);

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "get-shit-done-cc",
"version": "1.35.0",
"version": "1.36.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "get-shit-done-cc",
"version": "1.35.0",
"version": "1.36.0",
"license": "MIT",
"bin": {
"get-shit-done-cc": "bin/install.js"

View File

@@ -1,6 +1,6 @@
{
"name": "get-shit-done-cc",
"version": "1.35.0",
"version": "1.36.0",
"description": "A meta-prompting, context engineering and spec-driven development system for Claude Code, OpenCode, Gemini and Codex by TÂCHES.",
"bin": {
"get-shit-done-cc": "bin/install.js"

View File

@@ -352,6 +352,76 @@ describe('init commands ROADMAP fallback when phase directory does not exist (#1
});
});
// ─────────────────────────────────────────────────────────────────────────────
// init ignores archived phases from prior milestones that share a phase number
// ─────────────────────────────────────────────────────────────────────────────
describe('init commands ignore archived phases from prior milestones sharing a number', () => {
let tmpDir;
beforeEach(() => {
tmpDir = createTempProject();
// Current milestone ROADMAP has Phase 2 but no disk directory yet
fs.writeFileSync(
path.join(tmpDir, '.planning', 'ROADMAP.md'),
'# v2.0 Roadmap\n\n### Phase 2: New Feature\n**Goal:** New v2.0 feature\n**Requirements**: NEW-01, NEW-02\n**Plans:** TBD\n'
);
// Prior milestone archive has a shipped Phase 2 with different slug and artifacts
const archivedDir = path.join(tmpDir, '.planning', 'milestones', 'v1.0-phases', '02-old-feature');
fs.mkdirSync(archivedDir, { recursive: true });
fs.writeFileSync(path.join(archivedDir, '2-CONTEXT.md'), '# OLD v1.0 Phase 2 context');
fs.writeFileSync(path.join(archivedDir, '2-RESEARCH.md'), '# OLD v1.0 Phase 2 research');
});
afterEach(() => {
cleanup(tmpDir);
});
test('init plan-phase prefers current ROADMAP entry over archived v1.0 phase of same number', () => {
const result = runGsdTools('init plan-phase 2', tmpDir);
assert.ok(result.success, `Command failed: ${result.error}`);
const output = JSON.parse(result.output);
assert.strictEqual(output.phase_found, true);
assert.strictEqual(output.phase_name, 'New Feature',
'phase_name must come from current ROADMAP.md, not archived v1.0');
assert.strictEqual(output.phase_slug, 'new-feature');
assert.strictEqual(output.phase_dir, null,
'phase_dir must be null — current milestone has no directory yet');
assert.strictEqual(output.has_context, false,
'has_context must not inherit archived v1.0 artifacts');
assert.strictEqual(output.has_research, false,
'has_research must not inherit archived v1.0 artifacts');
assert.ok(!output.context_path,
'context_path must not point at archived v1.0 file');
assert.ok(!output.research_path,
'research_path must not point at archived v1.0 file');
assert.strictEqual(output.phase_req_ids, 'NEW-01, NEW-02');
});
test('init execute-phase prefers current ROADMAP entry over archived v1.0 phase of same number', () => {
const result = runGsdTools('init execute-phase 2', tmpDir);
assert.ok(result.success, `Command failed: ${result.error}`);
const output = JSON.parse(result.output);
assert.strictEqual(output.phase_found, true);
assert.strictEqual(output.phase_name, 'New Feature');
assert.strictEqual(output.phase_slug, 'new-feature');
assert.strictEqual(output.phase_dir, null);
assert.strictEqual(output.phase_req_ids, 'NEW-01, NEW-02');
});
test('init verify-work prefers current ROADMAP entry over archived v1.0 phase of same number', () => {
const result = runGsdTools('init verify-work 2', tmpDir);
assert.ok(result.success, `Command failed: ${result.error}`);
const output = JSON.parse(result.output);
assert.strictEqual(output.phase_found, true);
assert.strictEqual(output.phase_name, 'New Feature');
assert.strictEqual(output.phase_dir, null);
});
});
// ─────────────────────────────────────────────────────────────────────────────
// cmdInitTodos (INIT-01)
// ─────────────────────────────────────────────────────────────────────────────