Commit Graph

4890 Commits

Author SHA1 Message Date
Tom Boucher
b65892e6a2 docs(#1508): add ADR for Runtime Artifact Conversion Module content-rewrite ownership
Phase 0 of epic #1507. Records the decision to make the Runtime Artifact
Conversion Module the single owner of per-runtime content rewriting, flip the
dependency direction to installer/layout -> conversion, and close the
surface.cts -> bin/install.js getInstallExports relay. Doc-only.

Resolves ADR-3660 Initial-Scope deferral; distinct from epic #1258.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0187qgypdy1wkWRpdaf2hRuD
2026-06-20 20:54:32 -04:00
Behruz Nassre Esfahani
3388d682ee chore(#1400): add changeset for the Windows agent-skills flush fix
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 16:49:18 -07:00
Behruz Nassre Esfahani
6bbd8919d5 fix(#1400): flush agent-skills block via writeAllSync instead of process.exit(0)
cmdAgentSkills' plain (non-JSON) path wrote the <agent_skills> block with
process.stdout.write then immediately called process.exit(0). stdout.write is
async on pipes/files, so on Windows the process tore down before Node flushed
the buffer — the workflows' `$(gsd_run query agent-skills <type>)` capture
received 0 bytes and every ${AGENT_SKILLS_*} substitution expanded empty,
silently dropping configured per-agent skills.

Route the plain path through the existing synchronous output() helper
(writeAllSync, src/io.cts) + return — the same flush-safe mechanism the --json
branch already uses — instead of write + process.exit(0).

Adds a #1400 regression block to tests/agent-skills.test.cjs that captures
stdout via a real file descriptor and asserts the block is non-empty and
byte-identical to the --json .block.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 16:49:18 -07:00
Tom Boucher
900462a59c Merge pull request #1505 from open-gsd/feat/1452-context-guard-mode
feat(#1452): add workflow.context_guard_mode — proactive context exhaustion guard for execute-phase
2026-06-20 18:53:24 -04:00
Tom Boucher
2dedbdd11c fix(#1455): resolve project-code-prefixed roadmap headings
* fix: remove hardcoded phase project-code prefix cap

Centralize project-code prefix stripping/matching and replace fixed {1,6} caps so long codes (for example MANIFOLD-117) resolve across phase, roadmap parser, roadmap upgrade, and validate flows.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: address review feedback on prefix parsing

- allow project_code prefixes with digits and underscores while preserving milestone parsing
- use shared optional project-code prefix source in phase dir parsing
- extend regression coverage for APP1/APP_1 prefixed phases

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* chore: resolve review nit in phase-id test comment

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: resolve project-code-prefixed roadmap headings

Make getRoadmapPhaseInternal recover from drifted project-code-prefixed ROADMAP headings while preserving canonical bare-heading preference. Add init.phase-op and parser regressions for #1455 and guard gsd-roadmapper against emitting project_code in headings.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* chore: add changeset for project-code phase fix

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* chore: update roadmapper agent size baseline

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix(#1455): tighten project-code prefix regex to [A-Z] start; add boundary test; document source order

Resolves blockers from review:
- Regex changed from [A-Z_][A-Z0-9_]* to [A-Z][A-Z0-9_]* so leading
  underscores (_FOO-7, _-7) are never misread as project-code prefixes;
  adds boundary test asserting both do NOT strip.
- Adds comment to roadmapPhaseLookupSources explaining why 3 sources are
  needed (order-dependent canonical-heading preference).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Solvely-Colin <211764741+Solvely-Colin@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 18:45:41 -04:00
Tom Boucher
b63a500fad fix(#1505): extract context_guard step to reference file; fix allow-test-rule see ref
- Extract execute-phase.md context_guard step prose to
  gsd-core/references/execute-phase-context-guard.md (@-ref lazy load),
  bringing execute-phase.md back under the ADR-857 phase-6 size ceiling
  (92914 < 93166 bytes)
- Fix allow-test-rule comment: add `see #1452` per ADR-456 lint rule
- Update feat-1452 tests to check the reference file for extracted content
- Register execute-phase-context-guard.md in INVENTORY-MANIFEST.json and
  INVENTORY.md Workflow References section
- Regenerate workflow-size-baseline.json after file shrinkage

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 18:38:20 -04:00
Tom Boucher
a77f3c4b3a docs(#1452): document workflow.context_guard_mode in CONFIGURATION.md
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 18:12:03 -04:00
Tom Boucher
4eca5ac96c feat(#1452): add workflow.context_guard_mode to guard execute-phase against context exhaustion
Proactive checkpoint guard fires at each wave boundary before spawning agents.
Self-assesses context pressure against context-budget.md degradation tiers and
warns (warn, default) or auto-invokes /gsd:pause-work (auto) when POOR tier
(70%+) is detected. Config key validated; defaults to \"warn\".

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 18:10:49 -04:00
Tom Boucher
a4c89daff0 Merge branch 'next' into fix/1394-gemini-skill-tool-exclusion 2026-06-20 17:49:11 -04:00
Tom Boucher
3091ce007e Merge pull request #1504 from open-gsd/fix/1493-verify-drift-action-flat-shape
fix(#1493): read workflow.drift_action/drift_threshold from nested config shape in verify.cts
2026-06-20 17:48:20 -04:00
Tom Boucher
6fe5aa5c8d chore(#1493): add changeset for verify codebase-drift nested config fix (#1504)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 16:39:32 -04:00
Tom Boucher
6425a3cb72 fix(#1493): read workflow.drift_action/drift_threshold from nested config shape in verify.cts
loadConfig() returns a flattened object with no nested `workflow` key, so
config?.workflow was always undefined, making drift_action permanently 'warn'
and drift_threshold permanently 3 regardless of .planning/config.json. Fixes
by reading the raw config.json directly (matching the pattern in
check-command-router.cts:readWorkflowConfig). Adds two behavioral regression
tests that fail under the old code and pass under the fix.

Closes #1493

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 16:37:54 -04:00
Tom Boucher
9d057882e9 Merge pull request #1503 from open-gsd/chore/sync-next-version-1.6.0-rc.1
chore: sync next package version to 1.6.0-rc.1
2026-06-20 15:58:46 -04:00
github-actions[bot]
4441b20b4a chore: sync next package version to 1.6.0-rc.1 2026-06-20 19:58:40 +00:00
Joe
5fa1c8e6f0 Merge branch 'next' into fix/1477-surface-source-marker 2026-06-20 14:52:39 -05:00
Tom Boucher
d588471389 fix(#1501): build:lib before npm version in release workflow so capability-ledger.cjs exists for registry hook (#1502)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 15:39:21 -04:00
Tom Boucher
c330f70f65 feat(#1494): add workflow.mvp_mode to VALID_CONFIG_KEYS; document code_review_command and plan_chunked in planning-config.md (#1500)
* feat(#1494): add workflow.mvp_mode to VALID_CONFIG_KEYS; document code_review_command, plan_chunked, mvp_mode in planning-config.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: backfill PR number 1500 in changeset

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 15:32:07 -04:00
Behruz Nassre Esfahani
531aa01bc2 chore(#1394): reword changeset to drop product-name parenthetical
product-name-purity (#1777) rejects 'Gemini (…)' parentheticals that render
verbatim into CHANGELOG.md. Reword to 'Gemini and Gemini-backed Antigravity';
no behavior change. (Reword was left uncommitted in the prior rebase push.)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 15:04:39 -04:00
Behruz Nassre Esfahani
a2511c132d test(#1394): exercise the live bin/install.js convertGeminiToolName, add ask_user assertion
Addresses review: the regression unit test required the tsc build artifact
(gsd-core/bin/lib/runtime-artifact-conversion.cjs) instead of the live install
path. Destructure convertGeminiToolName from the existing ../bin/install.js
import so a stale build can't false-green while the live copy is broken, and
assert the full AskUserQuestion/ask_user exclusion group.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 15:04:39 -04:00
Behruz Nassre Esfahani
ba5625bf79 chore(#1394): add changeset for the Gemini Skill-tool exclusion fix
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 15:04:39 -04:00
Behruz Nassre Esfahani
4512a83f49 fix(#1394): exclude Skill/SlashCommand from the Gemini agent tool converter
convertGeminiToolName lowercased any unmapped Claude tool, so Skill and
SlashCommand became an invalid `skill`/`slashcommand` tool name. Gemini CLI
has no such built-in tool, so frontmatter validation failed (tools.N: Invalid
tool name) and aborted the entire agent load — 22 of 34 GSD agents were dead
on Gemini.

Add Skill and SlashCommand to the same `return null` exclusion branch that
already handles AskUserQuestion, in both the canonical src converter and the
hand-maintained bin/install.js copy that runs on the live --gemini install
path. Antigravity reuses this converter (it runs on the Gemini backend) and is
intentionally covered by the same exclusion — it surfaces GSD skills via the
skill surface (SKILL.md), not the agent tools: allowlist — locked by an added
Antigravity regression test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 15:04:39 -04:00
Tom Boucher
d7da068dd7 fix(#1498): regenerate capability-registry.cjs in npm version lifecycle hook (#1499)
* fix(#1498): regenerate capability-registry.cjs in npm version lifecycle hook

The version npm lifecycle script now runs gen-capability-registry.cjs --write
after sync-manifest-versions.cjs stamps all capability/*.json version fields.
Without this, every npm version X.Y.Z call left capability-registry.cjs stale
(capability JSONs got the new version string, but the registry still embedded
the old ones), causing gen-capability-registry.cjs --check to fail in the RC
test suite.

- package.json version script: add gen-capability-registry --write + git add
- tests/issue-844-manifest-version-sync.test.cjs: regression guard (describe F)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: backfill changeset pr: 1499

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 15:03:19 -04:00
Joe Slitzker
9727e2ae94 fix(#1477): key getInstallExports cache per configDir; document marker contract
Address second maintainer review on #1487:
- Blocker 1: getInstallExports now caches per runtimeConfigDir (Map) so a
  no-arg warm-up via the legacy walk-up path cannot poison a later
  getInstallExports(configDir) call. Add a regression test (verified to fail
  on the singleton cache) proving the no-arg warm-up does not poison the
  configDir-keyed resolution.
- Blocker 3: document the .gsd-source two-party provisioning contract in the
  CONTEXT.md Runtime Artifact Layout Module entry (writer, reader, content,
  guard, fall-through, package-root invariant, per-configDir cache).

Claude-Session: https://claude.ai/code/session_01XNT3SWgzjmEycNuweURDme
2026-06-20 13:46:30 -05:00
Joe Slitzker
cd47d9d317 fix(#1477): scope .gsd-source marker write to claude global; add PR ref to changeset
Address review on #1487:
- Scope the marker write to runtime === 'claude' && isGlobal, matching
  issue #1477. The Claude global skills layout is the only install path
  that ships the skills layout without a commands/gsd source tree; every
  other runtime/scope deploys commands/gsd, so walk-up already resolves.
- Add the trailing (#1487) reference to the changeset body per PRED.k329.body.

Claude-Session: https://claude.ai/code/session_01XNT3SWgzjmEycNuweURDme
2026-06-20 13:40:29 -05:00
Tom Boucher
f5276b36b3 fix(#1369): refresh wave manifest and re-check base before each wave in execute-phase (#1492)
* fix(#1369): refresh wave manifest and re-check base before each wave in execute-phase

Two compounding issues caused wave N+1 worktrees to fork from the stale
pre-wave-N commit, immediately tripping the worktree_branch_check FATAL
guard in every executor:

1. worktree.base-check auto-degrade only ran once at initialize time.
   After wave N merges advanced orchestrator HEAD past origin/HEAD, new
   worktrees were still forked from origin/HEAD (Claude Code "fresh" base).

2. WAVE_WORKTREE_MANIFEST was never unset between waves, so wave N+1
   reused the consumed wave-N manifest file, which would have blocked the
   step 5.5 manifest guard (#3384) on subsequent waves.

Fix: add two safeguards in execute-phase.md —
- Step 0.5 (start of each wave): re-runs worktree.base-check; auto-degrades
  USE_WORKTREES=false for that wave when HEAD has diverged from origin/HEAD.
- Step 7c (end of each wave): unsets WAVE_WORKTREE_MANIFEST so wave N+1
  creates a fresh per-wave manifest; re-asserts worktree.set-baseref
  (idempotent) and re-evaluates base degradation after wave merges land.

17 regression tests added in tests/bug-1369-wave-stale-base.test.cjs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(#1369): rename test to fix-NNN convention; update workflow size baseline

Rename tests/bug-1369-wave-stale-base.test.cjs → tests/fix-1369-wave-stale-base.test.cjs
to satisfy the lint-regression-test-names gate (new files cannot use bug-NNN prefix).

Update tests/workflow-size-baseline.json for execute-phase.md: 93157 → 97393
(LF-normalized byte count after adding step 0.5 inter-wave base re-check and
step 7c between-wave manifest reset).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(#1369): add issue reference to allow-test-rule comment

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(#1369): extract new execute-phase steps to references; satisfy ADR-857 cap

Step 0.5 (inter-wave worktree base re-check) and steps 7b–7c (pre-wave
dependency check + between-wave manifest reset/base refresh) added by this
PR grew execute-phase.md to 97393 bytes, violating the ADR-857 phase-6
architectural mandate that host-loop bodies remain strictly below the
pre-phase-6 baseline of 93166 bytes.

Extract both new blocks into dedicated reference files:
- gsd-core/references/execute-phase-wave-guard.md (step 0.5)
- gsd-core/references/execute-phase-between-wave-reset.md (steps 7b + 7c)

Replace inline prose with @-reference pointers. File now measures 92851
bytes (LF-normalized), satisfying the ADR-857 capstone conformance gate.

Also update tests/workflow-size-baseline.json to 92851 and add both new
reference files to docs/INVENTORY-MANIFEST.json.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(#1369): update regression tests to read from extracted reference files

Steps 0.5 and 7b+7c were moved to reference files to satisfy the ADR-857
size cap on execute-phase.md. Tests now check @-reference pointers in the
workflow for ordering and read content assertions from the reference files.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 14:22:59 -04:00
Tom Boucher
fb24d1c7ea test(#1496): add behavioral validateCapability check for capability tutorial manifests (#1497)
* test(#1464): add behavioral manifest-validation test for capability tutorial docs

Extracts JSON capability manifests from tutorial/reference docs and validates
them through the real validateCapability — closing the test gap that let
issue #1464's broken tutorial manifest (step missing ref) pass undetected.

Adds fix-1464-docs-manifest-validation.test.cjs with:
- Suite 1: build/install/reference docs' complete manifests pass validateCapability
- Suite 2: adversarial fixtures prove the original #1464 bug shapes are caught
  (step without ref → "steps[0].ref must be an object…"; id/folderId mismatch)
- Suite 3: extractManifests helper unit tests (complete vs. partial block filtering)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test(#1496): allowlist docs module for 3-file test cluster

docs-parity-live-registry, docs-update, and the new
fix-1464-docs-manifest-validation sit on the same docs production
module; add the docs entry to lint-test-file-count.allowlist.json
so the novel-offender CI gate passes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 14:05:12 -04:00
Tom Boucher
e627584f87 fix(#1453): rewrite stale get-shit-done paths in Codex skill mirror on upgrade (#1491)
* fix(#1453): clean up stale get-shit-done paths in Codex skill mirror on upgrade

Extends planLegacyCleanup in gsd-core/bin/lib/legacy-cleanup.cjs to scan
skills/gsd-* subdirectories for .md files that still embed the pre-rename
get-shit-done/ path (e.g. ~/.agents/skills/gsd-docs-update/SKILL.md).
These stale copies are removed by cleanupLegacyGsdCc during the next
install/upgrade so Codex can no longer discover and select them.

Adds 5 regression tests to tests/issue-607-legacy-cleanup.test.cjs covering
the stale path detection, non-flagging of fresh skills and user-owned dirs,
and the end-to-end ~/.agents/skills scenario from the issue.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(#1453): add gsd-allow-legacy-name markers to intentional legacy name references

Comments and test descriptions in legacy-cleanup.cjs and its test file
legitimately cite the old 'get-shit-done' directory name to explain what
the cleanup logic removes. Add the lint-exemption marker to each line so
lint-legacy-dir-name passes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 13:37:38 -04:00
Tom Boucher
4719b36d41 fix(#1445,#1446): exclude 999.x backlog from milestone totals; allow total_phases downward correction (#1490)
* fix(#1445,#1446): exclude 999.x backlog phases from milestone totals; allow total_phases downward correction

#1445: deriveProgressFromRoadmap (phase-lifecycle.cts), the roadmapPhaseCount
loop (state.cts), and getMilestonePhaseFilter (roadmap-parser.cts) all now
skip phase tokens matching /^999\b/ — consistent with the existing init.cts
filter. 999.x backlog dirs are consequently excluded from phaseDirs too.

#1446: shouldPreserveExistingProgress (state-document.cts) no longer includes
total_phases in its ratchet check. total_phases always takes the freshly
derived value; only completed_phases, total_plans, and completed_plans retain
ratchet behaviour.

Regression tests added for both bugs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: add changeset for #1445/#1446 progress-backlog-exclusion-and-ratchet

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(#1445,#1446): rename test files to fix-NNN convention; fix changeset pr: null

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 13:37:32 -04:00
Tom Boucher
33ccf5f89d fix(#1367): project-local install uses flat gsd-<cmd>.md layout (fixes /gsd: colon namespace) (#1489)
* fix(#1367): project-local install uses flat gsd-<cmd>.md layout

Claude Code project-local installs now write command files as flat
gsd-<cmd>.md at .claude/commands/ level instead of commands/gsd/<cmd>.md
(subdirectory), so Claude Code registers /gsd-<cmd> (hyphen form)
matching hooks, statusline, and all cross-command references.

- capabilities/claude/capability.json: local destSubpath commands/gsd → commands
- bin/install.js else branch: flat gsd-<stem>.md loop with runtime rewrites
- bin/install.js uninstall (1c): remove flat files + legacy subdir cleanup
- bin/install.js writeManifest: record flat commands/gsd-<cmd>.md keys
- legacy migration: preserves dev-preferences.md across reinstall and uninstall
- gsd-core/bin/lib/capability-registry.cjs: regenerated
- 6 new regression tests (L0–L5) in bug-1367-*.test.cjs
- Updated E suite in bug-3683 + bug-1736, layout + surface + descriptor tests
- scripts/lint-regression-test-names.allowlist.json: grandfathered bug-1367 test

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(#1367): add issue reference to allow-test-rule comment

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 13:37:27 -04:00
Tom Boucher
fa1ffb4824 fix(#1437): add phase.list-plans to gsd-tools (#1485)
* fix(#1437): add phase.list-plans to gsd-tools

Register phase.list-plans in PHASE_COMMAND_ALIASES, implement
cmdPhaseListPlans in src/phase.cts (uses findPhaseInternal + scanPhasePlans
to return plan_count/has_plans/plans/phase_dir), and wire the handler in
phase-command-router. Previously every call produced "Unknown phase
subcommand".

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(#1437): register new test file in lint-test-file-count allowlist

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(#1437): rename test to fix-NNN convention; update file-count allowlist

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 13:37:22 -04:00
Tom Boucher
ba3181204b fix(#1422,#1447): fix sub_repos/.git precedence; guard uncommitted data in new-milestone (#1484)
* fix(#1422): sub_repos config takes precedence over .git in findProjectRoot

When heuristic-3 (.git + parent .planning/) fires, do a lookahead walk
over ancestors above the matching parent to check if any further ancestor
has a sub_repos entry that explicitly claims the starting directory. If
found, return that ancestor instead — explicit config wins over the
implicit .git signal.

Regression tests updated: the heuristic-3 precedence test now asserts the
correct new behavior (sub_repos wins), and two additional coverage cases
added (startDir directly in sub_repo child, and startDir nested 2+ levels
inside the child).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(#1447): guard against uncommitted changes before deleting phase dirs in new-milestone

cmdPhasesClear now runs `git status --porcelain <phasesDir>` before
executing any rmSync. If uncommitted changes are detected it calls
error() and aborts, preventing silent data loss when new-milestone's
§6 "phases.clear --confirm" fires before the operator has archived
or committed outgoing phase work.

A new --force flag is added to bypass the guard for callers that have
already verified archival is done (or explicitly accept the loss).
When git is unavailable or the directory is not inside a git repo the
guard silently skips, preserving the existing behaviour for non-git
projects.

Five new regression tests cover: untracked files abort, staged-but-
uncommitted abort, --force bypasses, committed files pass, non-git
project passes without guard.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: add changeset for #1422 and #1447

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: correct changeset format

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 13:37:16 -04:00
Tom Boucher
bb88a78faa fix(#1472,#1454): workstream-aware health paths; exclude active worktree from W017 (#1483)
* fix(#1472,#1454): validate health workstream-aware paths; exclude active worktree from W017

#1472: cmdValidateHealth now uses planningRoot(cwd) for shared-root files
(PROJECT.md, config.json, MILESTONES.md) and planningDir(cwd) for
workstream-scoped files (ROADMAP.md, STATE.md, phases/). Previously a
single planningDir() call was used for all paths, causing false
E002/E003/E004/W003 when GSD_WORKSTREAM is set.

#1454: W017 no longer fires for a stale worktree whose path equals or is
an ancestor of process.cwd(), preventing advice to remove the active
session's own worktree.

Regression tests added for both bugs; all 40 existing health tests pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: correct changeset format

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 13:37:09 -04:00
Tom Boucher
fe0f9f904d fix(#1478,#1479,#1480): prohibit ungrounded baselines, error-suppressing fallbacks, and stale-artifact authority in planner verify blocks (#1482)
* fix(#1478,#1479,#1480): prohibit ungrounded baselines, error-suppressing fallbacks, and stale-artifact authority in verify blocks

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: add changeset for #1478/#1479/#1480 planner verify gate fix

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: correct changeset format

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(#1478,#1479,#1480): fix test contract violations from new planner dimensions

gsd-planner.md exceeded both the planner-decomposition 48K char limit and
the reachability-check 50K char limit after the new HARD RULE blocks were
added inline. The full rule details already exist in planner-antipatterns.md
(added in the same PR); replace the verbose inline blocks with a single
@-reference pointer to the antipatterns file, reducing the file from 50981
to 49130 chars (under both limits).

Also regenerate tests/agent-size-baseline.json to reflect the new sizes of
gsd-planner.md and gsd-plan-checker.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 13:37:03 -04:00
Tom Boucher
3a3b2135c2 chore(#1073): purge phantom pre-migration issue refs from source, tests, docs (#1471)
#2551/#3182/#2361 are pre-migration get-shit-done-redux issue numbers with no
equivalent in open-gsd/gsd-core; they mislead triage and manufacture phantom
blockers. Repoint to real successors (#717 byte-budget rework, #720) or rewrite
as prose referencing the discuss-phase/modes progressive-disclosure split.
Correct co-located 'line budget'/'<500 lines' framing to the byte-based reality
(#717). Add a CI guard (tests/no-phantom-issue-refs.test.cjs) that fails if a
phantom ref is reintroduced. SSH-key patterns (id_ed25519) left untouched.
No user-facing runtime behavior change.

Closes #1073
2026-06-20 13:36:57 -04:00
Tom Boucher
f8f295ff60 Merge pull request #1495 from open-gsd/docs/1464-capability-docs
docs(#1464): fix + complete the ADR-1244 capability doc set (followable tutorials, overlay-model, reference gaps, accuracy)
2026-06-20 13:18:10 -04:00
Tom Boucher
02c6491e61 docs(#1464): fix ADR-1244 capability doc set — followable tutorials, overlay-model + install tutorial, set/fragment/runtimeCompat reference, accuracy fixes 2026-06-20 13:02:24 -04:00
Tom Boucher
1c1c31f677 Merge pull request #1488 from open-gsd/feat/1463-capability-outdated
feat(#1463): add capability outdated (per-source update check); drop phantom slash-command docs
2026-06-20 11:02:47 -04:00
Tom Boucher
7c93d9e222 feat(#1463): add capability outdated (per-source update check); drop phantom slash-command docs
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 10:50:12 -04:00
Joe Slitzker
a9c30841ce test(#1477): move regression cases into the owning module test file
The lint-regression-test-names gate rejects new bug-NNNN-*.test.cjs files: a
new regression case must live in its owning module's test file. Relocate the
#1477 cases into tests/runtime-artifact-layout.test.cjs (the home of the
findInstallSourceRoot / getInstallExports resolution seam at the heart of the
bug) as a dedicated describe block, and delete the standalone file.

Claude-Session: https://claude.ai/code/session_01XNT3SWgzjmEycNuweURDme
2026-06-20 09:38:18 -05:00
Joe Slitzker
e574ad6fdf chore(#1477): add changeset fragment for surface source-marker fix
Claude-Session: https://claude.ai/code/session_01XNT3SWgzjmEycNuweURDme
2026-06-20 09:28:18 -05:00
Joe Slitzker
ee6f3b70c5 fix(#1477): write .gsd-source marker at install; resolve install-exports for the deployed layout
The Claude Code global skills layout ships gsd-core/{bin,contexts,references,
templates,workflows} but not the commands/gsd source tree, and
_runLegacyUninstallCleanup removes any commands/gsd/ for that scope. So at
runtime findInstallSourceRoot's walk-up from gsd-core/bin/lib has nothing to
find and /gsd-surface throws for every subcommand (list/status included). The
marker reader added in #1476 never fired because nothing wrote the marker.

Writer half (Failure 1): install() writes <configDir>/.gsd-source pointing at
the package's commands/gsd source (guarded on its presence so a half-published
package never leaves a dangling marker). findInstallSourceRoot already prefers
this marker over the walk-up.

Deployed install-exports (Failure 2): loadInstallExports' relative
'../../../bin/install.js' only resolves in the repo; in a deployed tree it
points at <configDir>/bin/install.js, which is never shipped, so the surface
write subcommands threw MODULE_NOT_FOUND. Derive install.js from the resolved
commands/gsd source root instead (its package root holds both commands/gsd and
bin/install.js), which is correct in the repo (walk-up) and in deployed installs
(marker) alike. No file relocation needed, so install.js' own internal requires
keep resolving. applySurface threads layout.configDir so the marker is honored.

Regression test reproduces the deployed global layout end-to-end: without the
marker the deployed walk-up throws, and getInstallExports under the old relative
path throws MODULE_NOT_FOUND; with both fixes list/status resolve and the
install-exports load. Adversarial marker cases (dangling, empty/whitespace)
fall through to walk-up.

Claude-Session: https://claude.ai/code/session_01XNT3SWgzjmEycNuweURDme
2026-06-20 09:15:59 -05:00
Tom Boucher
67a3842776 Merge pull request #1481 from open-gsd/fix/1460-integrity-confinement
fix(#1460): verify-or-reject capability --integrity per source; confine hook commands to the bundle
2026-06-20 09:21:58 -04:00
Tom Boucher
08d1c57d6e fix(#1460): verify-or-reject capability --integrity per source; confine hook commands to the bundle
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 09:10:04 -04:00
Tom Boucher
38e9b83178 Merge pull request #1475 from open-gsd/fix/1461-overlay-crash-dos 2026-06-20 08:01:26 -04:00
Tom Boucher
f7c6ce7a1f fix(#1461): loader never crashes on a malformed overlay (skip-with-warning); bound the source fetch
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 03:24:47 -04:00
Tom Boucher
e7855bc217 fix(#1459): user-owned consent store gates third-party capability activation; env/cwd in disclosure; loader validator parity (#1473) 2026-06-20 01:59:03 -04:00
Tom Boucher
81d4b6d573 docs(#1010): document projects-sync as the first reference third-party capability (#1470)
Add a worked example to the URL-import how-to showing how to install and
enable the projects-sync ADR-1244 ecosystem capability (published at
The-Artificer-of-Ciphers-LLC/projects-sync-capability). The capability ships
as an external installable repo; GSD Core gains the worked example only.

Closes #1010
2026-06-19 21:03:26 -04:00
Tom Boucher
c866ac1b24 fix(#1462): fail closed without data loss on a corrupt capability ledger; atomic ledger write (#1469) 2026-06-19 19:55:10 -04:00
Tom Boucher
7195c2a90b chore: add @davesienkowski to CODEOWNERS reviewer pool (#1466)
Adds davesienkowski (write/maintain collaborator) to the all-paths
reviewer pool so they are auto-requested on PRs.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 16:37:33 -04:00
Tom Boucher
0d56f544d2 feat(#1435): capability matrix (generated + drift-guarded) + trust-model doc consolidation (#1458)
* feat(#1435): capability matrix (generated + drift-guarded) + trust-model doc consolidation

ADR-1244 Phase 6. Adds the capability matrix reference, generated FROM the committed registry so it
can never drift from the actual capability set:
- scripts/gen-capability-matrix.cjs (--write / --check); --check is a CI drift guard.
- tests/capability-matrix-sync.test.cjs (4 tests): drift guard, buildMatrix==committed, every cap
  present, no placeholders.
- docs/reference/capability-matrix.md regenerated from the registry (release-stable: shows engines.gsd,
  omits the lockstep per-cap version that would churn the file every release).
- Consolidated the duplicate trust-model doc: deleted docs/explanation/the-capability-trust-model.md,
  merged its content into capability-trust-model.md, redirected ~10 references; no stale links remain.
- Diataxis verification (now that gsd capability is a real command): corrected the matrix's third-party
  section — the matrix is the first-party catalogue; the overlay-aware view of installed third-party
  capabilities is 'gsd capability list', not this generated file.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* docs(#1435): Added changeset for the capability matrix reference

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(#1435): address code-review — non-vacuous matrix test + generator polish

- capability-matrix-sync.test.cjs: assert the 'security registers a ship:pre gate' precondition
  unconditionally so the extension-point check can never degrade to a vacuous pass on registry drift.
- gen-capability-matrix.cjs: warn (stderr) on an unknown loop point at generation time; rename
  enginesOf -> fmtEngines for consistency with the other fmt* helpers (output unchanged).
- capability-trust-model.md: point the two how-to links at the real files
  (import-a-capability-from-a-url.md, version-a-capability.md) instead of the bare directory.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* chore(#1435): backfill changeset PR number → #1458

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 12:45:26 -04:00