Skip to content

Commit 113b4c1

Browse files
committed
feat(verifier): default gaps_found to backlog-park instead of new-phase; bump 2.45.9
1 parent 834fa51 commit 113b4c1

7 files changed

Lines changed: 78 additions & 9 deletions

File tree

.claude-plugin/marketplace.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"name": "gsd",
1212
"source": "./",
1313
"description": "Get Shit Done -- structured workflow plugin for Claude Code with planning, execution, verification, and MCP-backed project state",
14-
"version": "2.45.8",
14+
"version": "2.45.9",
1515
"author": {
1616
"name": "Jasper Nuyens"
1717
},

.claude-plugin/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "gsd",
3-
"version": "2.45.8",
3+
"version": "2.45.9",
44
"description": "Get Shit Done -- a structured workflow plugin for Claude Code that adds planning, execution, and verification commands with MCP-backed project state",
55
"author": {
66
"name": "Jasper Nuyens"

CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,25 @@ History before 2.38.2 lives in git + the per-milestone archive (see `.planning/m
88

99
## [Unreleased]
1010

11+
## [2.45.9] - 2026-05-29 (based on upstream GSD 1.42.3, hosted at open-gsd/get-shit-done-redux)
12+
13+
Behavior change addressing a real felt issue: in larger projects, GSD-managed milestones tend toward unbounded growth because the architecture has 4 workflows that add phases (`add-phase`, `insert-phase`, `add-backlog`, `plan-milestone-gaps`) against 1 that effectively closes them (`complete-milestone`). When `gsd-verifier` returns `gaps_found`, the historical default was to route the gaps into a follow-up phase via `/gsd:plan-phase --gaps`. That kept gap-driven phase multiplication going indefinitely.
14+
15+
This release flips the default. When `gaps_found`, the orchestrator now asks the user how to handle the gaps with three options: **Park to backlog** (recommended, gaps become 999.x backlog entries via `/gsd:add-backlog`, milestone ships when remaining in-scope phases close), **Escalate to current milestone** (gaps become a follow-up phase via `/gsd:plan-phase --gaps`, current behavior preserved), or **Decide later** (just print the summary, no action). The "Park to backlog" option is presented as the recommended default because most gaps are legitimately follow-up work, not blockers, and parking them surfaces the scope decision at the next milestone planning gate rather than mid-flight.
16+
17+
Why this matters: this project's own milestones (v1.0, v1.1, v1.2) all shipped at 3, 2, 3 phases with zero decimal-numbered inserts, which only works because the maintainer actively scope-polices. Larger team projects can't lean on a single judgment-bearer the same way, so the architectural bias toward addition becomes load-bearing.
18+
19+
Tradeoff: looser scope discipline. Teams that WANT exhaustive coverage and want every gap to close before milestone ship will prefer the previous default. They can still pick "Escalate to current milestone" on any individual gaps_found event. A config flag (`workflow.gaps_default_action: park | escalate`) is plausible if requests come in; not shipped yet.
20+
21+
Also bundled: the test stability commit from `834fa51` that landed unreleased on 2026-05-29 (refactor of `tests/mcp-write-tools-end-to-end.test.cjs` to drop the 6-sequential-spawn check, keeping `gsd_add_blocker` end-to-end + `gsd_plan_status` control case). 20/20 deterministic.
22+
23+
### Changed
24+
- **`workflows/execute-phase.md`** verify_phase_goal step: `gaps_found` handling now presents an `AskUserQuestion` with three options ("Park to backlog (Recommended)", "Escalate to current milestone", "Decide later") instead of unconditionally routing to `/gsd:plan-phase --gaps`. Park-to-backlog runs `/gsd:add-backlog` for each gap and marks the phase as `gaps_parked` so the milestone can ship when remaining in-scope phases close. The escalation path is unchanged from the previous behavior.
25+
- **`agents/gsd-verifier.md`**: softened the "Structure gaps for `/gsd:plan-phase --gaps`" guidance in 3 places to mention both downstream paths (backlog and escalation), so the verifier no longer pre-biases the orchestrator's routing choice.
26+
27+
### Fixed
28+
- **`tests/mcp-write-tools-end-to-end.test.cjs`** (from unreleased commit `834fa51`): dropped the racy "all 6 write tools in one server" check. Each MCP write tool's spawnSync of `bin/gsd-tools.cjs` takes 1-3 seconds (node startup cost), so 6 sequential calls hit the test budget. Kept `gsd_add_blocker actually mutates STATE.md` + `gsd_plan_status (control)` which together preserve the regression signal for #11. 20/20 deterministic.
29+
1130
## [2.45.8] - 2026-05-29 (based on upstream GSD 1.42.3, hosted at open-gsd/get-shit-done-redux)
1231

1332
Test stability fix for `tests/mcp-write-tools-end-to-end.test.cjs`. The v2.45.5 fix routes each MCP write-tool call through a `spawnSync('node', ['bin/gsd-tools.cjs', 'state', '<subcommand>'])` subprocess. The end-to-end test sends 6 sequential write-tool calls in one case, which means 6 sequential node-subprocess spawns inside the MCP server, each ~100-200ms. The test's original 1.5s post-request window was too tight: 5 of 5 local runs at v2.45.7 ship produced 1-2 of 3 passes instead of 3 of 3. Bumped the post-request wait to 5s and the overall test timeout to 15s. 5 of 5 runs now pass deterministically. The MCP server behavior itself is unchanged; this is purely a test budget adjustment.

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ This plugin starts from upstream GSD's source tree but adds Claude-Code-native c
136136

137137
| Feature | What it does | Command / hook |
138138
|---------|--------------|----------------|
139+
| **Gaps default to backlog, not new phase** (v2.45.9) | When the verifier returns `gaps_found`, the orchestrator now asks the user how to route them: **Park to backlog** (recommended, gaps become 999.x backlog entries via `/gsd:add-backlog`, milestone ships when in-scope phases close), **Escalate to current milestone** (previous behavior, gaps spawn a follow-up phase via `/gsd:plan-phase --gaps`), or **Decide later**. Default flip prevents unbounded milestone growth from verifier-driven phase multiplication. Escalation path preserved for gaps that genuinely block the milestone goal. | `workflows/execute-phase.md`, `agents/gsd-verifier.md` |
139140
| **Amend docs into work commit** (v2.45.7) | `/gsd:quick` now folds the docs (PLAN, SUMMARY, STATE updates) into the preceding work commit via `git commit --amend --no-edit` instead of emitting a separate `docs(quick-NN): ...` commit. Common case: one commit per task instead of two. Falls back to a separate commit when the amend would be unsafe (no new work commit, HEAD is a merge commit, `commit_docs: false`, or nothing staged). | `workflows/quick.md` |
140141
| **Executor self-test bias** (v2.45.6) | Nudges `gsd-executor` toward running automated checks (file existence, grep, command exit code, test runs) instead of emitting `checkpoint:human-verify` prompts that interrupt the user. Single-knob change: the agent prompt's declared `human-verify` share drops from 90% to 40%, with the implicit remainder being silent self-tests. Tunable based on observed false-positive rate. | `agents/gsd-executor.md` |
141142
| **User-docs jargon ratchet** (v2.45.4) | Catches accidental GSD-jargon leaks (raw paths, internal artifact names, naked plan IDs, "phase N" prose) into plugin user-facing docs at commit time and in CI. Counts-based ratchet against a baseline in `tests/drift-baseline.json`. Fenced code blocks are stripped before scanning so command examples in code blocks do not pollute the ratchet. Plugin self-policing only, downstream user projects are left untouched. | `bin/maintenance/check-user-docs-jargon.cjs` |

agents/gsd-verifier.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,7 @@ Parse the JSON to extract all phases. Identify phases with `number > current_pha
605605

606606
Before writing VERIFICATION.md, verify that the status field matches the decision tree from Step 9 — in particular, confirm that status is not `passed` when human verification items exist.
607607

608-
Structure gaps in YAML frontmatter for `/gsd:plan-phase --gaps`:
608+
Structure gaps in YAML frontmatter so the orchestrator can route them either to backlog (default, via `/gsd:add-backlog`) or to a follow-up phase (escalation, via `/gsd:plan-phase --gaps`). The user makes the routing choice after seeing the gap summary; do not pre-bias the recommendation in your verification output. The same YAML shape feeds both downstream paths:
609609

610610
```yaml
611611
gaps:
@@ -812,7 +812,7 @@ All must-haves verified. Phase goal achieved. Ready to proceed.
812812
1. **{Truth 1}** — {reason}
813813
- Missing: {what needs to be added}
814814

815-
Structured gaps in VERIFICATION.md frontmatter for `/gsd:plan-phase --gaps`.
815+
Structured gaps in VERIFICATION.md frontmatter feed the orchestrator's gap-handling choice (default: park to backlog via `/gsd:add-backlog`; escalation: `/gsd:plan-phase --gaps`).
816816

817817
{If human_needed:}
818818
### Human Verification Required
@@ -833,7 +833,7 @@ Automated checks passed. Awaiting human verification.
833833

834834
**DO NOT skip key link verification.** 80% of stubs hide here — pieces exist but aren't connected.
835835

836-
**Structure gaps in YAML frontmatter** for `/gsd:plan-phase --gaps`.
836+
**Structure gaps in YAML frontmatter** so the orchestrator can route them to backlog (default) or to a follow-up phase (escalation). Don't pre-bias the recommendation.
837837

838838
**DO flag for human verification when uncertain** (visual, real-time, external service).
839839

tests/drift-baseline.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
},
99
"user_docs_jargon": {
1010
"planning_paths": 38,
11-
"artifact_names": 45,
11+
"artifact_names": 46,
1212
"plan_files": 3,
1313
"generic_phase_num": 17,
1414
"generated_at": "2026-05-29",

workflows/execute-phase.md

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1491,7 +1491,7 @@ grep "^status:" "$PHASE_DIR"/*-VERIFICATION.md | cut -d: -f2 | tr -d ' '
14911491
|--------|--------|
14921492
| `passed` | → update_roadmap |
14931493
| `human_needed` | Persist and present human testing items; keep phase pending until verification reruns as `passed` |
1494-
| `gaps_found` | Present gap summary, offer `/gsd:plan-phase {phase} --gaps ${GSD_WS}` |
1494+
| `gaps_found` | Present gap summary, ask user to choose: **park to backlog** (default — gaps become 999.x entries via `/gsd:add-backlog`, milestone ships when remaining phases close) OR **escalate to current milestone** (gaps become a follow-up phase via `/gsd:plan-phase {phase} --gaps ${GSD_WS}`). Default biases toward backlog to prevent unbounded phase multiplication; user explicitly opts into escalation when gaps actually block milestone goal. |
14951495

14961496
**If human_needed:**
14971497

@@ -1565,6 +1565,51 @@ Items saved to `{phase_num}-HUMAN-UAT.md` — they will appear in `/gsd:progress
15651565
### What's Missing
15661566
{Gap summaries from VERIFICATION.md}
15671567
1568+
### What happens next
1569+
1570+
Two paths. The plugin defaults to **park to backlog** because turning every verifier gap into a new in-scope phase tends to balloon milestones unbounded; most gaps are legitimately follow-up work, not blockers. Use **escalate to current milestone** only when at least one gap genuinely blocks the milestone's ship criteria.
1571+
```
1572+
1573+
Then ask the user (or auto-default to "Park" when running non-interactively):
1574+
1575+
```
1576+
AskUserQuestion(
1577+
header: "Gaps handling",
1578+
question: "How should these {N} gap(s) be handled?",
1579+
options: [
1580+
{
1581+
label: "Park to backlog (Recommended)",
1582+
description: "Each gap becomes a 999.x backlog entry via /gsd:add-backlog. Milestone can ship when remaining in-scope phases close. Best when gaps are real but not blocking the milestone goal."
1583+
},
1584+
{
1585+
label: "Escalate to current milestone",
1586+
description: "Gaps become a follow-up phase via /gsd:plan-phase {X} --gaps. New verification cycle opens. Best when at least one gap blocks the milestone goal and MUST close before ship."
1587+
},
1588+
{
1589+
label: "Decide later",
1590+
description: "Just present the gaps and let me decide manually. Phase stays in gaps_found state until I run /gsd:add-backlog, /gsd:plan-phase --gaps, or override."
1591+
}
1592+
],
1593+
multiSelect: false
1594+
)
1595+
```
1596+
1597+
If "Park to backlog": for each gap, run `/gsd:add-backlog "{gap.truth}: {gap.evidence}"`. Mark the phase as `gaps_parked` in STATE.md (continuation allowed; ship not blocked). Print:
1598+
1599+
```
1600+
---
1601+
## ▶ Next Up — [${PROJECT_CODE}] ${PROJECT_TITLE}
1602+
1603+
{N} gap(s) parked as backlog items (999.{next}-999.{last}). Milestone can ship when remaining in-scope phases close.
1604+
1605+
`/gsd:next` — continue with next pending phase
1606+
Also: `cat .planning/ROADMAP.md` — review parked items
1607+
Also: `/gsd:plan-phase {X} --gaps ${GSD_WS}` — escalate later if you change your mind
1608+
```
1609+
1610+
If "Escalate to current milestone" (current behavior, preserved):
1611+
1612+
```
15681613
---
15691614
## ▶ Next Up — [${PROJECT_CODE}] ${PROJECT_TITLE}
15701615
@@ -1576,7 +1621,11 @@ Also: `cat {phase_dir}/{phase_num}-VERIFICATION.md` — full report
15761621
Also: `/gsd:verify-work {X} ${GSD_WS}` — manual testing first
15771622
```
15781623

1579-
Gap closure cycle: `/gsd:plan-phase {X} --gaps ${GSD_WS}` reads VERIFICATION.md → creates gap plans with `gap_closure: true` → user runs `/gsd:execute-phase {X} --gaps-only ${GSD_WS}` → verifier re-runs.
1624+
If "Decide later": just print the gap summary plus both follow-up commands, no automatic action.
1625+
1626+
Gap closure cycle (escalation path): `/gsd:plan-phase {X} --gaps ${GSD_WS}` reads VERIFICATION.md → creates gap plans with `gap_closure: true` → user runs `/gsd:execute-phase {X} --gaps-only ${GSD_WS}` → verifier re-runs.
1627+
1628+
Parking path: gaps land in `.planning/ROADMAP.md` under `## Backlog` as 999.x entries. They surface naturally at `/gsd:new-milestone` planning time, when scope decisions for the next milestone are made deliberately rather than as an in-flight reaction.
15801629
</step>
15811630

15821631
<step name="update_roadmap">
@@ -1689,7 +1738,7 @@ gsd-sdk query commit "docs(phase-{X}): evolve PROJECT.md after phase completion"
16891738

16901739
<step name="offer_next">
16911740

1692-
**Exception:** If `gaps_found`, the `verify_phase_goal` step already presents the gap-closure path (`/gsd:plan-phase {X} --gaps`). No additional routing needed — skip auto-advance.
1741+
**Exception:** If `gaps_found`, the `verify_phase_goal` step already presents the user with the gap-handling choice (park to backlog by default, or escalate to a follow-up phase via `/gsd:plan-phase {X} --gaps`). No additional routing needed — skip auto-advance regardless of which path the user picks.
16931742

16941743
**No-transition check (spawned by auto-advance chain):**
16951744

0 commit comments

Comments
 (0)