From 1bfadec2d0ff37f916494986f956b4c73ee0d5c4 Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Sun, 5 Jul 2026 15:42:10 -0400 Subject: [PATCH 01/39] fix(#1921): preserve verify-work state across gap-closure + defer follow-ups (#2025) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(#1921): preserve verify-work state across gap-closure + defer follow-ups Resuming /gsd:verify-work after /gsd:execute-phase --gaps-only lost the verification state: UAT ## Gaps still read status: failed even after their fix plans executed, so verify-work re-diagnosed them as fresh blockers, spawned a new gap plan, and reported only the new plan verified. A new state contract links each gap to its fix plan so fixed gaps are recognized. - verify-work.md gap YAML: stable gap_id (G-{phase}-{N}) per gap. - plan_gap_closure planner prompt: each *-PLAN.md tags the gap_ids it addresses in its frontmatter (gap_closure: true, gap_ids: [...]). - new reconcile_gaps step (run at resume_from_file entry): marks a gap status: resolved when its plan has a matching *-SUMMARY.md — fixed gaps are not re-diagnosed and do not spawn new gap plans; a re-reported break is treated as a fresh regression with a new gap_id. - deferred-follow-up branch: a future-work idea (signals: 'later', 'next version', 'out of scope', ...) is captured to UAT ## Deferred Follow-Ups instead of becoming a blocking gap/plan. - workflow-size baseline recaptured (verify-work LARGE tier, 38221/61440). Closes #1921 * docs(#1921): backfill changeset pr 2025 * fix(#1921): balance tags in verify-work.md via 4-backtick outer fence The plan_gap_closure step nested a ```yaml example inside a ``` block; same-length fences made stripFencedCode close the outer block early, swallowing the step's (14 opens / 13 closes). Widen the outer fence to 4 backticks so the nested yaml is contained. Regenerate golden fixtures + size baselines. Co-Authored-By: Claude Opus 4.8 --------- Co-authored-by: Claude Opus 4.8 --- .changeset/1921-verify-work-gap-recovery.md | 5 ++ gsd-core/workflows/verify-work.md | 64 ++++++++++++++++++- .../golden-install-parity/antigravity.json | 2 +- .../golden-install-parity/augment.json | 2 +- .../golden-install-parity/claude.json | 2 +- .../fixtures/golden-install-parity/cline.json | 2 +- .../golden-install-parity/codebuddy.json | 2 +- .../fixtures/golden-install-parity/codex.json | 2 +- .../golden-install-parity/copilot.json | 2 +- .../golden-install-parity/cursor.json | 2 +- .../golden-install-parity/hermes.json | 2 +- .../fixtures/golden-install-parity/kilo.json | 2 +- .../fixtures/golden-install-parity/kimi.json | 2 +- .../golden-install-parity/opencode.json | 2 +- .../fixtures/golden-install-parity/qwen.json | 2 +- .../fixtures/golden-install-parity/trae.json | 2 +- .../golden-install-parity/windsurf.json | 2 +- tests/workflow-size-baseline.json | 2 +- 18 files changed, 82 insertions(+), 19 deletions(-) create mode 100644 .changeset/1921-verify-work-gap-recovery.md diff --git a/.changeset/1921-verify-work-gap-recovery.md b/.changeset/1921-verify-work-gap-recovery.md new file mode 100644 index 000000000..776f031bb --- /dev/null +++ b/.changeset/1921-verify-work-gap-recovery.md @@ -0,0 +1,5 @@ +--- +type: Fixed +pr: 2025 +--- +**`/gsd:verify-work` preserves verification state across gap-closure execution and no longer auto-promotes deferred follow-ups into blocking gaps** — resuming after `/gsd:execute-phase --gaps-only` used to lose the verification state: the UAT `## Gaps` still read `status: failed` even after their fix plans executed, so verify-work re-diagnosed them as fresh blockers, spawned a new gap plan, and reported only the new plan as verified. A state contract now links each gap to its fix plan: every UAT gap carries a stable `gap_id` (`G-{phase}-{N}`), gap-closure plans tag the ids they address in their frontmatter (`gap_ids: […]`), and a new `reconcile_gaps` step on resume marks a gap `status: resolved` when its plan has a matching `*-SUMMARY.md` — so fixed gaps aren't re-diagnosed and the phase can close. Separately, a deferred-follow-up branch captures future-work ideas (signals like "later", "next version", "out of scope") into a `## Deferred Follow-Ups` section instead of creating a blocking gap/plan. (#1921) diff --git a/gsd-core/workflows/verify-work.md b/gsd-core/workflows/verify-work.md index f9f47c63c..7bacf8577 100644 --- a/gsd-core/workflows/verify-work.md +++ b/gsd-core/workflows/verify-work.md @@ -372,6 +372,28 @@ reason: "{verbatim user response}" Note: Blocked tests do NOT go into the Gaps section (they aren't code issues — they're prerequisite gates). +**If response indicates a deferred follow-up (NOT a current-phase blocker):** +- "later", "future", "follow-up", "next version", "out of scope", "nice to have", "not now", "defer", "down the road", "separate phase", "phase 2" + +These are future-work ideas, not code issues for the current phase. Capture them WITHOUT creating a gap plan (#1921 — a deferred follow-up must never become a blocking gap or spawn a fix plan): + +Update Tests section: +``` +### {N}. {name} +expected: {expected} +result: skipped +reason: "Deferred follow-up: {verbatim user response}" +``` + +Append to UAT.md `## Deferred Follow-Ups` (create the section if absent): +```yaml +- test: {N} + idea: "{verbatim user response}" + deferred_at: {today} +``` + +Do NOT append to `## Gaps` — deferred follow-ups are not blocking gaps. Continue to the next test. + **If response is anything else:** - Treat as issue description @@ -393,7 +415,8 @@ severity: {inferred} Append to Gaps section (structured YAML for plan-phase --gaps): ```yaml -- truth: "{expected behavior from test}" +- gap_id: G-{phase}-{N} # Stable id (phase + test number) — gap-closure plans tag it in their frontmatter so verify-work can reconcile resolved gaps on resume (#1921). + truth: "{expected behavior from test}" status: failed reason: "User reported: {verbatim user response}" severity: {inferred} @@ -411,9 +434,35 @@ If more tests remain → Update Current Test, go to `present_test` If no more tests → Go to `complete_session` + +**Reconcile diagnosed gaps against completed gap-closure plans (#1921):** + +When verify-work resumes after `/gsd:execute-phase --gaps-only`, the UAT `## Gaps` entries still read `status: failed` even though their fix plans have executed. Without reconciliation verify-work re-diagnoses them as fresh blockers and spawns new gap plans — losing the verification state. This step closes the loop. + +Read the UAT `## Gaps` section and the phase dir `*-PLAN.md` frontmatter. For each gap with `status: failed`: +1. Find a `*-PLAN.md` whose frontmatter `gap_ids` includes the gap's `gap_id` (`G-{phase}-{N}`). +2. If such a plan exists AND has a matching `*-SUMMARY.md` in the phase dir (the plan was executed by `--gaps-only`), the gap is **resolved** — update its YAML in place: + ```yaml + - gap_id: G-{phase}-{N} + status: resolved # was: failed + resolved_by: {plan basename} + resolved_at: {today} + ``` +3. If no plan references the `gap_id`, or the plan has no SUMMARY, leave the gap `status: failed` (still open). + +Read plan frontmatter directly in-context — do not pipe it through a shell parser. After reconciliation, announce: +``` +Reconciled gap-closure state: {resolved_count} gap(s) resolved by executed plans, {open_count} still open. +``` + +Resolved gaps are NOT re-diagnosed and do NOT spawn new gap plans. If the user later reports the same behavior as still broken, treat it as a new issue (a regression) with a fresh `gap_id`. + + **Resume testing from UAT file:** +**First run `reconcile_gaps`** (above) so gaps already fixed by `/gsd:execute-phase --gaps-only` are marked `resolved` before testing resumes (#1921). + Read the full UAT file. Find first test with `result: [pending]`. @@ -652,7 +701,7 @@ Display: Spawn gsd-planner in --gaps mode: -``` +```` Agent( prompt=""" @@ -673,13 +722,22 @@ ${AGENT_SKILLS_PLANNER} Output consumed by /gsd:execute-phase Plans must be executable prompts. + +**Gap linkage (#1921):** each created `*-PLAN.md` MUST list the UAT gap ids it addresses in its frontmatter: +```yaml +--- +gap_closure: true +gap_ids: [G-{phase}-{N}, ...] # the ## Gaps gap_id values this plan fixes +--- +``` +This lets `/gsd:verify-work` reconcile resolved gaps on resume (a gap whose plan has a matching `*-SUMMARY.md` is marked `status: resolved`, not re-diagnosed as a fresh blocker). """, subagent_type="gsd-planner", model="{planner_model}", description="Plan gap fixes for Phase {phase}" ) -``` +```` > **ORCHESTRATOR RULE — CODEX RUNTIME**: After calling Agent() above, stop working on this task immediately. Do not read more files, edit code, or run tests related to this task while the subagent is active. Wait for the subagent to return its result. This prevents duplicate work, conflicting edits, and wasted context. Only resume when the subagent result is available. diff --git a/tests/fixtures/golden-install-parity/antigravity.json b/tests/fixtures/golden-install-parity/antigravity.json index e884fbf03..0c5f07c65 100644 --- a/tests/fixtures/golden-install-parity/antigravity.json +++ b/tests/fixtures/golden-install-parity/antigravity.json @@ -303,7 +303,7 @@ "gsd-core/workflows/update.md": "2c58df5e21c41c31", "gsd-core/workflows/validate-phase.md": "6c0ab739d15709fa", "gsd-core/workflows/verify-phase.md": "8070a098ab538b33", - "gsd-core/workflows/verify-work.md": "d8e44ebee36b01e5", + "gsd-core/workflows/verify-work.md": "be699ed7920f61b0", "hooks/gsd-check-update-worker.js": "fa301e6366270d5f", "hooks/gsd-check-update.js": "4617a98bf529e4c3", "hooks/gsd-config-reload.js": "96546e0e8bb47904", diff --git a/tests/fixtures/golden-install-parity/augment.json b/tests/fixtures/golden-install-parity/augment.json index e3557f981..c72ac8f1d 100644 --- a/tests/fixtures/golden-install-parity/augment.json +++ b/tests/fixtures/golden-install-parity/augment.json @@ -373,7 +373,7 @@ "gsd-core/workflows/update.md": "fd160e13f8b7e83c", "gsd-core/workflows/validate-phase.md": "2c6d7671fcaabcaa", "gsd-core/workflows/verify-phase.md": "98a995046bdb6c3c", - "gsd-core/workflows/verify-work.md": "5ed471293dc6835f", + "gsd-core/workflows/verify-work.md": "34e980a6950cd83c", "hooks/gsd-check-update-worker.js": "cc1ef5f840f9dfc9", "hooks/gsd-check-update.js": "7b3a7983d5f1f5d3", "hooks/gsd-config-reload.js": "96546e0e8bb47904", diff --git a/tests/fixtures/golden-install-parity/claude.json b/tests/fixtures/golden-install-parity/claude.json index 7a285ad10..423300360 100644 --- a/tests/fixtures/golden-install-parity/claude.json +++ b/tests/fixtures/golden-install-parity/claude.json @@ -302,7 +302,7 @@ "gsd-core/workflows/update.md": "f9e7d8a760d0d3c8", "gsd-core/workflows/validate-phase.md": "2ac231dc541441c2", "gsd-core/workflows/verify-phase.md": "0d4ffabc1caa473a", - "gsd-core/workflows/verify-work.md": "2b49359ed055f9c4", + "gsd-core/workflows/verify-work.md": "efe57bdbbb3af03f", "hooks/gsd-check-update-worker.js": "a530efdb5fdc0da3", "hooks/gsd-check-update.js": "25cde66a12d6b886", "hooks/gsd-config-reload.js": "96546e0e8bb47904", diff --git a/tests/fixtures/golden-install-parity/cline.json b/tests/fixtures/golden-install-parity/cline.json index 734dc44ab..1616c4e1b 100644 --- a/tests/fixtures/golden-install-parity/cline.json +++ b/tests/fixtures/golden-install-parity/cline.json @@ -306,7 +306,7 @@ "gsd-core/workflows/update.md": "165beec33490bd28", "gsd-core/workflows/validate-phase.md": "5b4ae14c87859bd2", "gsd-core/workflows/verify-phase.md": "20e90407e1e531fc", - "gsd-core/workflows/verify-work.md": "343a1c8615c06c2b", + "gsd-core/workflows/verify-work.md": "6fa216623778c541", "scripts/changeset/README.md": "86ff89331dfd94b2", "scripts/changeset/cli.cjs": "68f92a344b199271", "scripts/changeset/github-release-notes.cjs": "795677f0c009b132", diff --git a/tests/fixtures/golden-install-parity/codebuddy.json b/tests/fixtures/golden-install-parity/codebuddy.json index 09416cee7..2071962c8 100644 --- a/tests/fixtures/golden-install-parity/codebuddy.json +++ b/tests/fixtures/golden-install-parity/codebuddy.json @@ -373,7 +373,7 @@ "gsd-core/workflows/update.md": "5ff1f77222977648", "gsd-core/workflows/validate-phase.md": "2c6d7671fcaabcaa", "gsd-core/workflows/verify-phase.md": "98a995046bdb6c3c", - "gsd-core/workflows/verify-work.md": "5ed471293dc6835f", + "gsd-core/workflows/verify-work.md": "34e980a6950cd83c", "hooks/gsd-check-update-worker.js": "bdc9324a2f080ddd", "hooks/gsd-check-update.js": "b7669f605631e506", "hooks/gsd-config-reload.js": "96546e0e8bb47904", diff --git a/tests/fixtures/golden-install-parity/codex.json b/tests/fixtures/golden-install-parity/codex.json index f150fac04..623d795ff 100644 --- a/tests/fixtures/golden-install-parity/codex.json +++ b/tests/fixtures/golden-install-parity/codex.json @@ -338,7 +338,7 @@ "gsd-core/workflows/update.md": "5c35c0ec0f462ea6", "gsd-core/workflows/validate-phase.md": "020201a41049679f", "gsd-core/workflows/verify-phase.md": "b9f70235e777aa81", - "gsd-core/workflows/verify-work.md": "d24a21519c50b1f8", + "gsd-core/workflows/verify-work.md": "69e27f6f419d0bba", "hooks/gsd-check-update.js": "ef48957eb6ac6a10", "hooks/gsd-context-monitor.js": "76fecaaa2babd6c1", "scripts/changeset/README.md": "86ff89331dfd94b2", diff --git a/tests/fixtures/golden-install-parity/copilot.json b/tests/fixtures/golden-install-parity/copilot.json index c375753f6..94ceacf54 100644 --- a/tests/fixtures/golden-install-parity/copilot.json +++ b/tests/fixtures/golden-install-parity/copilot.json @@ -304,7 +304,7 @@ "gsd-core/workflows/update.md": "f444a7cfcd246cfb", "gsd-core/workflows/validate-phase.md": "2f705775a4b76d42", "gsd-core/workflows/verify-phase.md": "59d1046b3a2bc481", - "gsd-core/workflows/verify-work.md": "74d024e92d8ca2b0", + "gsd-core/workflows/verify-work.md": "58e9b1b16f773b53", "hooks/gsd-session.json": "0a462834f2a28fee", "scripts/changeset/README.md": "86ff89331dfd94b2", "scripts/changeset/cli.cjs": "68f92a344b199271", diff --git a/tests/fixtures/golden-install-parity/cursor.json b/tests/fixtures/golden-install-parity/cursor.json index dc2e7f08f..cfb4a61bf 100644 --- a/tests/fixtures/golden-install-parity/cursor.json +++ b/tests/fixtures/golden-install-parity/cursor.json @@ -373,7 +373,7 @@ "gsd-core/workflows/update.md": "23e294ba707c3580", "gsd-core/workflows/validate-phase.md": "2df0c6e298a5f249", "gsd-core/workflows/verify-phase.md": "0d4ffabc1caa473a", - "gsd-core/workflows/verify-work.md": "74f5f7349ea9f757", + "gsd-core/workflows/verify-work.md": "145596b2542c457a", "hooks/gsd-cursor-post-tool.js": "019d503aee8b4a3f", "hooks/gsd-cursor-session-start.js": "c6e04ed597ea7020", "scripts/changeset/README.md": "86ff89331dfd94b2", diff --git a/tests/fixtures/golden-install-parity/hermes.json b/tests/fixtures/golden-install-parity/hermes.json index 2bb6ec260..9a09017f5 100644 --- a/tests/fixtures/golden-install-parity/hermes.json +++ b/tests/fixtures/golden-install-parity/hermes.json @@ -303,7 +303,7 @@ "gsd-core/workflows/update.md": "7499bb4cb2a3ce6f", "gsd-core/workflows/validate-phase.md": "75e8971d3981d06b", "gsd-core/workflows/verify-phase.md": "84e00bd685006870", - "gsd-core/workflows/verify-work.md": "f7750a6cce6d5391", + "gsd-core/workflows/verify-work.md": "e56e07475d5eb51e", "hooks/gsd-check-update-worker.js": "7989cc2bedd1138d", "hooks/gsd-check-update.js": "25f5ad726f76fc11", "hooks/gsd-config-reload.js": "880b696458e85e9b", diff --git a/tests/fixtures/golden-install-parity/kilo.json b/tests/fixtures/golden-install-parity/kilo.json index 4818d444d..163013a8e 100644 --- a/tests/fixtures/golden-install-parity/kilo.json +++ b/tests/fixtures/golden-install-parity/kilo.json @@ -373,7 +373,7 @@ "gsd-core/workflows/update.md": "07dc2fba78ad1865", "gsd-core/workflows/validate-phase.md": "557e3251e3b9349a", "gsd-core/workflows/verify-phase.md": "0d4ffabc1caa473a", - "gsd-core/workflows/verify-work.md": "41a198eb414e051e", + "gsd-core/workflows/verify-work.md": "b68ac37f6301a3b5", "hooks/gsd-check-update-worker.js": "c992bbad91d0e994", "hooks/gsd-check-update.js": "fdd77abe7ef26a2d", "hooks/gsd-config-reload.js": "96546e0e8bb47904", diff --git a/tests/fixtures/golden-install-parity/kimi.json b/tests/fixtures/golden-install-parity/kimi.json index fce5a3af1..8ad180f00 100644 --- a/tests/fixtures/golden-install-parity/kimi.json +++ b/tests/fixtures/golden-install-parity/kimi.json @@ -339,7 +339,7 @@ "gsd-core/workflows/update.md": "6718e0632bba26ca", "gsd-core/workflows/validate-phase.md": "2c6d7671fcaabcaa", "gsd-core/workflows/verify-phase.md": "98a995046bdb6c3c", - "gsd-core/workflows/verify-work.md": "5ed471293dc6835f", + "gsd-core/workflows/verify-work.md": "34e980a6950cd83c", "scripts/changeset/README.md": "86ff89331dfd94b2", "scripts/changeset/cli.cjs": "68f92a344b199271", "scripts/changeset/github-release-notes.cjs": "795677f0c009b132", diff --git a/tests/fixtures/golden-install-parity/opencode.json b/tests/fixtures/golden-install-parity/opencode.json index dacda292c..f9bacfedd 100644 --- a/tests/fixtures/golden-install-parity/opencode.json +++ b/tests/fixtures/golden-install-parity/opencode.json @@ -373,7 +373,7 @@ "gsd-core/workflows/update.md": "71b6cd852f38b4bc", "gsd-core/workflows/validate-phase.md": "abcdbc1b56780565", "gsd-core/workflows/verify-phase.md": "5bd04b040cd071dd", - "gsd-core/workflows/verify-work.md": "f7dad67215e6b730", + "gsd-core/workflows/verify-work.md": "f0d205568abfaf74", "hooks/gsd-check-update-worker.js": "385fb7c67810baf6", "hooks/gsd-check-update.js": "4549451414ffa7d7", "hooks/gsd-config-reload.js": "96546e0e8bb47904", diff --git a/tests/fixtures/golden-install-parity/qwen.json b/tests/fixtures/golden-install-parity/qwen.json index bec6afbe0..70a06b4a6 100644 --- a/tests/fixtures/golden-install-parity/qwen.json +++ b/tests/fixtures/golden-install-parity/qwen.json @@ -303,7 +303,7 @@ "gsd-core/workflows/update.md": "b34cb866152d4de3", "gsd-core/workflows/validate-phase.md": "e989cbaa4228564c", "gsd-core/workflows/verify-phase.md": "a8679ba1d84145c5", - "gsd-core/workflows/verify-work.md": "5d523d416fef66f0", + "gsd-core/workflows/verify-work.md": "b5afb65fdf311301", "hooks/gsd-check-update-worker.js": "4bb354044e0dff91", "hooks/gsd-check-update.js": "d2065cb3e725a42a", "hooks/gsd-config-reload.js": "4f52b8a0120bb1b8", diff --git a/tests/fixtures/golden-install-parity/trae.json b/tests/fixtures/golden-install-parity/trae.json index a045862ef..cf7f47c38 100644 --- a/tests/fixtures/golden-install-parity/trae.json +++ b/tests/fixtures/golden-install-parity/trae.json @@ -303,7 +303,7 @@ "gsd-core/workflows/update.md": "1f935251fca1f276", "gsd-core/workflows/validate-phase.md": "1c0ebe56d96a14d1", "gsd-core/workflows/verify-phase.md": "53cbdce394dcdac0", - "gsd-core/workflows/verify-work.md": "17b2f2591c3f642e", + "gsd-core/workflows/verify-work.md": "d3a0970205acc6a5", "scripts/changeset/README.md": "86ff89331dfd94b2", "scripts/changeset/cli.cjs": "68f92a344b199271", "scripts/changeset/github-release-notes.cjs": "795677f0c009b132", diff --git a/tests/fixtures/golden-install-parity/windsurf.json b/tests/fixtures/golden-install-parity/windsurf.json index ae20090c1..5ed6aac92 100644 --- a/tests/fixtures/golden-install-parity/windsurf.json +++ b/tests/fixtures/golden-install-parity/windsurf.json @@ -303,7 +303,7 @@ "gsd-core/workflows/update.md": "79aaf4b8f1f83045", "gsd-core/workflows/validate-phase.md": "2db47bf5547d7b9d", "gsd-core/workflows/verify-phase.md": "ea7f8a705b297e27", - "gsd-core/workflows/verify-work.md": "bbf699e62d93d05b", + "gsd-core/workflows/verify-work.md": "5ad63a5edfb6acac", "scripts/changeset/README.md": "86ff89331dfd94b2", "scripts/changeset/cli.cjs": "68f92a344b199271", "scripts/changeset/github-release-notes.cjs": "795677f0c009b132", diff --git a/tests/workflow-size-baseline.json b/tests/workflow-size-baseline.json index bf1ba001e..797f01b89 100644 --- a/tests/workflow-size-baseline.json +++ b/tests/workflow-size-baseline.json @@ -88,5 +88,5 @@ "update.md": 20914, "validate-phase.md": 10789, "verify-phase.md": 40772, - "verify-work.md": 35215 + "verify-work.md": 38267 } From f272983d90f8150e6326b35e93a7d57784bf32ed Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Sun, 5 Jul 2026 15:59:36 -0400 Subject: [PATCH 02/39] =?UTF-8?q?fix(#2019):=20planning-config.md=20global?= =?UTF-8?q?-learnings=20path=20~/.gsd/learnings=20=E2=86=92=20~/.gsd/knowl?= =?UTF-8?q?edge=20(#2026)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(#2019): planning-config.md global-learnings path ~/.gsd/learnings → ~/.gsd/knowledge The features.global_learnings row pointed at ~/.gsd/learnings/ but the implementation (src/learnings.cts, execute-phase.md) uses ~/.gsd/knowledge/. Docs now match the code. Closes #2019 * docs(#2019): backfill changeset pr 2026 --- .changeset/2019-planning-config-learnings-path.md | 5 +++++ gsd-core/references/planning-config.md | 2 +- tests/fixtures/golden-install-parity/antigravity.json | 2 +- tests/fixtures/golden-install-parity/augment.json | 2 +- tests/fixtures/golden-install-parity/claude.json | 2 +- tests/fixtures/golden-install-parity/cline.json | 2 +- tests/fixtures/golden-install-parity/codebuddy.json | 2 +- tests/fixtures/golden-install-parity/codex.json | 2 +- tests/fixtures/golden-install-parity/copilot.json | 2 +- tests/fixtures/golden-install-parity/cursor.json | 2 +- tests/fixtures/golden-install-parity/hermes.json | 2 +- tests/fixtures/golden-install-parity/kilo.json | 2 +- tests/fixtures/golden-install-parity/kimi.json | 2 +- tests/fixtures/golden-install-parity/opencode.json | 2 +- tests/fixtures/golden-install-parity/qwen.json | 2 +- tests/fixtures/golden-install-parity/trae.json | 2 +- tests/fixtures/golden-install-parity/windsurf.json | 2 +- 17 files changed, 21 insertions(+), 16 deletions(-) create mode 100644 .changeset/2019-planning-config-learnings-path.md diff --git a/.changeset/2019-planning-config-learnings-path.md b/.changeset/2019-planning-config-learnings-path.md new file mode 100644 index 000000000..110e8ef95 --- /dev/null +++ b/.changeset/2019-planning-config-learnings-path.md @@ -0,0 +1,5 @@ +--- +type: Fixed +pr: 2026 +--- +**`planning-config.md` global-learnings path corrected to `~/.gsd/knowledge/`** — the `features.global_learnings` row directed users to `~/.gsd/learnings/`, but the implementation (`src/learnings.cts`, `execute-phase.md`) stores and reads global learnings from `~/.gsd/knowledge/`. Anyone following the docs to inspect, back up, or seed their global learnings looked in a directory the code never touches. (#2019) diff --git a/gsd-core/references/planning-config.md b/gsd-core/references/planning-config.md index dcdeaab32..2e52d646f 100644 --- a/gsd-core/references/planning-config.md +++ b/gsd-core/references/planning-config.md @@ -317,7 +317,7 @@ Set via `features.*` namespace (e.g., `"features": { "thinking_partner": true }` | Key | Type | Default | Allowed Values | Description | |-----|------|---------|----------------|-------------| | `features.thinking_partner` | boolean | `false` | `true`, `false` | Enable conditional extended thinking at workflow decision points (used by discuss-phase and plan-phase for architectural tradeoff analysis) | -| `features.global_learnings` | boolean | `false` | `true`, `false` | Enable injection of global learnings from `~/.gsd/learnings/` into agent prompts | +| `features.global_learnings` | boolean | `false` | `true`, `false` | Enable injection of global learnings from `~/.gsd/knowledge/` into agent prompts | ### Hook Fields diff --git a/tests/fixtures/golden-install-parity/antigravity.json b/tests/fixtures/golden-install-parity/antigravity.json index 0c5f07c65..7123e38cf 100644 --- a/tests/fixtures/golden-install-parity/antigravity.json +++ b/tests/fixtures/golden-install-parity/antigravity.json @@ -106,7 +106,7 @@ "gsd-core/references/planner-reviews.md": "da39eace09a10743", "gsd-core/references/planner-revision.md": "86ba8a511f081f05", "gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b", - "gsd-core/references/planning-config.md": "8ce19741d18507f7", + "gsd-core/references/planning-config.md": "49fbbfdac6b8ced4", "gsd-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json": "f10df472f2846cc6", "gsd-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json": "31e8a781eeffe020", "gsd-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json": "70a532a7cc1b6ae8", diff --git a/tests/fixtures/golden-install-parity/augment.json b/tests/fixtures/golden-install-parity/augment.json index c72ac8f1d..8b275f7a4 100644 --- a/tests/fixtures/golden-install-parity/augment.json +++ b/tests/fixtures/golden-install-parity/augment.json @@ -176,7 +176,7 @@ "gsd-core/references/planner-reviews.md": "dda0193a0fbd4947", "gsd-core/references/planner-revision.md": "86ba8a511f081f05", "gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b", - "gsd-core/references/planning-config.md": "1c3a3aae2ae89e83", + "gsd-core/references/planning-config.md": "7fe958e09e74b6c8", "gsd-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json": "f10df472f2846cc6", "gsd-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json": "31e8a781eeffe020", "gsd-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json": "70a532a7cc1b6ae8", diff --git a/tests/fixtures/golden-install-parity/claude.json b/tests/fixtures/golden-install-parity/claude.json index 423300360..6b3c95929 100644 --- a/tests/fixtures/golden-install-parity/claude.json +++ b/tests/fixtures/golden-install-parity/claude.json @@ -105,7 +105,7 @@ "gsd-core/references/planner-reviews.md": "da39eace09a10743", "gsd-core/references/planner-revision.md": "86ba8a511f081f05", "gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b", - "gsd-core/references/planning-config.md": "4435dfdc3381233f", + "gsd-core/references/planning-config.md": "35aa39fef2641311", "gsd-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json": "f10df472f2846cc6", "gsd-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json": "31e8a781eeffe020", "gsd-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json": "70a532a7cc1b6ae8", diff --git a/tests/fixtures/golden-install-parity/cline.json b/tests/fixtures/golden-install-parity/cline.json index 1616c4e1b..f7801242a 100644 --- a/tests/fixtures/golden-install-parity/cline.json +++ b/tests/fixtures/golden-install-parity/cline.json @@ -109,7 +109,7 @@ "gsd-core/references/planner-reviews.md": "dda0193a0fbd4947", "gsd-core/references/planner-revision.md": "86ba8a511f081f05", "gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b", - "gsd-core/references/planning-config.md": "c386ac9e804f862e", + "gsd-core/references/planning-config.md": "15a5fc63268379d4", "gsd-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json": "f10df472f2846cc6", "gsd-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json": "31e8a781eeffe020", "gsd-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json": "70a532a7cc1b6ae8", diff --git a/tests/fixtures/golden-install-parity/codebuddy.json b/tests/fixtures/golden-install-parity/codebuddy.json index 2071962c8..c1c1fca70 100644 --- a/tests/fixtures/golden-install-parity/codebuddy.json +++ b/tests/fixtures/golden-install-parity/codebuddy.json @@ -176,7 +176,7 @@ "gsd-core/references/planner-reviews.md": "dda0193a0fbd4947", "gsd-core/references/planner-revision.md": "86ba8a511f081f05", "gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b", - "gsd-core/references/planning-config.md": "1c3a3aae2ae89e83", + "gsd-core/references/planning-config.md": "7fe958e09e74b6c8", "gsd-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json": "f10df472f2846cc6", "gsd-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json": "31e8a781eeffe020", "gsd-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json": "70a532a7cc1b6ae8", diff --git a/tests/fixtures/golden-install-parity/codex.json b/tests/fixtures/golden-install-parity/codex.json index 623d795ff..fc3b73e94 100644 --- a/tests/fixtures/golden-install-parity/codex.json +++ b/tests/fixtures/golden-install-parity/codex.json @@ -141,7 +141,7 @@ "gsd-core/references/planner-reviews.md": "7889bfa28e82156b", "gsd-core/references/planner-revision.md": "2ebf1a714d1ec4bf", "gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b", - "gsd-core/references/planning-config.md": "0767f44905c9a65e", + "gsd-core/references/planning-config.md": "8593e6610784a339", "gsd-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json": "f10df472f2846cc6", "gsd-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json": "31e8a781eeffe020", "gsd-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json": "70a532a7cc1b6ae8", diff --git a/tests/fixtures/golden-install-parity/copilot.json b/tests/fixtures/golden-install-parity/copilot.json index 94ceacf54..ea63432aa 100644 --- a/tests/fixtures/golden-install-parity/copilot.json +++ b/tests/fixtures/golden-install-parity/copilot.json @@ -107,7 +107,7 @@ "gsd-core/references/planner-reviews.md": "da39eace09a10743", "gsd-core/references/planner-revision.md": "86ba8a511f081f05", "gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b", - "gsd-core/references/planning-config.md": "ea950944302fba67", + "gsd-core/references/planning-config.md": "091d7541826f8cb0", "gsd-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json": "f10df472f2846cc6", "gsd-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json": "31e8a781eeffe020", "gsd-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json": "70a532a7cc1b6ae8", diff --git a/tests/fixtures/golden-install-parity/cursor.json b/tests/fixtures/golden-install-parity/cursor.json index cfb4a61bf..efa98aa06 100644 --- a/tests/fixtures/golden-install-parity/cursor.json +++ b/tests/fixtures/golden-install-parity/cursor.json @@ -176,7 +176,7 @@ "gsd-core/references/planner-reviews.md": "da39eace09a10743", "gsd-core/references/planner-revision.md": "86ba8a511f081f05", "gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b", - "gsd-core/references/planning-config.md": "e2330447f33f6609", + "gsd-core/references/planning-config.md": "a7b41174b754b215", "gsd-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json": "f10df472f2846cc6", "gsd-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json": "31e8a781eeffe020", "gsd-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json": "70a532a7cc1b6ae8", diff --git a/tests/fixtures/golden-install-parity/hermes.json b/tests/fixtures/golden-install-parity/hermes.json index 9a09017f5..9ba6e1882 100644 --- a/tests/fixtures/golden-install-parity/hermes.json +++ b/tests/fixtures/golden-install-parity/hermes.json @@ -106,7 +106,7 @@ "gsd-core/references/planner-reviews.md": "da39eace09a10743", "gsd-core/references/planner-revision.md": "86ba8a511f081f05", "gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b", - "gsd-core/references/planning-config.md": "9b5f8ed49024cdbf", + "gsd-core/references/planning-config.md": "b5a719401e701e12", "gsd-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json": "f10df472f2846cc6", "gsd-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json": "31e8a781eeffe020", "gsd-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json": "70a532a7cc1b6ae8", diff --git a/tests/fixtures/golden-install-parity/kilo.json b/tests/fixtures/golden-install-parity/kilo.json index 163013a8e..1264b0579 100644 --- a/tests/fixtures/golden-install-parity/kilo.json +++ b/tests/fixtures/golden-install-parity/kilo.json @@ -176,7 +176,7 @@ "gsd-core/references/planner-reviews.md": "da39eace09a10743", "gsd-core/references/planner-revision.md": "86ba8a511f081f05", "gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b", - "gsd-core/references/planning-config.md": "4acefb3c71169c84", + "gsd-core/references/planning-config.md": "af0a9694b3c39557", "gsd-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json": "f10df472f2846cc6", "gsd-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json": "31e8a781eeffe020", "gsd-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json": "70a532a7cc1b6ae8", diff --git a/tests/fixtures/golden-install-parity/kimi.json b/tests/fixtures/golden-install-parity/kimi.json index 8ad180f00..ec127f64a 100644 --- a/tests/fixtures/golden-install-parity/kimi.json +++ b/tests/fixtures/golden-install-parity/kimi.json @@ -142,7 +142,7 @@ "gsd-core/references/planner-reviews.md": "dda0193a0fbd4947", "gsd-core/references/planner-revision.md": "86ba8a511f081f05", "gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b", - "gsd-core/references/planning-config.md": "1c3a3aae2ae89e83", + "gsd-core/references/planning-config.md": "7fe958e09e74b6c8", "gsd-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json": "f10df472f2846cc6", "gsd-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json": "31e8a781eeffe020", "gsd-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json": "70a532a7cc1b6ae8", diff --git a/tests/fixtures/golden-install-parity/opencode.json b/tests/fixtures/golden-install-parity/opencode.json index f9bacfedd..2bd2fb15c 100644 --- a/tests/fixtures/golden-install-parity/opencode.json +++ b/tests/fixtures/golden-install-parity/opencode.json @@ -176,7 +176,7 @@ "gsd-core/references/planner-reviews.md": "da39eace09a10743", "gsd-core/references/planner-revision.md": "86ba8a511f081f05", "gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b", - "gsd-core/references/planning-config.md": "4acefb3c71169c84", + "gsd-core/references/planning-config.md": "af0a9694b3c39557", "gsd-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json": "f10df472f2846cc6", "gsd-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json": "31e8a781eeffe020", "gsd-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json": "70a532a7cc1b6ae8", diff --git a/tests/fixtures/golden-install-parity/qwen.json b/tests/fixtures/golden-install-parity/qwen.json index 70a06b4a6..c6d3c85d0 100644 --- a/tests/fixtures/golden-install-parity/qwen.json +++ b/tests/fixtures/golden-install-parity/qwen.json @@ -106,7 +106,7 @@ "gsd-core/references/planner-reviews.md": "da39eace09a10743", "gsd-core/references/planner-revision.md": "86ba8a511f081f05", "gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b", - "gsd-core/references/planning-config.md": "32430b855023bfdb", + "gsd-core/references/planning-config.md": "e8087cf6aae8d56f", "gsd-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json": "f10df472f2846cc6", "gsd-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json": "31e8a781eeffe020", "gsd-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json": "70a532a7cc1b6ae8", diff --git a/tests/fixtures/golden-install-parity/trae.json b/tests/fixtures/golden-install-parity/trae.json index cf7f47c38..06a7c7c96 100644 --- a/tests/fixtures/golden-install-parity/trae.json +++ b/tests/fixtures/golden-install-parity/trae.json @@ -106,7 +106,7 @@ "gsd-core/references/planner-reviews.md": "da39eace09a10743", "gsd-core/references/planner-revision.md": "86ba8a511f081f05", "gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b", - "gsd-core/references/planning-config.md": "970c47f816acdb30", + "gsd-core/references/planning-config.md": "33c5b0685be54e96", "gsd-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json": "f10df472f2846cc6", "gsd-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json": "31e8a781eeffe020", "gsd-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json": "70a532a7cc1b6ae8", diff --git a/tests/fixtures/golden-install-parity/windsurf.json b/tests/fixtures/golden-install-parity/windsurf.json index 5ed6aac92..330979148 100644 --- a/tests/fixtures/golden-install-parity/windsurf.json +++ b/tests/fixtures/golden-install-parity/windsurf.json @@ -106,7 +106,7 @@ "gsd-core/references/planner-reviews.md": "da39eace09a10743", "gsd-core/references/planner-revision.md": "86ba8a511f081f05", "gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b", - "gsd-core/references/planning-config.md": "742e11db47c5c0aa", + "gsd-core/references/planning-config.md": "062db9fe16ec76f9", "gsd-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json": "f10df472f2846cc6", "gsd-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json": "31e8a781eeffe020", "gsd-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json": "70a532a7cc1b6ae8", From 9f0d785b61915b02d427291fe545f541b2f87707 Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Sun, 5 Jul 2026 16:43:26 -0400 Subject: [PATCH 03/39] fix(#2020): remove dead SDK file refs that triggered infinite find.exe on Windows (#2027) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(#2020): remove dead SDK file refs that triggered infinite find.exe on Windows gsd-executor.md referenced sdk/src/query/QUERY-HANDLERS.md and reapply-patches.md referenced sdk/dist/cli.js — both retired with the SDK (ADR-0174). AI runtimes that locate doc refs via filesystem search ran find /, which on Git Bash for Windows traverses the whole drive (14h+, orphaned find.exe, 4M+ handles). - agents/gsd-executor.md: drop dead QUERY-HANDLERS.md ref. - workflows/reapply-patches.md: drop dead sdk/dist/cli.js clause. - tests/no-dead-sdk-refs.test.cjs: regression guard — no sdk/src|dist|handlers file refs in agents/workflows/references markdown. Closes #2020 * docs(#2020): backfill changeset pr 2027 --- .changeset/2020-executor-dead-sdk-ref.md | 5 ++ agents/gsd-executor.md | 2 +- gsd-core/workflows/reapply-patches.md | 2 +- tests/agent-size-baseline.json | 2 +- .../golden-install-parity/antigravity.json | 4 +- .../golden-install-parity/augment.json | 4 +- .../golden-install-parity/claude.json | 4 +- .../fixtures/golden-install-parity/cline.json | 4 +- .../golden-install-parity/codebuddy.json | 4 +- .../fixtures/golden-install-parity/codex.json | 6 +-- .../golden-install-parity/copilot.json | 4 +- .../golden-install-parity/cursor.json | 4 +- .../golden-install-parity/hermes.json | 4 +- .../fixtures/golden-install-parity/kilo.json | 4 +- .../fixtures/golden-install-parity/kimi.json | 4 +- .../golden-install-parity/opencode.json | 4 +- .../fixtures/golden-install-parity/qwen.json | 4 +- .../fixtures/golden-install-parity/trae.json | 4 +- .../golden-install-parity/windsurf.json | 4 +- tests/no-dead-sdk-refs.test.cjs | 54 +++++++++++++++++++ tests/workflow-size-baseline.json | 2 +- 21 files changed, 94 insertions(+), 35 deletions(-) create mode 100644 .changeset/2020-executor-dead-sdk-ref.md create mode 100644 tests/no-dead-sdk-refs.test.cjs diff --git a/.changeset/2020-executor-dead-sdk-ref.md b/.changeset/2020-executor-dead-sdk-ref.md new file mode 100644 index 000000000..2491f753e --- /dev/null +++ b/.changeset/2020-executor-dead-sdk-ref.md @@ -0,0 +1,5 @@ +--- +type: Fixed +pr: 2027 +--- +**Removed dead SDK file references from runtime-loaded markdown that triggered an infinite `find.exe` storm on Windows** — `agents/gsd-executor.md` pointed at `sdk/src/query/QUERY-HANDLERS.md` and `gsd-core/workflows/reapply-patches.md` at `sdk/dist/cli.js`, both retired with the SDK package (ADR-0174). AI runtimes that resolve doc references by filesystem search ran `find / -iname …`; on Git Bash for Windows `/` maps to the drive root, so `find.exe` traversed the whole disk (14h+, orphaned processes, 4M+ open handles each, unkillable). The references now resolve to live paths, and a new regression guard asserts no `sdk/src|sdk/dist|sdk/handlers` file references remain in agents/workflows/references markdown. (#2020) diff --git a/agents/gsd-executor.md b/agents/gsd-executor.md index 136fea55a..cfbe3b08b 100644 --- a/agents/gsd-executor.md +++ b/agents/gsd-executor.md @@ -691,7 +691,7 @@ Do NOT skip. Do NOT proceed to state updates if self-check fails. -After SUMMARY.md, update STATE.md using `gsd-tools query` state handlers (named flags; see `sdk/src/query/QUERY-HANDLERS.md`): +After SUMMARY.md, update STATE.md using `gsd-tools query` state handlers (named flags): ```bash # Advance plan counter (handles edge cases automatically) diff --git a/gsd-core/workflows/reapply-patches.md b/gsd-core/workflows/reapply-patches.md index 94494b33a..f585890ed 100644 --- a/gsd-core/workflows/reapply-patches.md +++ b/gsd-core/workflows/reapply-patches.md @@ -275,7 +275,7 @@ Two layered gates. Both must pass before proceeding to cleanup. Run the deterministic verifier script. Do NOT rely solely on the free-text `verified: yes/no` Hunk Verification Table from Step 4 — bug #2969 traced repeated false-positive `verified: yes` reports to that table being filled in without an actual content-presence check. The script performs the check structurally and exits non-zero on any miss. -Run the verifier as a child process (the gsd-tools binary directory is not required — the script ships under `gsd-core/bin/` in the source repo and is installed to `${GSD_HOME}/gsd-core/bin/`; it is also exposed via the SDK at `sdk/dist/cli.js verify-reapply` when present): +Run the verifier as a child process (the gsd-tools binary directory is not required — the script ships under `gsd-core/bin/` in the source repo and is installed to `${GSD_HOME}/gsd-core/bin/`): ```bash PRISTINE_DIR="${CONFIG_DIR}/gsd-pristine" diff --git a/tests/agent-size-baseline.json b/tests/agent-size-baseline.json index 5374cf811..09622cc3b 100644 --- a/tests/agent-size-baseline.json +++ b/tests/agent-size-baseline.json @@ -14,7 +14,7 @@ "gsd-domain-researcher.md": 6998, "gsd-eval-auditor.md": 12496, "gsd-eval-planner.md": 7008, - "gsd-executor.md": 43578, + "gsd-executor.md": 43539, "gsd-framework-selector.md": 6778, "gsd-integration-checker.md": 15238, "gsd-intel-updater.md": 18166, diff --git a/tests/fixtures/golden-install-parity/antigravity.json b/tests/fixtures/golden-install-parity/antigravity.json index 7123e38cf..02b686cf5 100644 --- a/tests/fixtures/golden-install-parity/antigravity.json +++ b/tests/fixtures/golden-install-parity/antigravity.json @@ -16,7 +16,7 @@ "agents/gsd-domain-researcher.md": "1db46cac3f4d9889", "agents/gsd-eval-auditor.md": "1b8391f1aafb067f", "agents/gsd-eval-planner.md": "3d10fd11147f6857", - "agents/gsd-executor.md": "e3e159690812a81e", + "agents/gsd-executor.md": "e5b95acff5989d80", "agents/gsd-framework-selector.md": "daa62c79619c76bf", "agents/gsd-integration-checker.md": "0643cd2d779b131c", "agents/gsd-intel-updater.md": "26c1f1e028c6346a", @@ -274,7 +274,7 @@ "gsd-core/workflows/profile-user.md": "355af92ac285567f", "gsd-core/workflows/progress.md": "79a11ce798082054", "gsd-core/workflows/quick.md": "a6aa362881f4e5da", - "gsd-core/workflows/reapply-patches.md": "825e37a55a992892", + "gsd-core/workflows/reapply-patches.md": "4dcd6117d0a507ca", "gsd-core/workflows/remove-phase.md": "23b9eb0858a2535e", "gsd-core/workflows/remove-workspace.md": "d0bd7e0601138798", "gsd-core/workflows/resume-project.md": "98e2cf8908e73a52", diff --git a/tests/fixtures/golden-install-parity/augment.json b/tests/fixtures/golden-install-parity/augment.json index 8b275f7a4..7b479cd81 100644 --- a/tests/fixtures/golden-install-parity/augment.json +++ b/tests/fixtures/golden-install-parity/augment.json @@ -16,7 +16,7 @@ "agents/gsd-domain-researcher.md": "671c9ea949889c4a", "agents/gsd-eval-auditor.md": "fcaec7b00f94c435", "agents/gsd-eval-planner.md": "a4a5b4b3f7828ba3", - "agents/gsd-executor.md": "88b1108114a2fa2e", + "agents/gsd-executor.md": "060c6de9f618c2ea", "agents/gsd-framework-selector.md": "4b77eebbe9288d80", "agents/gsd-integration-checker.md": "fa53e2d78be1de74", "agents/gsd-intel-updater.md": "fa40e685d7441ace", @@ -344,7 +344,7 @@ "gsd-core/workflows/profile-user.md": "14263db831230142", "gsd-core/workflows/progress.md": "893aa3c36983f74b", "gsd-core/workflows/quick.md": "3bafc0a59cc90d26", - "gsd-core/workflows/reapply-patches.md": "7915e40411490bbe", + "gsd-core/workflows/reapply-patches.md": "39050f72601aec89", "gsd-core/workflows/remove-phase.md": "df9a45f0b1880999", "gsd-core/workflows/remove-workspace.md": "a7ca66db6b7c132c", "gsd-core/workflows/resume-project.md": "f28da1200e4545f4", diff --git a/tests/fixtures/golden-install-parity/claude.json b/tests/fixtures/golden-install-parity/claude.json index 6b3c95929..1879d2098 100644 --- a/tests/fixtures/golden-install-parity/claude.json +++ b/tests/fixtures/golden-install-parity/claude.json @@ -15,7 +15,7 @@ "agents/gsd-domain-researcher.md": "f8be56555689a970", "agents/gsd-eval-auditor.md": "fea2759beff0a642", "agents/gsd-eval-planner.md": "112f6730f23854e3", - "agents/gsd-executor.md": "5e8219d0a9ff9485", + "agents/gsd-executor.md": "1a0fccbf7a1051cd", "agents/gsd-framework-selector.md": "c350ee693cb1aa4e", "agents/gsd-integration-checker.md": "c8b4e65dee89c8ea", "agents/gsd-intel-updater.md": "5b41e05f90ce89d9", @@ -273,7 +273,7 @@ "gsd-core/workflows/profile-user.md": "ff3820a27731ceb8", "gsd-core/workflows/progress.md": "bd1ecf9207331bda", "gsd-core/workflows/quick.md": "bd56a6313d5ed43c", - "gsd-core/workflows/reapply-patches.md": "2d7dada9edec108b", + "gsd-core/workflows/reapply-patches.md": "ba9406b60f2c4041", "gsd-core/workflows/remove-phase.md": "ada8a0546c686483", "gsd-core/workflows/remove-workspace.md": "f3ab3a88a7e9e1ed", "gsd-core/workflows/resume-project.md": "7f8dc986f0f35d96", diff --git a/tests/fixtures/golden-install-parity/cline.json b/tests/fixtures/golden-install-parity/cline.json index f7801242a..8ed577fb5 100644 --- a/tests/fixtures/golden-install-parity/cline.json +++ b/tests/fixtures/golden-install-parity/cline.json @@ -19,7 +19,7 @@ "agents/gsd-domain-researcher.md": "0fecdaea86466a56", "agents/gsd-eval-auditor.md": "36c44303085df2f8", "agents/gsd-eval-planner.md": "3ddea88a69b4da3f", - "agents/gsd-executor.md": "0a955e3fc57b22b9", + "agents/gsd-executor.md": "b662b48bbacda431", "agents/gsd-framework-selector.md": "564669d479433f15", "agents/gsd-integration-checker.md": "1bbbdd3d420b994e", "agents/gsd-intel-updater.md": "42c40fffbc720d0b", @@ -277,7 +277,7 @@ "gsd-core/workflows/profile-user.md": "26f74db0a7fcd268", "gsd-core/workflows/progress.md": "9f326d63afb4b76b", "gsd-core/workflows/quick.md": "10051a9b41d5d210", - "gsd-core/workflows/reapply-patches.md": "4cfdb59f5d8e727e", + "gsd-core/workflows/reapply-patches.md": "eb4272145a117904", "gsd-core/workflows/remove-phase.md": "e336350f8113a328", "gsd-core/workflows/remove-workspace.md": "e685dfbd736dfd90", "gsd-core/workflows/resume-project.md": "e23981178fa37b3d", diff --git a/tests/fixtures/golden-install-parity/codebuddy.json b/tests/fixtures/golden-install-parity/codebuddy.json index c1c1fca70..6516e362d 100644 --- a/tests/fixtures/golden-install-parity/codebuddy.json +++ b/tests/fixtures/golden-install-parity/codebuddy.json @@ -16,7 +16,7 @@ "agents/gsd-domain-researcher.md": "1c1a800108a2b225", "agents/gsd-eval-auditor.md": "99012004b14ea602", "agents/gsd-eval-planner.md": "4ebdd7fe9cbb0cfe", - "agents/gsd-executor.md": "89fe6f42f9b4003a", + "agents/gsd-executor.md": "28872f650cb8b46d", "agents/gsd-framework-selector.md": "7726fccc86bfeb50", "agents/gsd-integration-checker.md": "2d8339790bbb2dc3", "agents/gsd-intel-updater.md": "c51339956197cbd3", @@ -344,7 +344,7 @@ "gsd-core/workflows/profile-user.md": "4fa910d15dea5695", "gsd-core/workflows/progress.md": "893aa3c36983f74b", "gsd-core/workflows/quick.md": "5e7dcdd864513b87", - "gsd-core/workflows/reapply-patches.md": "7915e40411490bbe", + "gsd-core/workflows/reapply-patches.md": "39050f72601aec89", "gsd-core/workflows/remove-phase.md": "df9a45f0b1880999", "gsd-core/workflows/remove-workspace.md": "a7ca66db6b7c132c", "gsd-core/workflows/resume-project.md": "f28da1200e4545f4", diff --git a/tests/fixtures/golden-install-parity/codex.json b/tests/fixtures/golden-install-parity/codex.json index fc3b73e94..f0b003b85 100644 --- a/tests/fixtures/golden-install-parity/codex.json +++ b/tests/fixtures/golden-install-parity/codex.json @@ -31,8 +31,8 @@ "agents/gsd-eval-auditor.toml": "9b81d61b3c5f722d", "agents/gsd-eval-planner.md": "73f2ad2ff2797a51", "agents/gsd-eval-planner.toml": "09468ad1a34ac468", - "agents/gsd-executor.md": "c5e340b1a279eb2e", - "agents/gsd-executor.toml": "e583836b4db56565", + "agents/gsd-executor.md": "3c4556be34749bde", + "agents/gsd-executor.toml": "4730b30e5bb48e7e", "agents/gsd-framework-selector.md": "ebae32430887d2e0", "agents/gsd-framework-selector.toml": "637e4e021b7ec380", "agents/gsd-integration-checker.md": "9cc875676cf7d741", @@ -309,7 +309,7 @@ "gsd-core/workflows/profile-user.md": "05828c8cc61ef384", "gsd-core/workflows/progress.md": "7bedc431bb55edb8", "gsd-core/workflows/quick.md": "85fb48e52f0b3725", - "gsd-core/workflows/reapply-patches.md": "fba79b3c55c3b2e7", + "gsd-core/workflows/reapply-patches.md": "26297b84736e66a4", "gsd-core/workflows/remove-phase.md": "9ee0fddd11a0d9d4", "gsd-core/workflows/remove-workspace.md": "19d7465aaa50cb62", "gsd-core/workflows/resume-project.md": "9965f87eb278f7f8", diff --git a/tests/fixtures/golden-install-parity/copilot.json b/tests/fixtures/golden-install-parity/copilot.json index ea63432aa..dbcca6f03 100644 --- a/tests/fixtures/golden-install-parity/copilot.json +++ b/tests/fixtures/golden-install-parity/copilot.json @@ -16,7 +16,7 @@ "agents/gsd-domain-researcher.agent.md": "b06738b093df1cb9", "agents/gsd-eval-auditor.agent.md": "3c03009564de55c8", "agents/gsd-eval-planner.agent.md": "14751876fc2b5f16", - "agents/gsd-executor.agent.md": "1c42c925b9113c19", + "agents/gsd-executor.agent.md": "ff6d1fc07a0ff6e7", "agents/gsd-framework-selector.agent.md": "cafeec0b3489be45", "agents/gsd-integration-checker.agent.md": "30439b804927acc7", "agents/gsd-intel-updater.agent.md": "238c1a886f35a25c", @@ -275,7 +275,7 @@ "gsd-core/workflows/profile-user.md": "5cc032206c99ef71", "gsd-core/workflows/progress.md": "6b9a84a43dc55af5", "gsd-core/workflows/quick.md": "89c34e07f1bf6f53", - "gsd-core/workflows/reapply-patches.md": "7e1d16d9a9ccbb03", + "gsd-core/workflows/reapply-patches.md": "8fd59e24b486f180", "gsd-core/workflows/remove-phase.md": "e262654e319d1bc4", "gsd-core/workflows/remove-workspace.md": "ceddfeef5f2d6754", "gsd-core/workflows/resume-project.md": "40db7f350f5866d8", diff --git a/tests/fixtures/golden-install-parity/cursor.json b/tests/fixtures/golden-install-parity/cursor.json index efa98aa06..f1774e92b 100644 --- a/tests/fixtures/golden-install-parity/cursor.json +++ b/tests/fixtures/golden-install-parity/cursor.json @@ -16,7 +16,7 @@ "agents/gsd-domain-researcher.md": "56395dbdabf076f6", "agents/gsd-eval-auditor.md": "ad2840fd5cd76172", "agents/gsd-eval-planner.md": "2049dac060d00eda", - "agents/gsd-executor.md": "058936492c4f2814", + "agents/gsd-executor.md": "7e39d497c77b7c5a", "agents/gsd-framework-selector.md": "4b77eebbe9288d80", "agents/gsd-integration-checker.md": "5da30584d06b878c", "agents/gsd-intel-updater.md": "b8971c5d96e63b38", @@ -344,7 +344,7 @@ "gsd-core/workflows/profile-user.md": "8c943983241260b5", "gsd-core/workflows/progress.md": "65aabee5e8a6dd82", "gsd-core/workflows/quick.md": "db98fdbe79d68ffc", - "gsd-core/workflows/reapply-patches.md": "2d7dada9edec108b", + "gsd-core/workflows/reapply-patches.md": "ba9406b60f2c4041", "gsd-core/workflows/remove-phase.md": "ada8a0546c686483", "gsd-core/workflows/remove-workspace.md": "433affcd1a200826", "gsd-core/workflows/resume-project.md": "7f8dc986f0f35d96", diff --git a/tests/fixtures/golden-install-parity/hermes.json b/tests/fixtures/golden-install-parity/hermes.json index 9ba6e1882..a97c2d2be 100644 --- a/tests/fixtures/golden-install-parity/hermes.json +++ b/tests/fixtures/golden-install-parity/hermes.json @@ -16,7 +16,7 @@ "agents/gsd-domain-researcher.md": "d4c07520f650ffd5", "agents/gsd-eval-auditor.md": "4ffb265063c318e5", "agents/gsd-eval-planner.md": "03448fc9c5774b56", - "agents/gsd-executor.md": "aed0ea22f9322b2c", + "agents/gsd-executor.md": "0667b16c383d033c", "agents/gsd-framework-selector.md": "ea9981d65d6b3429", "agents/gsd-integration-checker.md": "35b4f2969d279871", "agents/gsd-intel-updater.md": "5fe5edfae2719cb8", @@ -274,7 +274,7 @@ "gsd-core/workflows/profile-user.md": "de5030437226cf2c", "gsd-core/workflows/progress.md": "f18db000584d9cb1", "gsd-core/workflows/quick.md": "66b26d6fe2bd4d71", - "gsd-core/workflows/reapply-patches.md": "7af45bb3f2fdd1b8", + "gsd-core/workflows/reapply-patches.md": "158083a310859594", "gsd-core/workflows/remove-phase.md": "fce799aae3ab2715", "gsd-core/workflows/remove-workspace.md": "8facde381657dd71", "gsd-core/workflows/resume-project.md": "a0443839f1f83c2d", diff --git a/tests/fixtures/golden-install-parity/kilo.json b/tests/fixtures/golden-install-parity/kilo.json index 1264b0579..9394242a9 100644 --- a/tests/fixtures/golden-install-parity/kilo.json +++ b/tests/fixtures/golden-install-parity/kilo.json @@ -16,7 +16,7 @@ "agents/gsd-domain-researcher.md": "a3874d80bcbc7380", "agents/gsd-eval-auditor.md": "630d4cd3bd6ea195", "agents/gsd-eval-planner.md": "3db12cde12aeb2c1", - "agents/gsd-executor.md": "3ee15ac212214106", + "agents/gsd-executor.md": "41575d10fe41e36a", "agents/gsd-framework-selector.md": "ad5f2c6b9bec6270", "agents/gsd-integration-checker.md": "c503e2f4a3d8ec05", "agents/gsd-intel-updater.md": "231393da62a45b2e", @@ -344,7 +344,7 @@ "gsd-core/workflows/profile-user.md": "203ebe3f8f3876a8", "gsd-core/workflows/progress.md": "9381c59676ccb937", "gsd-core/workflows/quick.md": "11ba83f6350462fb", - "gsd-core/workflows/reapply-patches.md": "2c44426624047ed0", + "gsd-core/workflows/reapply-patches.md": "becf9728cdb124c4", "gsd-core/workflows/remove-phase.md": "ada8a0546c686483", "gsd-core/workflows/remove-workspace.md": "fc83f362a2d0a1b7", "gsd-core/workflows/resume-project.md": "7f8dc986f0f35d96", diff --git a/tests/fixtures/golden-install-parity/kimi.json b/tests/fixtures/golden-install-parity/kimi.json index ec127f64a..99b174f6a 100644 --- a/tests/fixtures/golden-install-parity/kimi.json +++ b/tests/fixtures/golden-install-parity/kimi.json @@ -33,7 +33,7 @@ "agents/subagents/gsd-eval-auditor.yaml": "e3d868bd5fefe938", "agents/subagents/gsd-eval-planner.md": "70f8c5727bfb9876", "agents/subagents/gsd-eval-planner.yaml": "df8499f7af297ec2", - "agents/subagents/gsd-executor.md": "9b7607df31335054", + "agents/subagents/gsd-executor.md": "5ad0e1b4c9cd5c7e", "agents/subagents/gsd-executor.yaml": "e29422986636fd64", "agents/subagents/gsd-framework-selector.md": "a15b7aa1e0576e16", "agents/subagents/gsd-framework-selector.yaml": "fb52c31cde27b0e3", @@ -310,7 +310,7 @@ "gsd-core/workflows/profile-user.md": "5abfae83739fa978", "gsd-core/workflows/progress.md": "893aa3c36983f74b", "gsd-core/workflows/quick.md": "d722803b72217377", - "gsd-core/workflows/reapply-patches.md": "7915e40411490bbe", + "gsd-core/workflows/reapply-patches.md": "39050f72601aec89", "gsd-core/workflows/remove-phase.md": "df9a45f0b1880999", "gsd-core/workflows/remove-workspace.md": "a7ca66db6b7c132c", "gsd-core/workflows/resume-project.md": "f28da1200e4545f4", diff --git a/tests/fixtures/golden-install-parity/opencode.json b/tests/fixtures/golden-install-parity/opencode.json index 2bd2fb15c..edf5af8c4 100644 --- a/tests/fixtures/golden-install-parity/opencode.json +++ b/tests/fixtures/golden-install-parity/opencode.json @@ -16,7 +16,7 @@ "agents/gsd-domain-researcher.md": "71250e759ca9e723", "agents/gsd-eval-auditor.md": "c88890105f32ace6", "agents/gsd-eval-planner.md": "60bddb70a937f796", - "agents/gsd-executor.md": "d14a44fd6ae0935b", + "agents/gsd-executor.md": "70fddc081560944d", "agents/gsd-framework-selector.md": "1c0a10355e787675", "agents/gsd-integration-checker.md": "a9de5928e5a5c649", "agents/gsd-intel-updater.md": "493e07482fa6198a", @@ -344,7 +344,7 @@ "gsd-core/workflows/profile-user.md": "248d59a31948e0ed", "gsd-core/workflows/progress.md": "8fc3404087f50b95", "gsd-core/workflows/quick.md": "3866a5259e8912d8", - "gsd-core/workflows/reapply-patches.md": "a6cfec7e2a0e7ee2", + "gsd-core/workflows/reapply-patches.md": "a0e9b53f90abceb2", "gsd-core/workflows/remove-phase.md": "dea4661e8f89596f", "gsd-core/workflows/remove-workspace.md": "446847e71aa52504", "gsd-core/workflows/resume-project.md": "ad9f06a10bab8cc0", diff --git a/tests/fixtures/golden-install-parity/qwen.json b/tests/fixtures/golden-install-parity/qwen.json index c6d3c85d0..c2f3eb0b6 100644 --- a/tests/fixtures/golden-install-parity/qwen.json +++ b/tests/fixtures/golden-install-parity/qwen.json @@ -16,7 +16,7 @@ "agents/gsd-domain-researcher.md": "d4c07520f650ffd5", "agents/gsd-eval-auditor.md": "2d121dbec93fd4ce", "agents/gsd-eval-planner.md": "03448fc9c5774b56", - "agents/gsd-executor.md": "748d8595f8c530bc", + "agents/gsd-executor.md": "7c8fe1370531a609", "agents/gsd-framework-selector.md": "ea9981d65d6b3429", "agents/gsd-integration-checker.md": "33fd537b862eb944", "agents/gsd-intel-updater.md": "699dacdc0a1f2478", @@ -274,7 +274,7 @@ "gsd-core/workflows/profile-user.md": "263c0693563d98da", "gsd-core/workflows/progress.md": "3b1b2142a74af85c", "gsd-core/workflows/quick.md": "518740e30dcd4da3", - "gsd-core/workflows/reapply-patches.md": "4a93b90cbe70a2f1", + "gsd-core/workflows/reapply-patches.md": "de0ee8acfe7245b2", "gsd-core/workflows/remove-phase.md": "e8ae4fbbfac700f0", "gsd-core/workflows/remove-workspace.md": "4ac64de862dc650e", "gsd-core/workflows/resume-project.md": "7f20769f302e5427", diff --git a/tests/fixtures/golden-install-parity/trae.json b/tests/fixtures/golden-install-parity/trae.json index 06a7c7c96..2debe0ec7 100644 --- a/tests/fixtures/golden-install-parity/trae.json +++ b/tests/fixtures/golden-install-parity/trae.json @@ -16,7 +16,7 @@ "agents/gsd-domain-researcher.md": "b80f76874c04e515", "agents/gsd-eval-auditor.md": "470bf16303ec4d2e", "agents/gsd-eval-planner.md": "22334fde85723c9d", - "agents/gsd-executor.md": "381f4a44532d8b1b", + "agents/gsd-executor.md": "a918ba64279d1a8c", "agents/gsd-framework-selector.md": "7726fccc86bfeb50", "agents/gsd-integration-checker.md": "7cd2072984411c7f", "agents/gsd-intel-updater.md": "83de6ba9172891c3", @@ -274,7 +274,7 @@ "gsd-core/workflows/profile-user.md": "672821e6b1266645", "gsd-core/workflows/progress.md": "94768f835b0b8908", "gsd-core/workflows/quick.md": "8ac5f3919f754499", - "gsd-core/workflows/reapply-patches.md": "ea66e63f56e7deb3", + "gsd-core/workflows/reapply-patches.md": "21b38c374f19fd78", "gsd-core/workflows/remove-phase.md": "a46c2fe853bf4e86", "gsd-core/workflows/remove-workspace.md": "ae0e1c6d4438d663", "gsd-core/workflows/resume-project.md": "f242e4c8aba18ea2", diff --git a/tests/fixtures/golden-install-parity/windsurf.json b/tests/fixtures/golden-install-parity/windsurf.json index 330979148..af04dbed3 100644 --- a/tests/fixtures/golden-install-parity/windsurf.json +++ b/tests/fixtures/golden-install-parity/windsurf.json @@ -16,7 +16,7 @@ "agents/gsd-domain-researcher.md": "56395dbdabf076f6", "agents/gsd-eval-auditor.md": "fb64fc5acf359747", "agents/gsd-eval-planner.md": "2049dac060d00eda", - "agents/gsd-executor.md": "704ea6e1d44da9c1", + "agents/gsd-executor.md": "56ad34feb3cf5f12", "agents/gsd-framework-selector.md": "4b77eebbe9288d80", "agents/gsd-integration-checker.md": "4ffb37fb230c2b90", "agents/gsd-intel-updater.md": "a81d77c143c02108", @@ -274,7 +274,7 @@ "gsd-core/workflows/profile-user.md": "c4313672b81b5bcd", "gsd-core/workflows/progress.md": "18813a345bd2343a", "gsd-core/workflows/quick.md": "0fcad72e7dbe99c9", - "gsd-core/workflows/reapply-patches.md": "04885b2129cbb457", + "gsd-core/workflows/reapply-patches.md": "d449a23d3acf6379", "gsd-core/workflows/remove-phase.md": "e7a6af429b36e77b", "gsd-core/workflows/remove-workspace.md": "b5e60fbb33b3e33a", "gsd-core/workflows/resume-project.md": "82cfe1b8cb17c085", diff --git a/tests/no-dead-sdk-refs.test.cjs b/tests/no-dead-sdk-refs.test.cjs new file mode 100644 index 000000000..eaee21245 --- /dev/null +++ b/tests/no-dead-sdk-refs.test.cjs @@ -0,0 +1,54 @@ +'use strict'; + +// Regression guard for #2020 — dead SDK file references (sdk/src/..., sdk/dist/...) +// in runtime-loaded markdown cause AI runtimes to `find` them; on Git Bash for +// Windows `find /` traverses the whole drive (14h+, orphaned find.exe, 4M+ handles). +// The SDK package was retired (ADR-0174), so these paths never resolve. +// +// Scans the markdown a runtime loads + tries to locate references in +// (agents/, workflows/, references/) and fails on any sdk/(src|dist|handlers) +// file-path reference. Code-comment mentions in *.cjs (historical prose, not +// locatable file refs) are out of scope. + +const { describe, test } = require('node:test'); +const assert = require('node:assert/strict'); +const fs = require('fs'); +const path = require('path'); + +const ROOT = path.join(__dirname, '..'); +// Runtime-loaded markdown surfaces (the issue is about references a runtime +// tries to LOCATE as files — agents/workflows/references, not source comments). +const SCAN_DIRS = ['agents', 'gsd-core/workflows', 'gsd-core/references']; +// A dead SDK file-path reference: sdk/src|sdk/dist|sdk/handlers followed by a path. +const DEAD_SDK_REF = /sdk\/(?:src|dist|handlers)\//; + +function walkMd(dir, out = []) { + let entries; + try { entries = fs.readdirSync(dir, { withFileTypes: true }); } + catch { return out; } + for (const e of entries) { + const full = path.join(dir, e.name); + if (e.isDirectory()) walkMd(full, out); + else if (e.isFile() && e.name.endsWith('.md')) out.push(full); + } + return out; +} + +describe('#2020 — no dead SDK file references in runtime-loaded markdown', () => { + const offenders = []; + for (const rel of SCAN_DIRS) { + const absDir = path.join(ROOT, rel); + for (const file of walkMd(absDir)) { + const content = fs.readFileSync(file, 'utf8'); + const lines = content.split(/\r?\n/); + lines.forEach((line, i) => { + if (DEAD_SDK_REF.test(line)) offenders.push(`${path.relative(ROOT, file)}:${i + 1}`); + }); + } + } + + test('agents/workflows/references contain no sdk/src|sdk/dist|sdk/handlers references', () => { + assert.deepEqual(offenders, [], + `Dead SDK file references found (runtimes \`find\` these → #2020 Windows find.exe storm):\n${offenders.join('\n')}`); + }); +}); diff --git a/tests/workflow-size-baseline.json b/tests/workflow-size-baseline.json index 797f01b89..c5f07afdb 100644 --- a/tests/workflow-size-baseline.json +++ b/tests/workflow-size-baseline.json @@ -59,7 +59,7 @@ "profile-user.md": 21246, "progress.md": 30599, "quick.md": 49183, - "reapply-patches.md": 20393, + "reapply-patches.md": 20312, "remove-phase.md": 8513, "remove-workspace.md": 7551, "resume-project.md": 17270, From bb01f46c6bf394db78a03117eaa3c6a0f6fa30e3 Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Sun, 5 Jul 2026 16:59:23 -0400 Subject: [PATCH 04/39] fix(#2022): gate roadmap update-plan-progress checkbox on verification passed (#2030) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(#2022): gate roadmap update-plan-progress checkbox on verification passed cmdRoadmapUpdatePlanProgress stamped the phase checkbox + completion date the moment all summaries landed, with NO verification gate — unlike cmdPhaseComplete (phase.cts:1436) which checks readVerificationStatus. Since update-plan-progress is called after every wave and every plan, the checkbox fired before gsd-verifier confirmed the phase. - src/roadmap.cts: isComplete now requires summaryCount >= planCount AND readVerificationStatus(phaseDir).status === 'passed'. - tests/roadmap.test.cjs: 2 regression tests (no VERIFICATION.md → not complete; gaps_found → not complete) + updated 3 existing complete tests to include a passed VERIFICATION.md. Closes #2022 * docs(#2022): backfill changeset pr 2030 --- .changeset/2022-roadmap-verify-gate.md | 5 ++ src/roadmap.cts | 11 +++- tests/roadmap.test.cjs | 79 +++++++++++++++++++++++++- 3 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 .changeset/2022-roadmap-verify-gate.md diff --git a/.changeset/2022-roadmap-verify-gate.md b/.changeset/2022-roadmap-verify-gate.md new file mode 100644 index 000000000..bd31bfd92 --- /dev/null +++ b/.changeset/2022-roadmap-verify-gate.md @@ -0,0 +1,5 @@ +--- +type: Fixed +pr: 2030 +--- +**`roadmap update-plan-progress` no longer checks the phase checkbox without verification** — the command stamped the phase-level ROADMAP checkbox and completion date the moment the last plan summary landed (called routinely after every wave and every plan), with **no verification gate** — unlike `phase.complete` which correctly requires `readVerificationStatus(...).status === 'passed'`. Now `isComplete` requires both all plan summaries AND a passed verification, matching the `cmdPhaseComplete` contract, so the checkbox only fires after `gsd-verifier` has confirmed the phase. (#2022) diff --git a/src/roadmap.cts b/src/roadmap.cts index 654493111..740794042 100644 --- a/src/roadmap.cts +++ b/src/roadmap.cts @@ -34,6 +34,9 @@ const { countMatchedSummaries } = coreUtils; // eslint-disable-next-line @typescript-eslint/no-require-imports import frontmatter = require('./frontmatter.cjs'); const { extractFrontmatter, parseMustHavesBlock } = frontmatter; +// eslint-disable-next-line @typescript-eslint/no-require-imports +import verificationMod = require('./verification.cjs'); +const { readVerificationStatus } = verificationMod; // ─── Types ──────────────────────────────────────────────────────────────────── @@ -504,7 +507,13 @@ function cmdRoadmapUpdatePlanProgress(cwd: string, phaseNum: string | null | und return; } - const isComplete = summaryCount >= planCount; + // Verification gate (#2022): do NOT check the phase checkbox or stamp a + // completion date until the phase's verification status is 'passed', matching + // cmdPhaseComplete's gate (phase.cts:1436). Previously the checkbox fired the + // moment the last plan summary landed — before gsd-verifier had verified. + const phaseDir = path.join(cwd, phaseInfo!.directory); + const verificationPassed = readVerificationStatus(phaseDir).status === 'passed'; + const isComplete = summaryCount >= planCount && verificationPassed; const status = isComplete ? 'Complete' : summaryCount > 0 ? 'In Progress' : 'Planned'; const today = realClock.today(); diff --git a/tests/roadmap.test.cjs b/tests/roadmap.test.cjs index 83ef41f8d..da0ebfe65 100644 --- a/tests/roadmap.test.cjs +++ b/tests/roadmap.test.cjs @@ -814,6 +814,80 @@ describe('roadmap update-plan-progress command', () => { assert.ok(!/\[x\] \*\*Phase 30/.test(roadmapContent), 'phase checkbox must not be checked'); }); + test('#2022 — all summaries present but verification NOT passed → checkbox NOT checked', () => { + fs.writeFileSync( + path.join(tmpDir, '.planning', 'ROADMAP.md'), + `# Roadmap + +- [ ] **Phase 1: Test** - description + +### Phase 1: Test +**Goal:** Test goal +**Plans:** TBD + +## Progress + +| Phase | Milestone | Plans Complete | Status | Completed | +|-------|-----------|----------------|--------|-----------| +| 1. Test | v1.0 | 0/1 | Planned | - | +` + ); + + // 1 plan + 1 summary (all summaries present) but NO VERIFICATION.md → the + // verification gate (#2022) must prevent the checkbox from being checked. + const p1 = path.join(tmpDir, '.planning', 'phases', '01-test'); + fs.mkdirSync(p1, { recursive: true }); + fs.writeFileSync(path.join(p1, '01-01-PLAN.md'), '# Plan 1'); + fs.writeFileSync(path.join(p1, '01-01-SUMMARY.md'), '# Summary 1'); + + const result = runGsdTools('roadmap update-plan-progress 1', tmpDir); + assert.ok(result.success, `Command failed: ${result.error}`); + + const output = JSON.parse(result.output); + assert.strictEqual(output.complete, false, 'must NOT be complete without verification'); + assert.strictEqual(output.status, 'In Progress', 'status should be In Progress (not Complete)'); + + const roadmapContent = fs.readFileSync(path.join(tmpDir, '.planning', 'ROADMAP.md'), 'utf-8'); + assert.ok(roadmapContent.includes('[ ] **Phase 1'), 'phase checkbox must remain unchecked'); + assert.ok(!/\[x\] \*\*Phase 1/.test(roadmapContent), 'phase checkbox must NOT be checked without verification'); + assert.ok(roadmapContent.includes('1/1'), 'plan count should still be updated'); + }); + + test('#2022 — verification status NOT passed → checkbox NOT checked', () => { + fs.writeFileSync( + path.join(tmpDir, '.planning', 'ROADMAP.md'), + `# Roadmap + +- [ ] **Phase 1: Test** + +### Phase 1: Test +**Goal:** Test goal + +## Progress + +| Phase | Milestone | Plans Complete | Status | Completed | +|-------|-----------|----------------|--------|-----------| +| 1. Test | v1.0 | 0/1 | Planned | - | +` + ); + + const p1 = path.join(tmpDir, '.planning', 'phases', '01-test'); + fs.mkdirSync(p1, { recursive: true }); + fs.writeFileSync(path.join(p1, '01-01-PLAN.md'), '# Plan 1'); + fs.writeFileSync(path.join(p1, '01-01-SUMMARY.md'), '# Summary 1'); + // Verification exists but status is gaps_found (not passed) + fs.writeFileSync(path.join(p1, '01-VERIFICATION.md'), '---\nstatus: gaps_found\n---\n# Verification\n'); + + const result = runGsdTools('roadmap update-plan-progress 1', tmpDir); + assert.ok(result.success, `Command failed: ${result.error}`); + + const output = JSON.parse(result.output); + assert.strictEqual(output.complete, false, 'must NOT be complete (verification gaps_found)'); + assert.strictEqual(output.status, 'In Progress'); + const roadmapContent = fs.readFileSync(path.join(tmpDir, '.planning', 'ROADMAP.md'), 'utf-8'); + assert.ok(!roadmapContent.includes('[x]'), 'checkbox must NOT be checked (verification not passed)'); + }); + test('updates progress and checks checkbox on completion', () => { fs.writeFileSync( path.join(tmpDir, '.planning', 'ROADMAP.md'), @@ -833,11 +907,12 @@ describe('roadmap update-plan-progress command', () => { ` ); - // Create phase dir with 1 plan, 1 summary (complete) + // Create phase dir with 1 plan, 1 summary (complete) + verification passed (#2022 gate) const p1 = path.join(tmpDir, '.planning', 'phases', '01-test'); fs.mkdirSync(p1, { recursive: true }); fs.writeFileSync(path.join(p1, '01-01-PLAN.md'), '# Plan 1'); fs.writeFileSync(path.join(p1, '01-01-SUMMARY.md'), '# Summary 1'); + fs.writeFileSync(path.join(p1, '01-VERIFICATION.md'), '---\nstatus: passed\n---\n# Verification\n'); const result = runGsdTools('roadmap update-plan-progress 1', tmpDir); assert.ok(result.success, `Command failed: ${result.error}`); @@ -878,6 +953,7 @@ describe('roadmap update-plan-progress command', () => { fs.mkdirSync(p3, { recursive: true }); fs.writeFileSync(path.join(p3, '03-01-PLAN.md'), '# Plan 1'); fs.writeFileSync(path.join(p3, '03-01-SUMMARY.md'), '# Summary 1'); + fs.writeFileSync(path.join(p3, '03-VERIFICATION.md'), '---\nstatus: passed\n---\n# Verification\n'); const result = runGsdTools('roadmap update-plan-progress 03', tmpDir); assert.ok(result.success, `Command failed: ${result.error}`); @@ -959,6 +1035,7 @@ describe('roadmap update-plan-progress command', () => { fs.mkdirSync(p50, { recursive: true }); fs.writeFileSync(path.join(p50, '50-01-PLAN.md'), '# Plan'); fs.writeFileSync(path.join(p50, '50-01-SUMMARY.md'), '# Summary'); + fs.writeFileSync(path.join(p50, '50-VERIFICATION.md'), '---\nstatus: passed\n---\n# Verification\n'); const result = runGsdTools('roadmap update-plan-progress 50', tmpDir); assert.ok(result.success, `Command failed: ${result.error}`); From 68a5258d454cc550976d1e8f42332e7b86db0f27 Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Sun, 5 Jul 2026 17:15:48 -0400 Subject: [PATCH 05/39] fix(#2017): grant mcp__plugin_context7_context7__* for plugin-marketplace context7 (8 agents) (#2029) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(#2017: grant mcp__plugin_context7_context7__* for plugin-marketplace context7 The 8 context7-using agents granted only mcp__context7__* (standalone server form). Claude Code's plugin-marketplace context7 install names tools mcp__plugin_context7_context7__*, so the grant never matched and every researcher/planner/executor silently lost doc lookup (fell back to WebSearch). - 8 agents: add mcp__plugin_context7_context7__* alongside mcp__context7__*. - scripts/research-profiles.cjs: update the researcher profile tools to match. - tests/context7-plugin-grant-parity.test.cjs: regression guard — no agent grants the standalone form without the plugin form. Closes #2017 * docs(#2017): backfill changeset pr 2029 --- .../2017-context7-plugin-grant-prefix.md | 5 +++ agents/gsd-advisor-researcher.md | 2 +- agents/gsd-ai-researcher.md | 2 +- agents/gsd-domain-researcher.md | 2 +- agents/gsd-executor.md | 4 +-- agents/gsd-phase-researcher.md | 2 +- agents/gsd-planner.md | 2 +- agents/gsd-project-researcher.md | 2 +- agents/gsd-ui-researcher.md | 2 +- scripts/research-profiles.cjs | 12 +++---- tests/agent-size-baseline.json | 16 ++++----- tests/context7-plugin-grant-parity.test.cjs | 35 +++++++++++++++++++ .../golden-install-parity/antigravity.json | 2 +- .../golden-install-parity/augment.json | 2 +- .../golden-install-parity/claude.json | 16 ++++----- .../fixtures/golden-install-parity/cline.json | 2 +- .../golden-install-parity/codebuddy.json | 2 +- .../fixtures/golden-install-parity/codex.json | 18 +++++----- .../golden-install-parity/copilot.json | 16 ++++----- .../golden-install-parity/cursor.json | 2 +- .../golden-install-parity/hermes.json | 16 ++++----- .../fixtures/golden-install-parity/kilo.json | 2 +- .../fixtures/golden-install-parity/kimi.json | 2 +- .../golden-install-parity/opencode.json | 2 +- .../fixtures/golden-install-parity/qwen.json | 16 ++++----- .../fixtures/golden-install-parity/trae.json | 2 +- .../golden-install-parity/windsurf.json | 2 +- 27 files changed, 114 insertions(+), 74 deletions(-) create mode 100644 .changeset/2017-context7-plugin-grant-prefix.md create mode 100644 tests/context7-plugin-grant-parity.test.cjs diff --git a/.changeset/2017-context7-plugin-grant-prefix.md b/.changeset/2017-context7-plugin-grant-prefix.md new file mode 100644 index 000000000..91eb0250b --- /dev/null +++ b/.changeset/2017-context7-plugin-grant-prefix.md @@ -0,0 +1,5 @@ +--- +type: Fixed +pr: 2029 +--- +**context7 now works for plugin-marketplace installs (8 agents regained doc lookup)** — the agents granted only `mcp__context7__*`, which matches a standalone context7 MCP server but not the official Claude Code plugin-marketplace install (`context7@claude-plugins-official`), whose tools are named `mcp__plugin_context7_context7__*`. The grant never matched, so advisor/ai/domain/phase/project/ui-researcher + planner + executor silently lost documentation lookup and fell back to WebSearch. All 8 agents now grant both forms, the researcher profile table is updated, and a parity guard asserts no agent grants the standalone form without the plugin form. (#2017) diff --git a/agents/gsd-advisor-researcher.md b/agents/gsd-advisor-researcher.md index b6fcf61c7..62d84bc7e 100644 --- a/agents/gsd-advisor-researcher.md +++ b/agents/gsd-advisor-researcher.md @@ -1,7 +1,7 @@ --- name: gsd-advisor-researcher description: Researches a single gray area decision and returns a structured comparison table with rationale. Spawned by discuss-phase advisor mode. -tools: Read, Bash, Grep, Glob, Skill, WebSearch, WebFetch, mcp__context7__* +tools: Read, Bash, Grep, Glob, Skill, WebSearch, WebFetch, mcp__context7__*, mcp__plugin_context7_context7__* color: cyan --- diff --git a/agents/gsd-ai-researcher.md b/agents/gsd-ai-researcher.md index e9df2d44b..9c9a66db3 100644 --- a/agents/gsd-ai-researcher.md +++ b/agents/gsd-ai-researcher.md @@ -1,7 +1,7 @@ --- name: gsd-ai-researcher description: Researches a chosen AI framework's official docs to produce implementation-ready guidance — best practices, syntax, core patterns, and pitfalls distilled for the specific use case. Writes the Framework Quick Reference and Implementation Guidance sections of AI-SPEC.md. Spawned by /gsd:ai-integration-phase orchestrator. -tools: Read, Write, Edit, Bash, Grep, Glob, WebFetch, WebSearch, mcp__context7__* +tools: Read, Write, Edit, Bash, Grep, Glob, WebFetch, WebSearch, mcp__context7__*, mcp__plugin_context7_context7__* color: green # hooks: # PostToolUse: diff --git a/agents/gsd-domain-researcher.md b/agents/gsd-domain-researcher.md index 3b355b57a..701cb4022 100644 --- a/agents/gsd-domain-researcher.md +++ b/agents/gsd-domain-researcher.md @@ -1,7 +1,7 @@ --- name: gsd-domain-researcher description: Researches the business domain and real-world application context of the AI system being built. Surfaces domain expert evaluation criteria, industry-specific failure modes, regulatory context, and what "good" looks like for practitioners in this field — before the eval-planner turns it into measurable rubrics. Spawned by /gsd:ai-integration-phase orchestrator. -tools: Read, Write, Edit, Bash, Grep, Glob, WebSearch, WebFetch, mcp__context7__* +tools: Read, Write, Edit, Bash, Grep, Glob, WebSearch, WebFetch, mcp__context7__*, mcp__plugin_context7_context7__* color: purple # hooks: # PostToolUse: diff --git a/agents/gsd-executor.md b/agents/gsd-executor.md index cfbe3b08b..6f4ecc5fd 100644 --- a/agents/gsd-executor.md +++ b/agents/gsd-executor.md @@ -1,7 +1,7 @@ --- name: gsd-executor description: Executes GSD plans with atomic commits, deviation handling, checkpoint protocols, and state management. Spawned by execute-phase orchestrator or execute-plan command. -tools: Read, Write, Edit, Bash, Grep, Glob, Skill, mcp__context7__* +tools: Read, Write, Edit, Bash, Grep, Glob, Skill, mcp__context7__*, mcp__plugin_context7_context7__* color: yellow # hooks: # PostToolUse: @@ -24,7 +24,7 @@ Your job: Execute the plan completely, commit each task, create SUMMARY.md, upda When you need library or framework documentation, check in this order: -1. If Context7 MCP tools (`mcp__context7__*`) are available in your environment, use them: +1. If Context7 MCP tools (`mcp__context7__*, mcp__plugin_context7_context7__*`) are available in your environment, use them: - Resolve library ID: `mcp__context7__resolve-library-id` with `libraryName` - Fetch docs: `mcp__context7__get-library-docs` with `context7CompatibleLibraryId` and `topic` diff --git a/agents/gsd-phase-researcher.md b/agents/gsd-phase-researcher.md index aeec0d9bf..00bd8ff21 100644 --- a/agents/gsd-phase-researcher.md +++ b/agents/gsd-phase-researcher.md @@ -1,7 +1,7 @@ --- name: gsd-phase-researcher description: Researches how to implement a phase before planning. Produces RESEARCH.md consumed by gsd-planner. Spawned by /gsd:plan-phase orchestrator. -tools: Read, Write, Edit, Bash, Grep, Glob, Skill, WebSearch, WebFetch, mcp__context7__*, mcp__firecrawl__*, mcp__exa__*, mcp__tavily__*, mcp__ref__*, mcp__jina__*, mcp__perplexity__* +tools: Read, Write, Edit, Bash, Grep, Glob, Skill, WebSearch, WebFetch, mcp__context7__*, mcp__plugin_context7_context7__*, mcp__firecrawl__*, mcp__exa__*, mcp__tavily__*, mcp__ref__*, mcp__jina__*, mcp__perplexity__* color: cyan # hooks: # PostToolUse: diff --git a/agents/gsd-planner.md b/agents/gsd-planner.md index 3c8ece56e..18a792769 100644 --- a/agents/gsd-planner.md +++ b/agents/gsd-planner.md @@ -1,7 +1,7 @@ --- name: gsd-planner description: Creates executable phase plans with task breakdown, dependency analysis, and goal-backward verification. Spawned by /gsd:plan-phase orchestrator. -tools: Read, Write, Edit, Bash, Glob, Grep, Skill, WebFetch, mcp__context7__* +tools: Read, Write, Edit, Bash, Glob, Grep, Skill, WebFetch, mcp__context7__*, mcp__plugin_context7_context7__* color: green # hooks: # PostToolUse: diff --git a/agents/gsd-project-researcher.md b/agents/gsd-project-researcher.md index adfa391b5..c3123e915 100644 --- a/agents/gsd-project-researcher.md +++ b/agents/gsd-project-researcher.md @@ -1,7 +1,7 @@ --- name: gsd-project-researcher description: Researches domain ecosystem before roadmap creation. Produces files in .planning/research/ consumed during roadmap creation. Spawned by /gsd:new-project or /gsd:new-milestone orchestrators. -tools: Read, Write, Bash, Grep, Glob, Skill, WebSearch, WebFetch, mcp__context7__*, mcp__firecrawl__*, mcp__exa__*, mcp__tavily__*, mcp__ref__*, mcp__jina__*, mcp__perplexity__* +tools: Read, Write, Bash, Grep, Glob, Skill, WebSearch, WebFetch, mcp__context7__*, mcp__plugin_context7_context7__*, mcp__firecrawl__*, mcp__exa__*, mcp__tavily__*, mcp__ref__*, mcp__jina__*, mcp__perplexity__* color: cyan # hooks: # PostToolUse: diff --git a/agents/gsd-ui-researcher.md b/agents/gsd-ui-researcher.md index c75a54982..f48b1fb0c 100644 --- a/agents/gsd-ui-researcher.md +++ b/agents/gsd-ui-researcher.md @@ -1,7 +1,7 @@ --- name: gsd-ui-researcher description: Produces UI-SPEC.md design contract for frontend phases. Reads upstream artifacts, detects design system state, asks only unanswered questions. Spawned by /gsd:ui-phase orchestrator. -tools: Read, Write, Edit, Bash, Grep, Glob, Skill, WebSearch, WebFetch, mcp__context7__*, mcp__firecrawl__*, mcp__exa__*, mcp__tavily__*, mcp__ref__*, mcp__jina__* +tools: Read, Write, Edit, Bash, Grep, Glob, Skill, WebSearch, WebFetch, mcp__context7__*, mcp__plugin_context7_context7__*, mcp__firecrawl__*, mcp__exa__*, mcp__tavily__*, mcp__ref__*, mcp__jina__* color: purple # hooks: # PostToolUse: diff --git a/scripts/research-profiles.cjs b/scripts/research-profiles.cjs index 4d1c2ba72..ab879bab8 100644 --- a/scripts/research-profiles.cjs +++ b/scripts/research-profiles.cjs @@ -24,7 +24,7 @@ const PROFILES = [ 'Researches domain ecosystem before roadmap creation. Produces files in .planning/research/ consumed during roadmap creation. Spawned by /gsd:new-project or /gsd:new-milestone orchestrators.', color: 'cyan', tools: - 'Read, Write, Bash, Grep, Glob, Skill, WebSearch, WebFetch, mcp__context7__*, mcp__firecrawl__*, mcp__exa__*, mcp__tavily__*, mcp__ref__*, mcp__jina__*, mcp__perplexity__*', + 'Read, Write, Bash, Grep, Glob, Skill, WebSearch, WebFetch, mcp__context7__*, mcp__plugin_context7_context7__*, mcp__firecrawl__*, mcp__exa__*, mcp__tavily__*, mcp__ref__*, mcp__jina__*, mcp__perplexity__*', requiredIncludes: [ '@~/.claude/gsd-core/references/research-documentation-lookup.md', '@~/.claude/gsd-core/references/research-philosophy.md', @@ -46,7 +46,7 @@ const PROFILES = [ 'Researches how to implement a phase before planning. Produces RESEARCH.md consumed by gsd-planner. Spawned by /gsd:plan-phase orchestrator.', color: 'cyan', tools: - 'Read, Write, Edit, Bash, Grep, Glob, Skill, WebSearch, WebFetch, mcp__context7__*, mcp__firecrawl__*, mcp__exa__*, mcp__tavily__*, mcp__ref__*, mcp__jina__*, mcp__perplexity__*', + 'Read, Write, Edit, Bash, Grep, Glob, Skill, WebSearch, WebFetch, mcp__context7__*, mcp__plugin_context7_context7__*, mcp__firecrawl__*, mcp__exa__*, mcp__tavily__*, mcp__ref__*, mcp__jina__*, mcp__perplexity__*', requiredIncludes: [ '@~/.claude/gsd-core/references/research-documentation-lookup.md', '@~/.claude/gsd-core/references/research-philosophy.md', @@ -68,7 +68,7 @@ const PROFILES = [ description: 'Researches a single gray area decision and returns a structured comparison table with rationale. Spawned by discuss-phase advisor mode.', color: 'cyan', - tools: 'Read, Bash, Grep, Glob, Skill, WebSearch, WebFetch, mcp__context7__*', + tools: 'Read, Bash, Grep, Glob, Skill, WebSearch, WebFetch, mcp__context7__*, mcp__plugin_context7_context7__*', requiredIncludes: [ '@~/.claude/gsd-core/references/research-documentation-lookup.md', ], @@ -84,7 +84,7 @@ const PROFILES = [ 'Researches a chosen AI framework\'s official docs to produce implementation-ready guidance — best practices, syntax, core patterns, and pitfalls distilled for the specific use case. Writes the Framework Quick Reference and Implementation Guidance sections of AI-SPEC.md. Spawned by /gsd:ai-integration-phase orchestrator.', color: 'green', tools: - 'Read, Write, Edit, Bash, Grep, Glob, WebFetch, WebSearch, mcp__context7__*', + 'Read, Write, Edit, Bash, Grep, Glob, WebFetch, WebSearch, mcp__context7__*, mcp__plugin_context7_context7__*', requiredIncludes: [ '@~/.claude/gsd-core/references/research-documentation-lookup.md', ], @@ -101,7 +101,7 @@ const PROFILES = [ 'Researches the business domain and real-world application context of the AI system being built. Surfaces domain expert evaluation criteria, industry-specific failure modes, regulatory context, and what "good" looks like for practitioners in this field — before the eval-planner turns it into measurable rubrics. Spawned by /gsd:ai-integration-phase orchestrator.', color: 'purple', tools: - 'Read, Write, Edit, Bash, Grep, Glob, WebSearch, WebFetch, mcp__context7__*', + 'Read, Write, Edit, Bash, Grep, Glob, WebSearch, WebFetch, mcp__context7__*, mcp__plugin_context7_context7__*', requiredIncludes: [ '@~/.claude/gsd-core/references/research-documentation-lookup.md', ], @@ -117,7 +117,7 @@ const PROFILES = [ 'Produces UI-SPEC.md design contract for frontend phases. Reads upstream artifacts, detects design system state, asks only unanswered questions. Spawned by /gsd:ui-phase orchestrator.', color: 'purple', tools: - 'Read, Write, Edit, Bash, Grep, Glob, Skill, WebSearch, WebFetch, mcp__context7__*, mcp__firecrawl__*, mcp__exa__*, mcp__tavily__*, mcp__ref__*, mcp__jina__*', + 'Read, Write, Edit, Bash, Grep, Glob, Skill, WebSearch, WebFetch, mcp__context7__*, mcp__plugin_context7_context7__*, mcp__firecrawl__*, mcp__exa__*, mcp__tavily__*, mcp__ref__*, mcp__jina__*', requiredIncludes: [ '@~/.claude/gsd-core/references/research-documentation-lookup.md', ], diff --git a/tests/agent-size-baseline.json b/tests/agent-size-baseline.json index 09622cc3b..81abeeb01 100644 --- a/tests/agent-size-baseline.json +++ b/tests/agent-size-baseline.json @@ -1,6 +1,6 @@ { - "gsd-advisor-researcher.md": 4693, - "gsd-ai-researcher.md": 5909, + "gsd-advisor-researcher.md": 4727, + "gsd-ai-researcher.md": 5943, "gsd-assumptions-analyzer.md": 4646, "gsd-code-fixer.md": 36640, "gsd-code-reviewer.md": 16870, @@ -11,26 +11,26 @@ "gsd-doc-synthesizer.md": 9782, "gsd-doc-verifier.md": 12403, "gsd-doc-writer.md": 38924, - "gsd-domain-researcher.md": 6998, + "gsd-domain-researcher.md": 7032, "gsd-eval-auditor.md": 12496, "gsd-eval-planner.md": 7008, - "gsd-executor.md": 43539, + "gsd-executor.md": 43607, "gsd-framework-selector.md": 6778, "gsd-integration-checker.md": 15238, "gsd-intel-updater.md": 18166, "gsd-mempalace-curator.md": 4325, "gsd-nyquist-auditor.md": 7345, "gsd-pattern-mapper.md": 12487, - "gsd-phase-researcher.md": 40832, + "gsd-phase-researcher.md": 40866, "gsd-plan-checker.md": 44780, - "gsd-planner.md": 48157, - "gsd-project-researcher.md": 22208, + "gsd-planner.md": 48191, + "gsd-project-researcher.md": 22242, "gsd-research-synthesizer.md": 13847, "gsd-roadmapper.md": 22273, "gsd-security-auditor.md": 8981, "gsd-ui-auditor.md": 17249, "gsd-ui-checker.md": 11178, - "gsd-ui-researcher.md": 19466, + "gsd-ui-researcher.md": 19500, "gsd-user-profiler.md": 8516, "gsd-verifier.md": 49147 } diff --git a/tests/context7-plugin-grant-parity.test.cjs b/tests/context7-plugin-grant-parity.test.cjs new file mode 100644 index 000000000..fe3d7d577 --- /dev/null +++ b/tests/context7-plugin-grant-parity.test.cjs @@ -0,0 +1,35 @@ +'use strict'; + +// Regression guard for #2017 — agent `mcp__context7__*` grants only match a +// standalone context7 MCP server; the Claude Code plugin-marketplace install +// (`context7@claude-plugins-official`) names tools `mcp__plugin_context7_context7__*`, +// so every agent that uses context7 must grant BOTH forms or silently lose +// documentation lookup (falls back to WebSearch with no error). + +const { describe, test } = require('node:test'); +const assert = require('node:assert/strict'); +const fs = require('fs'); +const path = require('path'); + +const AGENTS_DIR = path.join(__dirname, '..', 'agents'); + +function agentFiles() { + return fs.readdirSync(AGENTS_DIR).filter((f) => f.endsWith('.md')).map((f) => path.join(AGENTS_DIR, f)); +} + +describe('#2017 — context7 plugin-marketplace grant parity', () => { + const STANDALONE = 'mcp__context7__*'; + const PLUGIN = 'mcp__plugin_context7_context7__*'; + + for (const file of agentFiles()) { + const name = path.basename(file); + const content = fs.readFileSync(file, 'utf8'); + const toolsLine = (content.split(/\r?\n/).find((l) => /^tools:/.test(l)) || ''); + + test(`${name}: standalone context7 grant implies the plugin-marketplace grant`, () => { + if (!toolsLine.includes(STANDALONE)) return; // agent doesn't use context7 — skip + assert.ok(toolsLine.includes(PLUGIN), + `${name} grants ${STANDALONE} but not ${PLUGIN} (plugin-marketplace installs silently lose doc lookup — #2017)`); + }); + } +}); diff --git a/tests/fixtures/golden-install-parity/antigravity.json b/tests/fixtures/golden-install-parity/antigravity.json index 02b686cf5..0789647ed 100644 --- a/tests/fixtures/golden-install-parity/antigravity.json +++ b/tests/fixtures/golden-install-parity/antigravity.json @@ -16,7 +16,7 @@ "agents/gsd-domain-researcher.md": "1db46cac3f4d9889", "agents/gsd-eval-auditor.md": "1b8391f1aafb067f", "agents/gsd-eval-planner.md": "3d10fd11147f6857", - "agents/gsd-executor.md": "e5b95acff5989d80", + "agents/gsd-executor.md": "152ca51a10b99ff8", "agents/gsd-framework-selector.md": "daa62c79619c76bf", "agents/gsd-integration-checker.md": "0643cd2d779b131c", "agents/gsd-intel-updater.md": "26c1f1e028c6346a", diff --git a/tests/fixtures/golden-install-parity/augment.json b/tests/fixtures/golden-install-parity/augment.json index 7b479cd81..709d168ea 100644 --- a/tests/fixtures/golden-install-parity/augment.json +++ b/tests/fixtures/golden-install-parity/augment.json @@ -16,7 +16,7 @@ "agents/gsd-domain-researcher.md": "671c9ea949889c4a", "agents/gsd-eval-auditor.md": "fcaec7b00f94c435", "agents/gsd-eval-planner.md": "a4a5b4b3f7828ba3", - "agents/gsd-executor.md": "060c6de9f618c2ea", + "agents/gsd-executor.md": "46f911cd211034b0", "agents/gsd-framework-selector.md": "4b77eebbe9288d80", "agents/gsd-integration-checker.md": "fa53e2d78be1de74", "agents/gsd-intel-updater.md": "fa40e685d7441ace", diff --git a/tests/fixtures/golden-install-parity/claude.json b/tests/fixtures/golden-install-parity/claude.json index 1879d2098..fe2c991b9 100644 --- a/tests/fixtures/golden-install-parity/claude.json +++ b/tests/fixtures/golden-install-parity/claude.json @@ -1,7 +1,7 @@ { ".gsd-profile": "0e716a5fef4e6dc1", - "agents/gsd-advisor-researcher.md": "7cdfe98e2baf606e", - "agents/gsd-ai-researcher.md": "fa68db1fb2c6ee8a", + "agents/gsd-advisor-researcher.md": "6f1f17e206e2c0c4", + "agents/gsd-ai-researcher.md": "e2236ee7b717c925", "agents/gsd-assumptions-analyzer.md": "f94fdd67f70b4a5d", "agents/gsd-code-fixer.md": "3d5f67cfd24ac452", "agents/gsd-code-reviewer.md": "d626a828e8de3648", @@ -12,26 +12,26 @@ "agents/gsd-doc-synthesizer.md": "135bbdfb9053cbd8", "agents/gsd-doc-verifier.md": "4232dcf9076e3566", "agents/gsd-doc-writer.md": "8cb62907c6458111", - "agents/gsd-domain-researcher.md": "f8be56555689a970", + "agents/gsd-domain-researcher.md": "5f7d366251b957fe", "agents/gsd-eval-auditor.md": "fea2759beff0a642", "agents/gsd-eval-planner.md": "112f6730f23854e3", - "agents/gsd-executor.md": "1a0fccbf7a1051cd", + "agents/gsd-executor.md": "22fc2f17098a4d14", "agents/gsd-framework-selector.md": "c350ee693cb1aa4e", "agents/gsd-integration-checker.md": "c8b4e65dee89c8ea", "agents/gsd-intel-updater.md": "5b41e05f90ce89d9", "agents/gsd-mempalace-curator.md": "77b53f1b155242b4", "agents/gsd-nyquist-auditor.md": "0bc0cdad7b3a0013", "agents/gsd-pattern-mapper.md": "b45b5e106775bec1", - "agents/gsd-phase-researcher.md": "529a4573230b104e", + "agents/gsd-phase-researcher.md": "85217c69c1ed2ac6", "agents/gsd-plan-checker.md": "c70134c61b969589", - "agents/gsd-planner.md": "d42aa2d1bc51edb4", - "agents/gsd-project-researcher.md": "e572c285002ba02e", + "agents/gsd-planner.md": "aa68af11f852ecfd", + "agents/gsd-project-researcher.md": "f468e96f8339d1e0", "agents/gsd-research-synthesizer.md": "7be02e47f4fd901b", "agents/gsd-roadmapper.md": "8a7f1f1256a6aed5", "agents/gsd-security-auditor.md": "4f9fc3f654af4944", "agents/gsd-ui-auditor.md": "40c0dcc15bcfb9fb", "agents/gsd-ui-checker.md": "6e94b43fd459e10e", - "agents/gsd-ui-researcher.md": "48bc161ca5a858b9", + "agents/gsd-ui-researcher.md": "5e561130434efdb2", "agents/gsd-user-profiler.md": "003276f85792cfda", "agents/gsd-verifier.md": "2271174b5aa20e31", "gsd-core/VERSION": "ef0deccd81a6723c", diff --git a/tests/fixtures/golden-install-parity/cline.json b/tests/fixtures/golden-install-parity/cline.json index 8ed577fb5..29676a00f 100644 --- a/tests/fixtures/golden-install-parity/cline.json +++ b/tests/fixtures/golden-install-parity/cline.json @@ -19,7 +19,7 @@ "agents/gsd-domain-researcher.md": "0fecdaea86466a56", "agents/gsd-eval-auditor.md": "36c44303085df2f8", "agents/gsd-eval-planner.md": "3ddea88a69b4da3f", - "agents/gsd-executor.md": "b662b48bbacda431", + "agents/gsd-executor.md": "441e624e9685e505", "agents/gsd-framework-selector.md": "564669d479433f15", "agents/gsd-integration-checker.md": "1bbbdd3d420b994e", "agents/gsd-intel-updater.md": "42c40fffbc720d0b", diff --git a/tests/fixtures/golden-install-parity/codebuddy.json b/tests/fixtures/golden-install-parity/codebuddy.json index 6516e362d..bcfa031ea 100644 --- a/tests/fixtures/golden-install-parity/codebuddy.json +++ b/tests/fixtures/golden-install-parity/codebuddy.json @@ -16,7 +16,7 @@ "agents/gsd-domain-researcher.md": "1c1a800108a2b225", "agents/gsd-eval-auditor.md": "99012004b14ea602", "agents/gsd-eval-planner.md": "4ebdd7fe9cbb0cfe", - "agents/gsd-executor.md": "28872f650cb8b46d", + "agents/gsd-executor.md": "d0bfc88c01a63181", "agents/gsd-framework-selector.md": "7726fccc86bfeb50", "agents/gsd-integration-checker.md": "2d8339790bbb2dc3", "agents/gsd-intel-updater.md": "c51339956197cbd3", diff --git a/tests/fixtures/golden-install-parity/codex.json b/tests/fixtures/golden-install-parity/codex.json index f0b003b85..b9c054582 100644 --- a/tests/fixtures/golden-install-parity/codex.json +++ b/tests/fixtures/golden-install-parity/codex.json @@ -1,9 +1,9 @@ { ".gsd-profile": "0e716a5fef4e6dc1", ".gsd/defaults.json": "560664b045e645cb", - "agents/gsd-advisor-researcher.md": "3995e081531dd043", + "agents/gsd-advisor-researcher.md": "eea6d1604aaf305c", "agents/gsd-advisor-researcher.toml": "144f037c79aa9c26", - "agents/gsd-ai-researcher.md": "9deaf29ae170faff", + "agents/gsd-ai-researcher.md": "303be751c91da4c8", "agents/gsd-ai-researcher.toml": "5a16e952628fdeb0", "agents/gsd-assumptions-analyzer.md": "21ee3cd4095f7cf8", "agents/gsd-assumptions-analyzer.toml": "9460360826f33ab1", @@ -25,14 +25,14 @@ "agents/gsd-doc-verifier.toml": "c0b7ac150730b954", "agents/gsd-doc-writer.md": "0a3557268f169722", "agents/gsd-doc-writer.toml": "d21d67f9ba074156", - "agents/gsd-domain-researcher.md": "bafef7d698ccb928", + "agents/gsd-domain-researcher.md": "fbd2f916f265c106", "agents/gsd-domain-researcher.toml": "a49ddec9005b4bf5", "agents/gsd-eval-auditor.md": "2810917e02e5547c", "agents/gsd-eval-auditor.toml": "9b81d61b3c5f722d", "agents/gsd-eval-planner.md": "73f2ad2ff2797a51", "agents/gsd-eval-planner.toml": "09468ad1a34ac468", - "agents/gsd-executor.md": "3c4556be34749bde", - "agents/gsd-executor.toml": "4730b30e5bb48e7e", + "agents/gsd-executor.md": "93a05c1436bc4458", + "agents/gsd-executor.toml": "f5a55d4eacd8613c", "agents/gsd-framework-selector.md": "ebae32430887d2e0", "agents/gsd-framework-selector.toml": "637e4e021b7ec380", "agents/gsd-integration-checker.md": "9cc875676cf7d741", @@ -45,13 +45,13 @@ "agents/gsd-nyquist-auditor.toml": "b3d7214b42fb67fa", "agents/gsd-pattern-mapper.md": "efbcfa7c5de4027f", "agents/gsd-pattern-mapper.toml": "48a17baa3d7d142c", - "agents/gsd-phase-researcher.md": "a8876e9ca2e40d2f", + "agents/gsd-phase-researcher.md": "87d74324e7708ea0", "agents/gsd-phase-researcher.toml": "44a3d510cd0ce3bd", "agents/gsd-plan-checker.md": "e7f02c10ea788aee", "agents/gsd-plan-checker.toml": "6f8ceb421d0ad721", - "agents/gsd-planner.md": "0e92e8d74894a56b", + "agents/gsd-planner.md": "5d638a2e37b63731", "agents/gsd-planner.toml": "50cec2af6b45a61c", - "agents/gsd-project-researcher.md": "787697faf68ad1a5", + "agents/gsd-project-researcher.md": "959f2e57c3d69ed8", "agents/gsd-project-researcher.toml": "f395e8e8c4baf1ed", "agents/gsd-research-synthesizer.md": "497f85adf53259ef", "agents/gsd-research-synthesizer.toml": "053616d4941a1458", @@ -63,7 +63,7 @@ "agents/gsd-ui-auditor.toml": "5e9dd62a12a16a1e", "agents/gsd-ui-checker.md": "bf7bf8cc301c65a1", "agents/gsd-ui-checker.toml": "d0a084e82a9ae52d", - "agents/gsd-ui-researcher.md": "cab148fcbfff7e4d", + "agents/gsd-ui-researcher.md": "2befca69af55e44a", "agents/gsd-ui-researcher.toml": "b55270666066e501", "agents/gsd-user-profiler.md": "1bf5033c929181c1", "agents/gsd-user-profiler.toml": "b9c244bb8fbf8140", diff --git a/tests/fixtures/golden-install-parity/copilot.json b/tests/fixtures/golden-install-parity/copilot.json index dbcca6f03..1587338a1 100644 --- a/tests/fixtures/golden-install-parity/copilot.json +++ b/tests/fixtures/golden-install-parity/copilot.json @@ -1,8 +1,8 @@ { ".gsd-profile": "0e716a5fef4e6dc1", ".gsd/defaults.json": "560664b045e645cb", - "agents/gsd-advisor-researcher.agent.md": "ecd72019cd5634c4", - "agents/gsd-ai-researcher.agent.md": "65c846c74f17a74b", + "agents/gsd-advisor-researcher.agent.md": "1fb10242ff7fb1c9", + "agents/gsd-ai-researcher.agent.md": "8e9c3a2ddd179bb1", "agents/gsd-assumptions-analyzer.agent.md": "cdabed4777a842fe", "agents/gsd-code-fixer.agent.md": "8f39aacb760aab57", "agents/gsd-code-reviewer.agent.md": "fa1e7c421c78eae1", @@ -13,26 +13,26 @@ "agents/gsd-doc-synthesizer.agent.md": "16cebf04d8998356", "agents/gsd-doc-verifier.agent.md": "0230208ae7ab1a08", "agents/gsd-doc-writer.agent.md": "37ea4932a4b80355", - "agents/gsd-domain-researcher.agent.md": "b06738b093df1cb9", + "agents/gsd-domain-researcher.agent.md": "d603239b3e9fe428", "agents/gsd-eval-auditor.agent.md": "3c03009564de55c8", "agents/gsd-eval-planner.agent.md": "14751876fc2b5f16", - "agents/gsd-executor.agent.md": "ff6d1fc07a0ff6e7", + "agents/gsd-executor.agent.md": "0058082fef5a4985", "agents/gsd-framework-selector.agent.md": "cafeec0b3489be45", "agents/gsd-integration-checker.agent.md": "30439b804927acc7", "agents/gsd-intel-updater.agent.md": "238c1a886f35a25c", "agents/gsd-mempalace-curator.agent.md": "9e5290ea4c4ac211", "agents/gsd-nyquist-auditor.agent.md": "6463a50d90ada125", "agents/gsd-pattern-mapper.agent.md": "b1f488b0fa6a2395", - "agents/gsd-phase-researcher.agent.md": "fc6062a07152951b", + "agents/gsd-phase-researcher.agent.md": "03cfb510a766fe93", "agents/gsd-plan-checker.agent.md": "c50a5b008ddcbfad", - "agents/gsd-planner.agent.md": "5a1d56ee3dae82a9", - "agents/gsd-project-researcher.agent.md": "39007b6fcb854032", + "agents/gsd-planner.agent.md": "d40d16eced1c6463", + "agents/gsd-project-researcher.agent.md": "d73bdbe986ffa8a6", "agents/gsd-research-synthesizer.agent.md": "f03eed4aa89e47c5", "agents/gsd-roadmapper.agent.md": "322048cf8ddcb4e5", "agents/gsd-security-auditor.agent.md": "6f6a88b35dc2a24b", "agents/gsd-ui-auditor.agent.md": "92f50549e84ef482", "agents/gsd-ui-checker.agent.md": "c9958f2587b24156", - "agents/gsd-ui-researcher.agent.md": "a9c6a2f0e9975df6", + "agents/gsd-ui-researcher.agent.md": "d24301cc182be33e", "agents/gsd-user-profiler.agent.md": "ae16a248e18dd42b", "agents/gsd-verifier.agent.md": "87a8e3238e838a39", "copilot-instructions.md": "1fb04111759f1645", diff --git a/tests/fixtures/golden-install-parity/cursor.json b/tests/fixtures/golden-install-parity/cursor.json index f1774e92b..8703f0963 100644 --- a/tests/fixtures/golden-install-parity/cursor.json +++ b/tests/fixtures/golden-install-parity/cursor.json @@ -16,7 +16,7 @@ "agents/gsd-domain-researcher.md": "56395dbdabf076f6", "agents/gsd-eval-auditor.md": "ad2840fd5cd76172", "agents/gsd-eval-planner.md": "2049dac060d00eda", - "agents/gsd-executor.md": "7e39d497c77b7c5a", + "agents/gsd-executor.md": "1fb2c778178cfa1c", "agents/gsd-framework-selector.md": "4b77eebbe9288d80", "agents/gsd-integration-checker.md": "5da30584d06b878c", "agents/gsd-intel-updater.md": "b8971c5d96e63b38", diff --git a/tests/fixtures/golden-install-parity/hermes.json b/tests/fixtures/golden-install-parity/hermes.json index a97c2d2be..44bbdba23 100644 --- a/tests/fixtures/golden-install-parity/hermes.json +++ b/tests/fixtures/golden-install-parity/hermes.json @@ -1,8 +1,8 @@ { ".gsd-profile": "0e716a5fef4e6dc1", ".gsd/defaults.json": "560664b045e645cb", - "agents/gsd-advisor-researcher.md": "f3f0a55854689045", - "agents/gsd-ai-researcher.md": "72f67082f35c9da1", + "agents/gsd-advisor-researcher.md": "f1c4a47d3d8cea72", + "agents/gsd-ai-researcher.md": "08847faf5494ff08", "agents/gsd-assumptions-analyzer.md": "f11a80795163bb5d", "agents/gsd-code-fixer.md": "94628312f25decb5", "agents/gsd-code-reviewer.md": "5ef947ca5baed775", @@ -13,26 +13,26 @@ "agents/gsd-doc-synthesizer.md": "8e6fb8220f777022", "agents/gsd-doc-verifier.md": "d3d8457bdd44bf10", "agents/gsd-doc-writer.md": "2858a8335170e85c", - "agents/gsd-domain-researcher.md": "d4c07520f650ffd5", + "agents/gsd-domain-researcher.md": "412cdbb05ba252ea", "agents/gsd-eval-auditor.md": "4ffb265063c318e5", "agents/gsd-eval-planner.md": "03448fc9c5774b56", - "agents/gsd-executor.md": "0667b16c383d033c", + "agents/gsd-executor.md": "18365948be7c2dff", "agents/gsd-framework-selector.md": "ea9981d65d6b3429", "agents/gsd-integration-checker.md": "35b4f2969d279871", "agents/gsd-intel-updater.md": "5fe5edfae2719cb8", "agents/gsd-mempalace-curator.md": "399e90e473b33814", "agents/gsd-nyquist-auditor.md": "8bfde4a9a36318aa", "agents/gsd-pattern-mapper.md": "cea092600aeb3978", - "agents/gsd-phase-researcher.md": "1c73b638d891363e", + "agents/gsd-phase-researcher.md": "2bd0402f33d757ca", "agents/gsd-plan-checker.md": "4b4e2b475bf5b5c3", - "agents/gsd-planner.md": "08e85102869630b4", - "agents/gsd-project-researcher.md": "97711cda03fdc9c0", + "agents/gsd-planner.md": "018542e335a983fa", + "agents/gsd-project-researcher.md": "425a7df7f37a5c06", "agents/gsd-research-synthesizer.md": "9d31c87fc2c87ffa", "agents/gsd-roadmapper.md": "64dce5d5f9fa5654", "agents/gsd-security-auditor.md": "e4d35ada4ea67d7f", "agents/gsd-ui-auditor.md": "86797e85f718dfac", "agents/gsd-ui-checker.md": "c56fa63fb94ded5f", - "agents/gsd-ui-researcher.md": "daa5ef704ff55753", + "agents/gsd-ui-researcher.md": "25ffa7fa83c32a69", "agents/gsd-user-profiler.md": "ca3bf75581f211a0", "agents/gsd-verifier.md": "82d3e9015ed04017", "gsd-core/VERSION": "ef0deccd81a6723c", diff --git a/tests/fixtures/golden-install-parity/kilo.json b/tests/fixtures/golden-install-parity/kilo.json index 9394242a9..302dc5bb1 100644 --- a/tests/fixtures/golden-install-parity/kilo.json +++ b/tests/fixtures/golden-install-parity/kilo.json @@ -16,7 +16,7 @@ "agents/gsd-domain-researcher.md": "a3874d80bcbc7380", "agents/gsd-eval-auditor.md": "630d4cd3bd6ea195", "agents/gsd-eval-planner.md": "3db12cde12aeb2c1", - "agents/gsd-executor.md": "41575d10fe41e36a", + "agents/gsd-executor.md": "c9aca9129bd4cab3", "agents/gsd-framework-selector.md": "ad5f2c6b9bec6270", "agents/gsd-integration-checker.md": "c503e2f4a3d8ec05", "agents/gsd-intel-updater.md": "231393da62a45b2e", diff --git a/tests/fixtures/golden-install-parity/kimi.json b/tests/fixtures/golden-install-parity/kimi.json index 99b174f6a..b289f7ae0 100644 --- a/tests/fixtures/golden-install-parity/kimi.json +++ b/tests/fixtures/golden-install-parity/kimi.json @@ -33,7 +33,7 @@ "agents/subagents/gsd-eval-auditor.yaml": "e3d868bd5fefe938", "agents/subagents/gsd-eval-planner.md": "70f8c5727bfb9876", "agents/subagents/gsd-eval-planner.yaml": "df8499f7af297ec2", - "agents/subagents/gsd-executor.md": "5ad0e1b4c9cd5c7e", + "agents/subagents/gsd-executor.md": "278a569a7306244c", "agents/subagents/gsd-executor.yaml": "e29422986636fd64", "agents/subagents/gsd-framework-selector.md": "a15b7aa1e0576e16", "agents/subagents/gsd-framework-selector.yaml": "fb52c31cde27b0e3", diff --git a/tests/fixtures/golden-install-parity/opencode.json b/tests/fixtures/golden-install-parity/opencode.json index edf5af8c4..de87b3b82 100644 --- a/tests/fixtures/golden-install-parity/opencode.json +++ b/tests/fixtures/golden-install-parity/opencode.json @@ -16,7 +16,7 @@ "agents/gsd-domain-researcher.md": "71250e759ca9e723", "agents/gsd-eval-auditor.md": "c88890105f32ace6", "agents/gsd-eval-planner.md": "60bddb70a937f796", - "agents/gsd-executor.md": "70fddc081560944d", + "agents/gsd-executor.md": "b091b0126895ae03", "agents/gsd-framework-selector.md": "1c0a10355e787675", "agents/gsd-integration-checker.md": "a9de5928e5a5c649", "agents/gsd-intel-updater.md": "493e07482fa6198a", diff --git a/tests/fixtures/golden-install-parity/qwen.json b/tests/fixtures/golden-install-parity/qwen.json index c2f3eb0b6..f81102328 100644 --- a/tests/fixtures/golden-install-parity/qwen.json +++ b/tests/fixtures/golden-install-parity/qwen.json @@ -1,8 +1,8 @@ { ".gsd-profile": "0e716a5fef4e6dc1", ".gsd/defaults.json": "560664b045e645cb", - "agents/gsd-advisor-researcher.md": "f3f0a55854689045", - "agents/gsd-ai-researcher.md": "72f67082f35c9da1", + "agents/gsd-advisor-researcher.md": "f1c4a47d3d8cea72", + "agents/gsd-ai-researcher.md": "08847faf5494ff08", "agents/gsd-assumptions-analyzer.md": "f11a80795163bb5d", "agents/gsd-code-fixer.md": "5660b5d7a912dbac", "agents/gsd-code-reviewer.md": "f70ee630a166fec8", @@ -13,26 +13,26 @@ "agents/gsd-doc-synthesizer.md": "8e6fb8220f777022", "agents/gsd-doc-verifier.md": "3767850df78f4a36", "agents/gsd-doc-writer.md": "10962b6bd4212379", - "agents/gsd-domain-researcher.md": "d4c07520f650ffd5", + "agents/gsd-domain-researcher.md": "412cdbb05ba252ea", "agents/gsd-eval-auditor.md": "2d121dbec93fd4ce", "agents/gsd-eval-planner.md": "03448fc9c5774b56", - "agents/gsd-executor.md": "7c8fe1370531a609", + "agents/gsd-executor.md": "0735dcf053be7c76", "agents/gsd-framework-selector.md": "ea9981d65d6b3429", "agents/gsd-integration-checker.md": "33fd537b862eb944", "agents/gsd-intel-updater.md": "699dacdc0a1f2478", "agents/gsd-mempalace-curator.md": "399e90e473b33814", "agents/gsd-nyquist-auditor.md": "7fb0ecf639c1cdfe", "agents/gsd-pattern-mapper.md": "9ab071c3ffc1cf46", - "agents/gsd-phase-researcher.md": "b064bc7bb4881443", + "agents/gsd-phase-researcher.md": "ecb365e5f62aaafc", "agents/gsd-plan-checker.md": "ca47fdf6d4a36849", - "agents/gsd-planner.md": "358edac30c2edf06", - "agents/gsd-project-researcher.md": "b0f23dcd0f383907", + "agents/gsd-planner.md": "7cb18e515bab3c05", + "agents/gsd-project-researcher.md": "d38509cab69224d9", "agents/gsd-research-synthesizer.md": "6d64fce8b06b7a62", "agents/gsd-roadmapper.md": "604b25c6687811f4", "agents/gsd-security-auditor.md": "f85447e5b5300feb", "agents/gsd-ui-auditor.md": "cc46d104cbc49079", "agents/gsd-ui-checker.md": "8f140c80fc193e13", - "agents/gsd-ui-researcher.md": "c2e93ad96d0a93e1", + "agents/gsd-ui-researcher.md": "623cb59aa6dbe146", "agents/gsd-user-profiler.md": "ca3bf75581f211a0", "agents/gsd-verifier.md": "45c450b6d7cc5f0d", "gsd-core/VERSION": "ef0deccd81a6723c", diff --git a/tests/fixtures/golden-install-parity/trae.json b/tests/fixtures/golden-install-parity/trae.json index 2debe0ec7..89e5f358f 100644 --- a/tests/fixtures/golden-install-parity/trae.json +++ b/tests/fixtures/golden-install-parity/trae.json @@ -16,7 +16,7 @@ "agents/gsd-domain-researcher.md": "b80f76874c04e515", "agents/gsd-eval-auditor.md": "470bf16303ec4d2e", "agents/gsd-eval-planner.md": "22334fde85723c9d", - "agents/gsd-executor.md": "a918ba64279d1a8c", + "agents/gsd-executor.md": "45eeb443a6e6dbe8", "agents/gsd-framework-selector.md": "7726fccc86bfeb50", "agents/gsd-integration-checker.md": "7cd2072984411c7f", "agents/gsd-intel-updater.md": "83de6ba9172891c3", diff --git a/tests/fixtures/golden-install-parity/windsurf.json b/tests/fixtures/golden-install-parity/windsurf.json index af04dbed3..32a327a0a 100644 --- a/tests/fixtures/golden-install-parity/windsurf.json +++ b/tests/fixtures/golden-install-parity/windsurf.json @@ -16,7 +16,7 @@ "agents/gsd-domain-researcher.md": "56395dbdabf076f6", "agents/gsd-eval-auditor.md": "fb64fc5acf359747", "agents/gsd-eval-planner.md": "2049dac060d00eda", - "agents/gsd-executor.md": "56ad34feb3cf5f12", + "agents/gsd-executor.md": "406fdcc0597bea77", "agents/gsd-framework-selector.md": "4b77eebbe9288d80", "agents/gsd-integration-checker.md": "4ffb37fb230c2b90", "agents/gsd-intel-updater.md": "a81d77c143c02108", From 460956bfed079413bce8f791d5610dfb7e5fd8b1 Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Sun, 5 Jul 2026 17:28:34 -0400 Subject: [PATCH 06/39] fix(#2018): applySurface empty manifest no longer deletes gsd-* agents (#2031) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(#2018): applySurface empty manifest no longer deletes gsd-* agents The agent-prune loop in _syncGsdDir deleted any gsd-*.md not in the staged set. When the manifest resolved empty (null/non-object, no entries, no files key, or unresolvable install source root), the staged set was empty → every gsd-* agent was deleted. Skills were guarded by pruneSkillDirs' manifest- membership check; agents had no equivalent. - src/surface.cts: skip the agent-prune loop when the manifest is empty/absent (copy still runs — genuinely new agents are added). - tests/surface-empty-manifest-agents.test.cjs: boundary matrix — empty manifest preserves agents (Map() + undefined); non-empty manifest + empty staged still prunes (boundary); empty manifest + new staged copies new + preserves existing. Closes #2018 * docs(#2018): backfill changeset pr 2031 --- ...2018-applysurface-empty-manifest-agents.md | 5 ++ src/surface.cts | 19 ++++-- tests/surface-empty-manifest-agents.test.cjs | 67 +++++++++++++++++++ 3 files changed, 86 insertions(+), 5 deletions(-) create mode 100644 .changeset/2018-applysurface-empty-manifest-agents.md create mode 100644 tests/surface-empty-manifest-agents.test.cjs diff --git a/.changeset/2018-applysurface-empty-manifest-agents.md b/.changeset/2018-applysurface-empty-manifest-agents.md new file mode 100644 index 000000000..68ddf4024 --- /dev/null +++ b/.changeset/2018-applysurface-empty-manifest-agents.md @@ -0,0 +1,5 @@ +--- +type: Fixed +pr: 2031 +--- +**`applySurface` no longer deletes every `gsd-*` agent when the skills manifest resolves empty** — the agent-prune loop in `_syncGsdDir` deleted any `gsd-*.md` not in the staged set, and when the manifest was empty/unresolvable (null manifest, no array entries, no `files` key, or an unresolvable install source root), the staged set was empty → every agent was pruned. Skills were guarded by `pruneSkillDirs`'s manifest-membership check (conservative preservation on empty manifest); agents had no equivalent. The agent-prune loop is now skipped when the manifest is empty/absent, so agents are preserved while copy (adding genuinely new agents) still runs. (#2018) diff --git a/src/surface.cts b/src/surface.cts index 120944c6f..caa4bcc34 100644 --- a/src/surface.cts +++ b/src/surface.cts @@ -509,11 +509,20 @@ function _syncGsdDir(stagedDir: string, destDir: string, kind: ArtifactKind | st // - agents: only gsd-* are GSD-owned // - flat command dirs: only `${kindPrefix}`-prefixed are GSD-owned // - namespaced command dirs: the whole dir is GSD-owned - for (const file of fs.readdirSync(destDir).filter(f => f.endsWith('.md'))) { - if (kindName === 'agents' && !file.startsWith('gsd-')) continue; - if (kindName === 'commands' && !namespacedByDir && kindPrefix && !file.startsWith(kindPrefix)) continue; - if (!stagedDestNames.has(file)) { - try { fs.unlinkSync(path.join(destDir, file)); } catch { /* ignore */ } + // + // Manifest gate (#2018): when the manifest is empty/absent (e.g. an unresolvable + // install source root yields an empty staged dir), the staged set is untrustworthy. + // Skills are guarded by pruneSkillDirs' manifest-membership check; agents must be + // guarded here — skip the prune loop entirely so an empty manifest never deletes + // every gsd-* agent. Copying (above) still runs so genuinely new agents are added. + const shouldPruneAgents = !(kindName === 'agents' && (!manifest || manifest.size === 0)); + if (shouldPruneAgents) { + for (const file of fs.readdirSync(destDir).filter(f => f.endsWith('.md'))) { + if (kindName === 'agents' && !file.startsWith('gsd-')) continue; + if (kindName === 'commands' && !namespacedByDir && kindPrefix && !file.startsWith(kindPrefix)) continue; + if (!stagedDestNames.has(file)) { + try { fs.unlinkSync(path.join(destDir, file)); } catch { /* ignore */ } + } } } } diff --git a/tests/surface-empty-manifest-agents.test.cjs b/tests/surface-empty-manifest-agents.test.cjs new file mode 100644 index 000000000..ba884511b --- /dev/null +++ b/tests/surface-empty-manifest-agents.test.cjs @@ -0,0 +1,67 @@ +'use strict'; + +// Regression guard for #2018 — applySurface over an empty/unresolvable manifest +// silently deleted every gsd-* agent because the agent-prune loop in _syncGsdDir +// didn't check manifest membership (unlike pruneSkillDirs which conservatively +// preserves everything when the manifest is empty). The fix skips the agent-prune +// loop when the manifest is empty/absent so agents are never bulk-deleted. + +const { describe, test, beforeEach, afterEach } = require('node:test'); +const assert = require('node:assert/strict'); +const fs = require('fs'); +const os = require('os'); +const path = require('path'); + +const { _syncGsdDir } = require('../gsd-core/bin/lib/surface.cjs'); + +function tmp() { return fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-surface-empty-')); } + +describe('#2018 — empty manifest must not delete gsd-* agents', () => { + let dest, staged; + beforeEach(() => { + dest = tmp(); staged = tmp(); + // Simulate existing agents in dest (what a real install has) + for (const name of ['gsd-executor.md', 'gsd-planner.md', 'gsd-verifier.md']) { + fs.writeFileSync(path.join(dest, name), `# ${name}\n`); + } + // Staged dir is EMPTY (unresolvable manifest → nothing staged) + }); + afterEach(() => { try { fs.rmSync(dest, { recursive: true, force: true }); } catch {} try { fs.rmSync(staged, { recursive: true, force: true }); } catch {} }); + + test('empty manifest → agents preserved (not deleted)', () => { + _syncGsdDir(staged, dest, 'agents', new Map()); + const remaining = fs.readdirSync(dest).filter((f) => f.startsWith('gsd-')); + assert.deepEqual(remaining.sort(), ['gsd-executor.md', 'gsd-planner.md', 'gsd-verifier.md'], + 'all gsd-* agents must survive an empty manifest'); + }); + + test('undefined manifest → agents preserved', () => { + _syncGsdDir(staged, dest, 'agents', undefined); + const remaining = fs.readdirSync(dest).filter((f) => f.startsWith('gsd-')); + assert.ok(remaining.length === 3, 'all agents preserved with undefined manifest'); + }); + + test('non-empty manifest + empty staged → agents still preserved (staged set empty but manifest exists)', () => { + // A populated manifest (even with a different set) is trusted; but staged is empty. + // The manifest gate only fires on EMPTY manifest. With a non-empty manifest but + // empty staged, the prune loop SHOULD run (agents not in staged get pruned). + // This test documents the boundary: non-empty manifest → prune happens. + const manifest = new Map([['gsd-old-agent', []]]); + _syncGsdDir(staged, dest, 'agents', manifest); + const remaining = fs.readdirSync(dest).filter((f) => f.startsWith('gsd-')); + // With a non-empty manifest, staged is empty → all agents pruned (this is the + // existing behavior for a genuine "all agents were un-surfaced" scenario, NOT + // the empty-manifest bug). + assert.deepEqual(remaining, [], 'non-empty manifest + empty staged → agents pruned (expected behavior)'); + }); + + test('empty manifest but new agents staged → new agents added, existing preserved', () => { + // Stage a new agent + fs.writeFileSync(path.join(staged, 'gsd-new-agent.md'), '# New\n'); + _syncGsdDir(staged, dest, 'agents', new Map()); + const remaining = fs.readdirSync(dest).filter((f) => f.startsWith('gsd-')); + assert.ok(remaining.includes('gsd-new-agent.md'), 'new staged agent must be copied'); + assert.ok(remaining.includes('gsd-executor.md'), 'existing agent must be preserved'); + assert.ok(remaining.length === 4, '3 existing + 1 new = 4 agents'); + }); +}); From f77179248d6c80b9fe82e1c035a73ad55444b929 Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Sun, 5 Jul 2026 17:39:11 -0400 Subject: [PATCH 07/39] fix(#2012): scope phase.complete Progress-row regex to ## Progress section (#2032) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(#2012): scope Progress-row regex to ## Progress section (was binding to earlier table) The Progress-row writer used a non-global regex that matched ANY table row starting with the phase number. When an earlier table (e.g. Requirements coverage | Phase | Requirements | Count |) preceded ## Progress, the regex bound to the wrong row (3-column), no-op'd, and never reached the real Progress row. roadmap_updated stayed true (it's existsSync), masking the failure. - src/phase.cts: scope the tableRowPattern regex to the ## Progress section (indexOf + slice) so it only matches Progress-table rows. - tests/phase.test.cjs: regression test — ROADMAP with a phase-numbered Requirements table before ## Progress → Progress row updated, Requirements row untouched. Closes #2012 * docs(#2012): backfill changeset pr 2032 --- .../2012-phase-complete-progress-row.md | 5 ++ src/phase.cts | 15 +++++- tests/phase.test.cjs | 47 +++++++++++++++++++ 3 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 .changeset/2012-phase-complete-progress-row.md diff --git a/.changeset/2012-phase-complete-progress-row.md b/.changeset/2012-phase-complete-progress-row.md new file mode 100644 index 000000000..3bc84044c --- /dev/null +++ b/.changeset/2012-phase-complete-progress-row.md @@ -0,0 +1,5 @@ +--- +type: Fixed +pr: 2032 +--- +**`phase.complete` now updates the `## Progress` rollup row even when an earlier phase-numbered table precedes it** — the Progress-row writer used a non-global regex that matched *any* table row starting with the phase number, so it bound to the first such row (e.g. a `| Phase | Requirements | Count |` coverage table), no-op'd on the wrong 3-column row, and never reached the real Progress row. The regex is now scoped to the `## Progress` section so it binds to the correct table. The command still returned `roadmap_updated: true` (that field is `fs.existsSync(ROADMAP.md)`), masking the silent failure. (#2012) diff --git a/src/phase.cts b/src/phase.cts index 6dca595d1..f2ca162e4 100644 --- a/src/phase.cts +++ b/src/phase.cts @@ -1460,7 +1460,10 @@ function cmdPhaseComplete(cwd: string, phaseNum: string, raw: boolean): void { `^(\\|\\s*${phaseEscaped}\\.?\\s[^|]*(?:\\|[^\\n]*))$`, 'im', ); - roadmapContent = roadmapContent.replace(tableRowPattern, (fullRow) => { + // Scope the Progress-row search to the ## Progress section so the regex + // doesn't bind to an earlier table (e.g. | Phase | Requirements | Count |) + // whose rows also start with the phase number. (#2012) + const updateProgressRow = (fullRow: string): string => { const cells = fullRow.split('|').slice(1, -1); const dateShape = /^\d{4}-\d{2}-\d{2}$/; if (cells.length === 5) { @@ -1477,7 +1480,15 @@ function cmdPhaseComplete(cwd: string, phaseNum: string, raw: boolean): void { cells[3] = dateShape.test(existingDate4) ? cells[3] : ` ${today} `; } return '|' + cells.join('|') + '|'; - }); + }; + const progressIdx = roadmapContent.indexOf('## Progress'); + if (progressIdx >= 0) { + const beforeProgress = roadmapContent.slice(0, progressIdx); + const progressSection = roadmapContent.slice(progressIdx); + roadmapContent = beforeProgress + progressSection.replace(tableRowPattern, updateProgressRow); + } else { + roadmapContent = roadmapContent.replace(tableRowPattern, updateProgressRow); + } const planCountPattern = new RegExp( `(#{2,4}\\s*Phase\\s+${phaseEscaped}[\\s\\S]*?\\*\\*Plans:\\*\\*\\s*)[^\\n]+`, diff --git a/tests/phase.test.cjs b/tests/phase.test.cjs index 1dad00845..6681c40cd 100644 --- a/tests/phase.test.cjs +++ b/tests/phase.test.cjs @@ -2530,6 +2530,53 @@ describe('phase complete command', () => { assert.ok(roadmap.includes('completed'), 'completion date should be added'); }); + test('#2012 — Progress row updated even when an earlier phase-numbered table precedes ## Progress', () => { + fs.writeFileSync( + path.join(tmpDir, '.planning', 'ROADMAP.md'), + `# Roadmap + +- [ ] Phase 3: Build + +### Phase 3: Build +**Goal:** Build stuff + +## Requirements Coverage + +| Phase | Requirements | Count | +|-------|-------------|-------| +| 3. Build | R-01 | 5 | + +## Progress + +| Phase | Milestone | Plans Complete | Status | Completed | +|-------|-----------|----------------|--------|-----------| +| 3. Build | v1.0 | 0/1 | Planned | - | +` + ); + fs.writeFileSync( + path.join(tmpDir, '.planning', 'STATE.md'), + `# State\n\n**Current Phase:** 03\n**Status:** In progress\n**Last Activity:** 2025-01-01\n` + ); + + const p3 = path.join(tmpDir, '.planning', 'phases', '03-build'); + fs.mkdirSync(p3, { recursive: true }); + fs.writeFileSync(path.join(p3, '03-01-PLAN.md'), '# Plan'); + fs.writeFileSync(path.join(p3, '03-01-SUMMARY.md'), '# Summary'); + + const result = runVerifiedPhaseComplete('phase complete 3', tmpDir); + assert.ok(result.success, `Command failed: ${result.error}`); + + const roadmap = fs.readFileSync(path.join(tmpDir, '.planning', 'ROADMAP.md'), 'utf-8'); + + // The Requirements coverage table row must be UNCHANGED (3 columns, not a Progress row). + const reqRow = roadmap.match(/^\| 3\. Build \| R-01 \| 5 \|$/m); + assert.ok(reqRow, 'Requirements coverage row must be untouched'); + + // The Progress row must be updated to Complete with a date. + const progressRow = roadmap.match(/^\| 3\. Build \| v1\.0 \| 1\/1 \| Complete\s+\| \d{4}-\d{2}-\d{2} \|/m); + assert.ok(progressRow, 'Progress row must be updated to Complete with a date'); + }); + test('detects last phase in milestone', () => { fs.writeFileSync( path.join(tmpDir, '.planning', 'ROADMAP.md'), From 6c725438cca1ac9376aec57d594726a0e7fc71e2 Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Sun, 5 Jul 2026 18:01:28 -0400 Subject: [PATCH 08/39] fix(#2018): use helpers.cleanup() not raw fs.rmSync in surface test; drop unused imports (#2033) The #2018 regression test used raw fs.rmSync() in afterEach, tripping the local/no-raw-rmsync-in-tests eslint rule (Windows-EBUSY retry budget). CI's lint-tests job (no eslint cache) caught it on next; local --cache runs had false-greened it. Switch to helpers.cleanup(). Also drop two unused destructured imports (evaluateCommandExitZero, interpolate) in the gate-predicate-evaluator test that emitted no-unused-vars warnings. Co-authored-by: Claude Opus 4.8 --- tests/gate-predicate-evaluator.test.cjs | 2 -- tests/surface-empty-manifest-agents.test.cjs | 3 ++- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/gate-predicate-evaluator.test.cjs b/tests/gate-predicate-evaluator.test.cjs index d3e2579a1..7d5c9fb39 100644 --- a/tests/gate-predicate-evaluator.test.cjs +++ b/tests/gate-predicate-evaluator.test.cjs @@ -22,8 +22,6 @@ const fc = require('fast-check'); const { evaluatePredicate, - evaluateCommandExitZero, - interpolate, COMMAND_EXIT_ZERO_DEFAULT_TIMEOUT_MS, COMMAND_MAX_OUTPUT_CHARS, COMMAND_MAX_LENGTH, diff --git a/tests/surface-empty-manifest-agents.test.cjs b/tests/surface-empty-manifest-agents.test.cjs index ba884511b..9d5aa36cc 100644 --- a/tests/surface-empty-manifest-agents.test.cjs +++ b/tests/surface-empty-manifest-agents.test.cjs @@ -13,6 +13,7 @@ const os = require('os'); const path = require('path'); const { _syncGsdDir } = require('../gsd-core/bin/lib/surface.cjs'); +const { cleanup } = require('./helpers.cjs'); function tmp() { return fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-surface-empty-')); } @@ -26,7 +27,7 @@ describe('#2018 — empty manifest must not delete gsd-* agents', () => { } // Staged dir is EMPTY (unresolvable manifest → nothing staged) }); - afterEach(() => { try { fs.rmSync(dest, { recursive: true, force: true }); } catch {} try { fs.rmSync(staged, { recursive: true, force: true }); } catch {} }); + afterEach(() => { cleanup(dest); cleanup(staged); }); test('empty manifest → agents preserved (not deleted)', () => { _syncGsdDir(staged, dest, 'agents', new Map()); From 76556f715cc952b4bb792d3f9bdcf369dc32826a Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Sun, 5 Jul 2026 18:32:57 -0400 Subject: [PATCH 09/39] chore(#2034): remove stale QUICK-WINS-CONFIRMED-BUGS.md from repo root (#2035) Leaked working-notes/triage file (Started 2026-05-16, Grok+user /gsd-inbox session) accidentally committed to the root in 05316369a. References resolved issues; not referenced by any code, test, doc, manifest, or golden fixture. Closes #2034 Co-authored-by: Claude Opus 4.8 --- QUICK-WINS-CONFIRMED-BUGS.md | 73 ------------------------------------ 1 file changed, 73 deletions(-) delete mode 100644 QUICK-WINS-CONFIRMED-BUGS.md diff --git a/QUICK-WINS-CONFIRMED-BUGS.md b/QUICK-WINS-CONFIRMED-BUGS.md deleted file mode 100644 index ac041691e..000000000 --- a/QUICK-WINS-CONFIRMED-BUGS.md +++ /dev/null @@ -1,73 +0,0 @@ -# Quick Wins: Confirmed-Bug Fixes - -**Status**: Active -**Started**: 2026-05-16 -**Owner**: Current session (Grok + user) -**Context**: Follow-up to `/gsd-inbox` triage on 2026-05-16 - -## Goal - -Land 6 high-signal, confirmed-bug issues that currently have **zero open pull requests**. These are the cleanest quick-win opportunities available in the public GitHub inbox right now. - -All six issues carry the `confirmed-bug` label, meaning the bug has been verified and a fix is explicitly welcome. - -## The 6 Issues (Prioritized) - -| # | Issue | Short Title | Type | Recommended Flow | Est. Effort | Status | Notes | -|---|-------|-------------|------|------------------|-------------|--------|-------| -| 1 | [#3583](https://github.com/open-gsd/gsd-core/issues/3583) | Claude skill install leaves `/gsd:` in `SKILL.md` body | Installer / Command namespace | PR 3629 (our branch) + competing 3586 | Small (1 file + test) | PR opened / Review | **Leading PR: 3629** (cristianuibar) — reviewed + hardened with CodeRabbit feedback (left-boundary regex + body-scoped guard). Competing PR 3586 has "needs changes" + "ci: failing". Issue still carries `confirmed-bug`. | -| 2 | [#3579](https://github.com/open-gsd/gsd-core/issues/3579) | `build-hooks.js` + npm publish omit graphify auto-update hook | Packaging / Build | `/gsd-quick` | Small | Not started | Classic "new feature missed in release artifact". Easy local verification. | -| 3 | [#3496](https://github.com/open-gsd/gsd-core/issues/3496) | `/gsd:update` changelog extraction skips intermediate versions | Workflow / Update logic | `/gsd-quick` or lightweight plan | Medium-small | Not started | Needs deterministic version-range helper. | -| 4 | [#3588](https://github.com/open-gsd/gsd-core/issues/3588) | Production `npm audit` has 1 high + 5 moderate advisories | Security / Dependencies | Direct + careful review | Medium | Not started | Transitive via `@anthropic-ai/claude-agent-sdk`. May need overrides. | -| 5 | [#3584](https://github.com/open-gsd/gsd-core/issues/3584) | Runtime `bin/lib/*.cjs` still emit `/gsd:` (larger piece deferred from #3583) | Runtime output / Slash formatter | Short plan first, then execute | Medium-Large | Not started | 16+ files. Design a centralized runtime-aware formatter. Do after #3583. | -| 6 | [#3340](https://github.com/open-gsd/gsd-core/issues/3340) | SDK publish lag — agent dir fix never shipped in `@opengsd/gsd-sdk@0.1.0` | Release / SDK publishing | Plan + coordination | Medium (release-focused) | Not started | Oldest. Mostly a publishing/versioning task. | - -## Execution Rules for This Batch - -- **Branch naming**: `fix/NNNN-short-description` (enforced by CI) -- **PR template**: Must use `.github/PULL_REQUEST_TEMPLATE/fix.md` -- **Linking**: `Fixes #NNNN` (or `Closes`) in the PR body -- **Changeset**: Required for all user-facing or security fixes -- **Testing**: All existing tests must pass + new coverage where the issue describes a gap -- **Clean context windows**: Each fix should preferably be driven from a fresh session using the prepared prompts (see session notes or ask for them) -- **GSD self-use**: For the small ones (#3583, #3579, #3496), using `/gsd-quick` (or `/gsd-fast`) inside the fix session is encouraged and appropriate. For #3584, a short planning step is recommended. - -## Status Legend - -- **Not started** — Issue claimed for this batch, no work begun -- **In progress** — Active work in a clean window -- **PR opened** — Pull request created and linked -- **Review** — Awaiting review / CI / merge fixes -- **Merged** — Landed on main -- **Blocked** — Needs input from maintainers or upstream - -## Current Status - -- [x] #3583 — **PR opened** (3629 leading after CodeRabbit review + hardening push; competing 3586 needs changes + CI failing) -- [ ] #3579 — Not started (cleanest next target — 0 PRs) -- [ ] #3496 — PR 3497 open (changes requested) -- [ ] #3588 — Not started -- [ ] #3584 — Not started (larger; deferred runtime cjs colon emissions) -- [ ] #3340 — Not started - -**Progress**: 0 / 6 merged (1 in active review) - -## Process Notes - -- These issues were identified during a `/gsd-inbox` run on 2026-05-16. -- At the time of creation of this file, zero of the six had open PRs. -- 2026-05-16 Grok session: Reviewed PR 3629 (our #3583 fix) for CodeRabbit comments. 1 critical was false-positive (scripts/ *is* published per package.json "files" + npm pack). Applied the 2 valid suggestions (bidirectional word-boundary lookbehind in `buildColonPattern` + body-only scope for the colon-ref regression guard in the test). Tests pass. Pushed hardening commit to the fork branch. Competing PR 3586 exists but is behind on CI/review status. -- Work is intended to be done in **parallel clean context windows** (one issue per fresh Claude/Codex/Gemini session) using dedicated prompts. -- After each fix is complete in its window, the resulting branch + PR description should be brought back here for final review and opening. -- This file serves as the single source of truth for the current batch while execution is in progress. It can be deleted or moved to `docs/archive/` once all six PRs are merged. - -## Related Artifacts - -- Inbox triage report: `/tmp/GSD-INBOX-TRIAGE-2026-05-16.md` (from the `/gsd-inbox` run) -- Full issue list with `confirmed-bug` label: `gh issue list --state open --label confirmed-bug` - ---- - -**Next action**: #3583 now has active PR(s) under review. Next clean quick win (0 PRs, small packaging effort, high value for recently-landed graphify feature): **#3579**. Validated via GitHub search: no PRs mention 3579. Ready for `/gsd-quick` or direct fix (update `scripts/build-hooks.js` HOOKS_TO_COPY + ensure `hooks/lib/` copy in installer + fix any publish filter). - -This document will be updated as status changes. \ No newline at end of file From 19fd9343f6838b58d4e2fa8a5d6d0b0c2f0323ec Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Sun, 5 Jul 2026 20:56:12 -0400 Subject: [PATCH 10/39] feat(#2002): self-healing runtime build for plugin-marketplace installs (#2036) The compiled gsd-core/bin/lib/*.cjs modules are gitignored build artifacts (ADR-457) shipped prebuilt in the npm tarball. A Claude Code plugin-marketplace / git-clone install materializes the repo tree directly and never runs `npm run build:lib`, so those ~148 files are absent and every CLI command dies at load with `Cannot find module './lib/cli-exit.cjs'`. gsd-tools.cjs now calls ensureRuntimeBuild() before its ./lib requires: a new committed bin helper that compiles the tree once on demand (lock-guarded, incremental-cache-cleared, portable `node ` invocation) when the sentinel cli-exit.cjs is missing, and surfaces an actionable error when TypeScript is unavailable. The already-built npm path is a single fs.existsSync no-op. ADR-457 (gitignored, build-at-publish) is preserved; no release-pipeline change. Verified against a simulated marketplace checkout (148 build outputs removed): the CLI self-heals and the result is byte-identical to `npm run build:lib`. Closes #2002 Co-authored-by: Claude Opus 4.8 --- .../2002-cli-self-healing-runtime-build.md | 6 + docs/how-to/install-on-your-runtime.md | 2 + gsd-core/bin/ensure-runtime-build.cjs | 246 +++++++++++++ gsd-core/bin/gsd-tools.cjs | 18 + tests/ensure-runtime-build.test.cjs | 340 ++++++++++++++++++ .../golden-install-parity/antigravity.json | 3 +- .../golden-install-parity/augment.json | 3 +- .../golden-install-parity/claude.json | 3 +- .../fixtures/golden-install-parity/cline.json | 3 +- .../golden-install-parity/codebuddy.json | 3 +- .../fixtures/golden-install-parity/codex.json | 3 +- .../golden-install-parity/copilot.json | 3 +- .../golden-install-parity/cursor.json | 3 +- .../golden-install-parity/hermes.json | 3 +- .../fixtures/golden-install-parity/kilo.json | 3 +- .../fixtures/golden-install-parity/kimi.json | 3 +- .../golden-install-parity/opencode.json | 3 +- .../fixtures/golden-install-parity/qwen.json | 3 +- .../fixtures/golden-install-parity/trae.json | 3 +- .../golden-install-parity/windsurf.json | 3 +- 20 files changed, 642 insertions(+), 15 deletions(-) create mode 100644 .changeset/2002-cli-self-healing-runtime-build.md create mode 100644 gsd-core/bin/ensure-runtime-build.cjs create mode 100644 tests/ensure-runtime-build.test.cjs diff --git a/.changeset/2002-cli-self-healing-runtime-build.md b/.changeset/2002-cli-self-healing-runtime-build.md new file mode 100644 index 000000000..3e2f35507 --- /dev/null +++ b/.changeset/2002-cli-self-healing-runtime-build.md @@ -0,0 +1,6 @@ +--- +type: Changed +pr: 2036 +--- + +**The GSD CLI now self-heals a missing runtime build.** The compiled `gsd-core/bin/lib/*.cjs` modules are gitignored build artifacts (ADR-457) that ship prebuilt in the npm tarball but are absent on a Claude Code plugin-marketplace / git-clone install, which never runs `npm run build:lib`. Previously every command died at load with `Cannot find module './lib/cli-exit.cjs'`. The `gsd-tools` entrypoint now detects the missing output and compiles it once, on demand (lock-guarded so parallel invocations don't race), then proceeds — a single no-op check on the already-built npm path. When TypeScript is genuinely unavailable it prints an actionable `npm install && npm run build:lib` message instead of crashing. diff --git a/docs/how-to/install-on-your-runtime.md b/docs/how-to/install-on-your-runtime.md index d24c1203f..051b94828 100644 --- a/docs/how-to/install-on-your-runtime.md +++ b/docs/how-to/install-on-your-runtime.md @@ -102,6 +102,8 @@ The `gsd-tools` binary (installed as part of the `@opengsd/gsd-core` npm package Node.js (`node`) must also be available on your `PATH`. The plugin's always-on guard hooks (wired in `hooks/hooks.json`) are invoked as `node "${CLAUDE_PLUGIN_ROOT}/hooks/