Commit Graph

3208 Commits

Author SHA1 Message Date
Jeremy McSpadden
22a3400c64 Merge pull request #547 from open-gsd/codex/changelog-1.2.0
docs(#546): update changelog for 1.2.0
2026-05-31 10:59:28 -05:00
Jeremy McSpadden
c18edb4225 docs(#546): update changelog for 1.2.0 2026-05-31 10:56:48 -05:00
Jeremy McSpadden
e8ba6d276a Merge pull request #543 from open-gsd/codex/readme-version-alignment
[codex] docs: align README version source of truth
2026-05-31 10:33:32 -05:00
Jeremy McSpadden
c6724ea947 docs(#542): align README version source of truth 2026-05-31 10:31:26 -05:00
Jeremy McSpadden
0c2afb4d19 Merge pull request #529 from open-gsd/codex/tagline-punctuation-next
[codex] Correct GSD Core tagline punctuation
2026-05-31 08:00:50 -05:00
Jeremy McSpadden
42f8c192a8 Merge branch 'next' into codex/tagline-punctuation-next 2026-05-31 07:57:37 -05:00
Jeremy McSpadden
d6f555adec Merge pull request #533 from open-gsd/codex/remove-readme-continuity-section
[codex] Remove README continuity section
2026-05-31 07:50:13 -05:00
Jeremy McSpadden
313e6dace9 Merge pull request #535 from open-gsd/ci/maintainer-pr-policy-skips
ci(#534): skip maintainer PR policy gates
2026-05-31 07:49:37 -05:00
Jeremy McSpadden
1c835e208d ci(#534): skip maintainer PR policy gates 2026-05-31 07:46:56 -05:00
Jeremy McSpadden
7eaa14f48f docs(#532): remove README continuity section 2026-05-31 07:41:39 -05:00
Jeremy McSpadden
a8c025febc Merge pull request #531 from open-gsd/codex/readme-brand-cleanup-next
[codex] Streamline README brand header
2026-05-31 07:39:43 -05:00
Jeremy McSpadden
ec8a08f2d2 docs(#530): streamline README brand header 2026-05-31 07:36:52 -05:00
Jeremy McSpadden
09cb6d79b2 docs(#528): correct GSD Core tagline punctuation 2026-05-31 07:33:01 -05:00
Jeremy McSpadden
66b1a56b69 Merge pull request #527 from open-gsd/codex/include-assets-next
[codex] Include README assets in next package
2026-05-31 07:29:59 -05:00
Jeremy McSpadden
9bee1cab7f fix(#526): include README assets in package 2026-05-31 07:28:12 -05:00
Jeremy McSpadden
062f6dc11a Merge pull request #525 from open-gsd/main
Main
2026-05-31 07:21:41 -05:00
Jeremy McSpadden
45e4111257 Merge pull request #524 from open-gsd/codex/gsd-core-brand-refresh
[codex] Rebrand public docs as GSD Core
2026-05-31 07:19:48 -05:00
Jeremy McSpadden
c81d5fcb2c docs(#523): rebrand public docs as GSD Core 2026-05-31 07:16:19 -05:00
github-actions[bot]
63ad985b6a chore: finalize v1.2.0 2026-05-31 01:24:28 +00:00
github-actions[bot]
9e91489325 chore: bump to 1.2.0-rc.1 2026-05-31 00:02:19 +00:00
github-actions[bot]
ade4ee440b chore: bump version to 1.2.0 for release 2026-05-30 23:30:28 +00:00
Tom Boucher
0fbe1d899e chore(#191): retire the gsd-sdk shim — route everything at gsd-tools (#522)
* chore(#191): migrate gsd-sdk query call sites to gsd-tools query

Retiring the gsd-sdk shim. gsd-tools.cjs already accepts `query` as a
meta-prefix (gsd-tools query <command>), so this is a behavior-preserving 1:1
swap across the runtime reference prompts, the graphify hook's commit-detection
gate, and two bin/lib comment/message references.

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

* chore(#191): remove vestigial gsd-sdk shim code from installer + projection

The gsd-sdk shim was already not wired up (no gsd-sdk bin in package.json;
buildWindowsShimTriple had zero call sites). Remove the dead code:
- shell-command-projection.cjs: buildWindowsShimTriple + formatSdkPathDiagnostic
  (+ their now-unused PACKAGE_NAME import) and exports
- install.js: the re-export wrappers + imports, the #3406 stale-standalone-sdk
  detection (detectStaleStandaloneSdk/formatStaleStandaloneSdkWarning + its
  global-install call site), and the exports

Preserved (retained, not gsd-sdk): buildCodexHookWindowsShimIR (#3426) — only
its comments referenced the gsd-sdk pattern; reworded. Also kept the
homePathCoveredByRc 'reopen your shell' branch in maybeSuggestPathExport — its
logic is bin-dir-agnostic, only the message mentioned gsd-sdk; reworded to use
the actual bin dir.

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

* test(#191): update tests for retired gsd-sdk shim

- bug-3441/bug-3442: drop the formatSdkPathDiagnostic / buildWindowsShimTriple
  assertions (functions removed); retained PATH-action + drift-guard tests stay
- bug-505: remove the 'still exported' assertions for detectStaleStandaloneSdk /
  formatStaleStandaloneSdkWarning / the shim contract surface (#505 kept them;
  #191 removes them)
- graphify-auto-update: migrate the hook-dispatch inputs gsd-sdk query commit ->
  gsd-tools query commit to match the migrated commit hook

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

* docs(#191): point active docs at gsd-tools query (gsd-sdk shim retired)

Update the user/agent-facing docs (AGENTS, COMMANDS, CONFIGURATION, USER-GUIDE,
ship-pr-body-sections) that presented gsd-sdk query as a current command to
gsd-tools query. Historical docs (ADRs, PRDs, release notes) left untouched.

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

* docs(#191): correct state.load vs state.json description for gsd-tools query

Adversarial-review (codex) finding: the migrated USER-GUIDE line claimed both
'gsd-tools query state.json' and 'state.load' resolve to the frontmatter-rebuild
handler. Verified they don't — state.load returns the CJS load shape
(config + state_raw + flags), state.json returns the frontmatter shape. Both are
available via gsd-tools query; corrected the text to say so.

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

* chore(#191): add changeset for gsd-sdk shim retirement

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

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 19:19:14 -04:00
Colin Johnson
2bc295b32d fix(#464): make phase completion planning writes transactional (#465)
* fix(#464): make phase completion planning writes transactional

* fix(#464): add phase completion changeset

* test(#464): avoid source-grep rollback assertion

* fix(#464): address phase completion rollback review

* fix(#191): remove retired sdk tsconfig reference
2026-05-30 17:44:36 -04:00
Tom Boucher
79002a00cb chore(#518): rename npm package + bin to @opengsd/gsd-core (#519)
* chore: rename npm package + bin to @opengsd/gsd-core (functional)

- package.json: name @opengsd/get-shit-done-redux → @opengsd/gsd-core,
  bin key get-shit-done-redux → gsd-core, repository/homepage/bugs URLs
- package-lock.json: regenerated (npm install --package-lock-only)
- tests/**, scripts/**, bin/**, .github/**, agents/**, commands/**,
  get-shit-done/bin/**, get-shit-done/workflows/**:
  applied the 4-rule replacement (scoped npm ref, GitHub repo path,
  bin/clone invocations) per #505 single-source refactor

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

* docs: sweep live references to @opengsd/gsd-core

Update all live documentation (README.md + translations, docs/**,
CONTRIBUTING.md, VERSIONING.md, SECURITY.md, CONTEXT.md,
docs/CANARY.md) to reflect the renamed package and repository.

Rules applied:
- @opengsd/get-shit-done-redux → @opengsd/gsd-core (scoped npm name)
- open-gsd/get-shit-done-redux → open-gsd/gsd-core (GitHub repo)
- GSD-redux/get-shit-done-redux → open-gsd/gsd-core (stale badge org)
- bare bin/clone refs → gsd-core

CHANGELOG.md, docs/adr/**, docs/RELEASE-*.md, docs/research/**,
and .changeset/** are preserved byte-identical.

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

* fix: add negative lookbehind to slash-command regex in bug-2954 test

The extractSlashReferences regex matched /gsd-core inside npm package
URLs (@opengsd/gsd-core), producing a false /gsd:core command reference.
Adding a negative lookbehind (?<![a-z]) excludes matches preceded by a
letter, so only standalone /gsd-<cmd> and /gsd:<cmd> tokens are found.

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

* chore(#518): add changeset for package rename

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

* test(#518): update package-identity expectations to the renamed coordinates

The rebase regenerated the seam to @opengsd/gsd-core (bin gsd-core, repo
open-gsd/gsd-core). The #498 seam tests assert deriveIdentity against the REAL
package.json, so their expected literals must follow the rename. The drift-lint
unit test is left as-is — its SEAM is a self-consistent fixture and its
stale-literal detection cases would shift if altered; the live-repo scan in it
already passes.

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

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 17:25:02 -04:00
Tom Boucher
05cdec5f47 feat(#22): plan-vs-codebase drift guard (source-grounded reviewer + intel surface) (#487)
* feat(#22): add plan_review.source_grounding + _authority config keys

Two additive opt-out keys for the drift guard: source_grounding (bool,
default true) gates the source-grounded reviewer pass; _authority (enum
grep|intel|treesitter|lsp|scip, default grep) selects the resolver rung.
No existing default changed.

Refs #22

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(#22): add intel api-surface renderer + CLI subcommand

Renders .planning/intel/api-map.json into a human-readable API-SURFACE.md
for planner injection. Empty/missing map still writes a surface that
announces itself incomplete (absence = unknown, not 'does not exist').
Gated on intel.enabled like all intel functions.

Refs #22

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(#22): add source-grounding pass to plan-review-convergence

Default-on reviewer pass (plan_review.source_grounding) that enumerates
every symbol a plan cites, excludes declared new artifacts, resolves each
against source via the configured authority adapter, and records
three-valued verdicts. rung-0/1 MISSING is needs-acknowledgement, not a
hard block; UNCHECKABLE is logged in a REVIEWS.md coverage section.

Refs #22

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(#22): inject API-SURFACE.md into planner + require Artifacts section

When intel.enabled, plan-phase regenerates API-SURFACE.md and injects it
as a HINT (prefer, may be incomplete, absence = unknown), never a hard
rule. Every plan must now emit an 'Artifacts this phase produces' section
so the source-grounding reviewer can separate new symbols from references
to existing code.

Refs #22

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(#22): surface drift-guard in setup + settings, add docs

/gsd:new-project asks to enable plan_review.source_grounding (default Y);
/gsd:settings exposes the toggle and authority knob. Documents both config
keys in CONFIGURATION.md, the intel api-surface command in COMMANDS.md,
the drift guard in USER-GUIDE.md, and links ADR 22 from ARCHITECTURE.md.

Refs #22

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(#22): respect AskUserQuestion 4-option cap and plan-phase XL line budget

settings drift-guard toggle moved to its own 2-option question; #22
plan-phase additions condensed to bring the file back under the 1810-line
XL budget without dropping the intel gate, the incomplete-surface hint, or
the Artifacts-section requirement.

Refs #22

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(#22): use live slash-command forms in drift-guard docs

Doc-parity gate requires every slash-command token in docs/*.md to resolve
to a registered command. Corrected the command form(s) referenced in the
#22 drift-guard / api-surface documentation.

The unresolved token was /gsd-core, matched from the GitHub repo reference
"open-gsd/gsd-core#22" in docs/adr/22-plan-drift-guard.md. This is the
same pattern as the existing 'test-runner' exemption (open-gsd/gsd-test-runner).
Added 'core' to INTERNAL_COMPONENT_SLUGS with a matching explanatory comment.

Refs #22

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore(#22): add changeset fragment for drift guard (PR #487)

Refs #22

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: CI Rebase Check <ci@gsd-redux>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 17:08:11 -04:00
Tom Boucher
7fd71226b2 chore(#507): retire dead sdk/ references from CONTEXT.md (#508)
ADR-0174 retired the @opengsd/gsd-sdk package; sdk/ no longer exists.
CONTEXT.md still pointed contributors at dead sdk/src/**.ts paths — the
source of the stale references cited in bug reports #500 and #501.

- Glossary: repoint module Source-of-truth/entry-point pointers to the
  live get-shit-done/bin/lib/*.cjs and bin/shared/*.manifest.json homes;
  trim retired SDK-only clauses (milestone runner, SDK native-query
  surfaces, generator pattern). Every replacement path verified on disk.
- Remap live predicates: WORKSTREAM.POINTER.SEAM (-> active-workstream-
  store.cjs), PRED.k320.ci-paths-monitored (-> actual ci-test-scope
  roots), EXEC.CLASSIFY.handler (-> agent-command-router.cjs).
- Remove/generalize obsolete SDK-duality operative rules: SDK-ONLY-VERBS
  (deleted), PORT-DRIFT.cjs-sdk (deleted), SDK-PORT-NAME-COLLISION ->
  NAME-COLLISION (generalized), GENERATIVE exemplar repointed to live
  runtime-launcher-parity.test.cjs, stale-sdk/dist-gen-scripts section
  removed; REMOVED-BUT-NEEDED / SOURCE-GREP / CANARY.detect de-sdk'd.
- Preserve dated SESSION.* log + CANARY.examples audit (history).

Follow-ups for code-side sdk/ cleanup: #504 (lint/stryker config),
#505 (install.js sdk/dist verify), #506 (bin/lib generated banners).

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 17:06:27 -04:00
Tom Boucher
0008244245 refactor: remove stale Source: sdk/src generated-file banners from bin/lib/*.cjs (#510)
* refactor: remove stale sdk/src generated-file banners from bin/lib/*.cjs (#506)

Drop the GENERATED FILE / Source: sdk/src / Regenerate: cd sdk banners from
13 hand-maintained CJS modules and delete the orphaned
generator-freshness-contract script + test. Post-ADR-0174 cleanup; the
referenced sdk/ generator pipeline (dir, gen:* scripts, *.generated.cjs) no
longer exists. No runtime behavior change.

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

* docs: add changeset for #510 (sdk/src banner cleanup)

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

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 17:06:23 -04:00
Tom Boucher
6f2520786d feat(#498): single Package Identity seam for /gsd:update + fix runtime undefined-name bug (#499)
* feat(#498): generated package-identity seam derived from package.json

Introduce a single source for GSD's published-package coordinates:
scripts/generate-package-identity.cjs (pure deriveIdentity + formatManualInstall
+ render) emits the generated get-shit-done/bin/lib/package-identity.cjs with
values baked from package.json at build time. Baking is required because the
installed tree carries only a synthetic {"type":"commonjs"} package.json, so a
runtime require('package.json').name resolves to undefined (#378). Reconciles

Wired into npm run build; a parity test fails CI if the committed file drifts
from package.json.

Refs #498

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

* fix(#498): repoint update worker + check-latest-version at the seam

- check-latest-version.cjs sources PACKAGE_NAME from the package-identity seam
  instead of a re-typed literal (single source; #2992's constant guarantee is
  preserved since the seam bakes from package.json).
- gsd-check-update-worker.js no longer does require('../package.json').name
  (resolved to undefined in the installed tree → background update check
  silently broken, #378). It now delegates the latest-version lookup to
  checkLatestVersion(), collapsing the duplicated npm-view call onto the single
  deterministic adapter and inheriting its typed {ok,version,reason} surface.
- Move the PR #3102 Windows shell-gate contract test onto execNpm (where the
  spawn now lives) and assert the worker no longer spawns npm directly.
- Rewrite the #378 contract: worker must NOT use require(package.json).name and
  must delegate; check-latest-version PACKAGE_NAME is single-sourced from the seam.

Fixes #378-class runtime breakage. Refs #498

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

* chore(#498): changeset for package-identity seam + update-check fix

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

* feat(#498): drift-guard lint — value-check GSD coordinate literals against the seam

scripts/lint-package-identity-drift.cjs scans the runtime/code surface
(bin/, hooks/, scripts/, get-shit-done/) and asserts every GSD package name
and GitHub repo slug literal equals the Package Identity seam's current value.
Passes today; fails the moment a repoint isn't propagated (rename package.json,
regenerate the seam, and stale literals are reported until updated). This is
the second adapter that makes the seam real and a repoint mechanically safe.

Enforced via tests/issue-498-identity-drift-lint.test.cjs (scanRepo === [])
under npm test; also exposed as `npm run check:identity-drift`.

Refs #498

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

* feat(#498): update-context projection — port update.md resolution to a tested seam

Add get-shit-done/bin/lib/update-context.cjs: a pure, injected-fs port of
update.md's ~280-line get_installed_version bash. resolveUpdateContext()
reproduces the full precedence cascade (preferred fast-path -> local probe ->
global probe via env overrides then $HOME -> LOCAL-if-distinct -> scope
cascade -> UNKNOWN) and returns the 4-field contract { installedVersion,
scope, runtime, gsdDir }. The fs is injected so every branch is finally
testable without a live multi-runtime install.

Expose it as `gsd-tools update-context [--config-dir <d>] [--runtime <r>] --json`.
Purely additive — update.md is unchanged in this commit; the workflow swap
follows separately.

Refs #498

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

* feat(#498): swap update.md resolution to the update-context projection

Replace ~280 lines of inline runtime/scope/config-dir bash in update.md's
get_installed_version step with a call to `gsd-tools update-context --json`
(60 lines: derive PREFERRED_* from execution_context, resolve gsd-tools.cjs,
parse the 4-field JSON). Behavior is unchanged — the projection reproduces the
same cascade — but the logic is now tested in update-context.cjs instead of
untestable bash-in-markdown.

Relocate the #3608 antigravity-first-class contract onto the projection
(RUNTIME_DIRS order, inferPreferredRuntime, envRuntimeDirs) plus a behavioral
test; keep the execution_context path-classification assertion on update.md.
Re-point install.test's custom-config-dir assertion (kilo.jsonc/KILO_CONFIG)
to update-context.cjs where that detection now lives.

Full root suite: 2022 pass / 0 fail.

Refs #498

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

* docs(#498): record Update Context Module in CONTEXT.md

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

* fix(#498): CI — avoid bare gsd-tools in update.md; register new CLI modules

- update.md update-context invocation: resolve the PATH gsd-tools shim into a
  variable and call "$GSD_TOOLS" (never a bare `gsd-tools` command) — satisfies
  the #2851 workflow-bare-gsd-tools guard.
- Register package-identity.cjs and update-context.cjs in docs/INVENTORY.md
  (CLI Modules 76 -> 78 + rows) and regenerate docs/INVENTORY-MANIFEST.json,
  fixing inventory-counts and inventory-manifest-sync.

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

* test(#498): make update-context + parity tests OS-agnostic (Windows CI)

Two Windows-only test failures, both test-portability (production code is fine —
the real-fs CLI integration test passed on Windows):

- update-context resolver tests + bug-3608 behavioral test used POSIX path-string
  keys in their fake fs, but the resolver builds lookups via path.join/resolve
  (backslash + drive letter on Windows) → keys never matched → everything
  resolved to UNKNOWN/claude. Normalize fake-fs keys and gsdDir comparisons
  through path.resolve so they match on both platforms.
- package-identity parity test compared render() (LF) to the committed file,
  which Windows git checks out as CRLF (no .gitattributes eol rule). Normalize
  line endings before comparing, matching the repo convention
  (autonomous-decomposition, bug-3707).

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

* fix(#498): update.md backup must use GSD_DIR (adversarial-review finding)

The get_installed_version rewrite emits GSD_DIR but dropped the probe-loop
variables LOCAL_DIR/GLOBAL_DIR. The backup_custom_files step still read those,
so RUNTIME_DIR went empty for every LOCAL/GLOBAL install and detect-custom-files
was skipped — and since the update then runs a clean install that wipes managed
dirs (commands/gsd, get-shit-done), user-added files could be deleted without
the intended backup.

Set RUNTIME_DIR="$GSD_DIR" directly (the resolved config dir; empty for
UNKNOWN scope, which still skips the backup). Add a structural regression
(tests/issue-498-update-backup-runtime-dir.test.cjs).

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

* test(#503): re-point Antigravity .agent detection at the #498 projection

#499 moves the runtime/scope detection cascade out of update.md inline bash
into get-shit-done/bin/lib/update-context.cjs. The #503 regression test asserted
on the inline RUNTIME_DIRS array, which no longer exists, so it would fail
against the projected update.md even though the .agent guarantee is preserved.

Rewrite it to verify the surviving surfaces:
 - behavioral: resolveUpdateContext resolves a LOCAL ./.agent install to the
   antigravity runtime (the original root cause, now covered by adding
   ['antigravity', '.agent'] to the projection RUNTIME_DIRS table)
 - update.md prose classifier still maps /.agent/ -> antigravity
 - the post-update cache-clear for-dir loop still includes .agent

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

* fix(#498): finish de-hardcoding consumers + close adversarial-review parity gaps

Restore the consumer de-hardcoding that is the point of the seam, and close the
parity gaps an adversarial review (codex) found in the update-context projection.

De-hardcode the repo slug + install command in the changeset tooling — #516
only single-sourced the package NAME, leaving 'open-gsd/get-shit-done-redux'
hardcoded in scripts/changeset/cli.cjs and github-release-notes.cjs. Route both
through the seam's repoSlug/packageName so a rename is a regenerate, not a hand
edit. The drift-lint real scan now reports zero divergent coordinate literals.

Projection parity vs the old inline bash, as ONE consistent rule
(trustedVersionAt) applied on every path:
 - expand a leading ~/ in preferredConfigDir before the fast path (the bash ran
   expand_home first; a custom --config-dir ~/foo otherwise fell to UNKNOWN)
 - trust a version only when BOTH VERSION and the update.md marker exist — fast
   path AND LOCAL/GLOBAL cascade; a partial dir falls to 0.0.0 keeping scope
 - apply the same same-path dedup to the 0.0.0 fallback so a partial install
   probed from cwd===home is not misdetected as LOCAL

Adds regression tests for tilde expansion, VERSION-only (cascade + fast path),
and the cwd===home partial-install dedup.

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

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 16:53:44 -04:00
Tom Boucher
fbd555c2ce fix(#520): register package-identity.cjs in inventory (regression from #516) (#521)
#516 added get-shit-done/bin/lib/package-identity.cjs without regenerating
the inventory, breaking inventory-manifest-sync and inventory-counts on next.
Regenerate docs/INVENTORY-MANIFEST.json and bump docs/INVENTORY.md
CLI-module count 76 -> 77 with the new row.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 14:43:20 -04:00
Tom Boucher
b54026e106 chore(#516): single-source the package name from package.json (#517)
Adds get-shit-done/bin/lib/package-identity.cjs as the single source of
truth for PACKAGE_NAME, derived from package.json `name` via require.
Refactors all runtime code-line occurrences in bin/install.js,
get-shit-done/bin/check-latest-version.cjs,
get-shit-done/bin/lib/shell-command-projection.cjs,
get-shit-done/bin/lib/verify.cjs, scripts/changeset/cli.cjs,
scripts/changeset/github-release-notes.cjs, and
scripts/release-tarball-smoke.cjs to import PACKAGE_NAME from the
identity module instead of hardcoding the literal.

The package name is unchanged (@opengsd/get-shit-done-redux). Behaviour
is byte-identical: all --help, hint, and release-notes strings render
exactly as before. Golden-literal tests (bug-2992, bug-378) keep their
hardcoded expected values and remain GREEN.

Adds tests/package-name-single-source.test.cjs lint guard: fails CI if
@opengsd/get-shit-done-redux appears as a code-line literal in runtime
.cjs/.js outside the identity module, enforcing a one-file rename path.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 13:07:58 -04:00
Tom Boucher
a1f4996d9a fix(#505): remove dead SDK-shim verification subsystem from bin/install.js (#515)
* fix(#505): remove dead SDK-shim verification subsystem from bin/install.js

Post-ADR-0174 the @opengsd/gsd-sdk package was retired; sdk/ no longer ships.
installSdkIfNeeded had no callers in the live install flow and its entire
transitive call graph (classifySdkInstall, buildSdkFailFastReport,
renderSdkFailFastReport, buildGsdSdkVersionMismatchReport, readGsdSdkVersion,
parseGsdSdkVersion, findGsdSdkOnPath, isGsdSdkOnPath, isLegacyGsdSdkShim,
filterNpxFromPath, getUserShellPath, getUserShellWindowsPersistentPath,
trySelfLinkGsdSdk, trySelfLinkGsdSdkWindows, buildWindowsShimTriple,
formatSdkPathDiagnostic, renderGsdSdkVersionMismatchReport) was dead code.
Also removed two now-empty test files (no-unconditional-win32-skip.test.cjs,
bug-3020-install-shell-path-probe.test.cjs) that exercised the removed
functions, and added a regression guard (bug-505-remove-dead-sdk-verification.test.cjs).
detectStaleStandaloneSdk and formatStaleStandaloneSdkWarning are deliberately
KEPT — they handle a real leftover-global-SDK condition (#3406).

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

* chore: add changeset for #505 dead SDK-shim removal

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

* fix(#505): restore buildWindowsShimTriple/formatSdkPathDiagnostic projection surfaces

The dead-code removal also deleted buildWindowsShimTriple and
formatSdkPathDiagnostic (plus their imports/exports). These have no
production caller, but they are the install.js side of a projection-contract
drift guard: tests/bug-3441 and tests/bug-3442 assert install.js delegates to
shell-command-projection.cjs rather than hand-rolling the projection. Removing
them broke those tests (TypeError: ... is not a function) — surfaced by the
full/coverage CI matrix, which runs suites the local scoped run skipped.

Restore the two thin wrappers, their `*FromProjection` import aliases, and
their exports. Update the bug-505 guard test to assert they remain exported as
contract surfaces (moved out of the dead-symbol list).

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

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 12:01:04 -04:00
Tom Boucher
d720cef8e9 fix(#500): state planned-phase corrupts STATE.md milestone progress.* counters (#514)
* fix(#500): stop state planned-phase corrupting milestone progress.* counters

Two independent defects combined to corrupt STATE.md progress.* on a
plan-phase run:

RC1 — cmdStatePlannedPhase wrote via writeStateMd, which unconditionally
runs syncStateFrontmatter and rebuilds progress.* (total/completed
plans+phases) from a half-planned disk snapshot, trampling curated
counters. It now routes through readModifyWriteStateMd(..., { resync:false }),
the same body-only-write guard state.update uses — per-phase body fields
are updated, milestone progress.* is preserved.

RC2 — isRootPlanFile's loose /PLAN/i fallback matched legacy
`<N>-PLAN-<NN>-SUMMARY.md` names (they contain "PLAN"), double-counting
summaries as plans (a 4-plan/4-summary phase scanned as planCount:8,
completed:false). isRootPlanFile now rejects isRootSummaryFile before the
fallback, so summaries are never counted as plans.

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

* chore(#500): add changeset for planned-phase progress fix

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

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 12:01:01 -04:00
Tom Boucher
5589f4f817 fix(#501): stop flat "## Phase Details" leaking phases into active milestone (#513)
* fix(#501): stop flat "## Phase Details" leaking phases into active milestone

extractCurrentMilestone returned `preamble + currentSection`, where the
preamble (everything before the first milestone heading, only <details>
stripped) could carry a flat "## Phase Details" section listing `### Phase N:`
entries for ALL milestones. Those leaked into the active-milestone scope, so
getMilestonePhaseFilter / buildStateFrontmatter counted the whole project
(e.g. total_phases: 18) instead of the active milestone (14-18).

Fix (maintainer direction: code fix, count + validate-aware):
1. core.cjs extractCurrentMilestone — strip flat phase-detail blocks
   (`### Phase N:` heading + body, and a "## Phase Details" heading) from the
   preamble. The active milestone's own phases live in currentSection, so this
   is safe. Fixes the count with no ROADMAP edits.
2. verify.cjs cmdValidateConsistency + cmdValidateHealth — the "phases on disk
   but not in ROADMAP" / W007 checks now compare disk dirs against the FULL
   roadmap (every milestone), not the active-milestone scope. Without this,
   narrowing the scope would flag every shipped phase dir as a spurious orphan
   (the documented side effect of the <details> workaround).

Tests reproduce the real layout (flat Phase Details before milestones) and
assert: state json total_phases counts only active phases; validate
consistency and validate health (W007) do not flag shipped phase dirs.

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

* chore(#501): add changeset for flat Phase Details milestone leak fix

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

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 12:00:58 -04:00
Tom Boucher
b0c5d86aba fix(#503): detect local Antigravity (.agent) installs in /gsd:update (#512)
* fix(#503): detect local Antigravity (.agent) installs in /gsd:update

The installer places local Antigravity installs in ./.agent/
(bin/install.js getDirName('antigravity') === '.agent'), but the
/gsd:update detection cascade in update.md only knew the global
Antigravity layout (.gemini/antigravity{,-ide,-cli}). A local .agent
install fell through to the `Otherwise -> claude` default, so the
update refreshed Claude artifacts instead of the Antigravity install.

Add `.agent` -> antigravity to all four runtime-dir surfaces in
update.md: the execution_context path classifier, the RUNTIME_DIRS
candidate array, the local-scope discovery loop, and the post-update
cache-clear loop (the last otherwise left a stale update indicator on
local Antigravity installs).

Note: the issue also cited update-context.cjs, which does not exist on
`next` (it is introduced by the still-open PR #499). The same .agent
fix should be carried into update-context.cjs when #499 lands.

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

* chore(#503): add changeset for Antigravity .agent detection fix

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

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 12:00:55 -04:00
Jeremy McSpadden
3b4f293825 Merge pull request #497 from open-gsd/dependabot/npm_and_yarn/npm_and_yarn-9540d54162
chore(deps): bump tmp from 0.0.33 to removed in the npm_and_yarn group across 1 directory
2026-05-29 19:19:16 -05:00
dependabot[bot]
11c7fc590e chore(deps): bump tmp in the npm_and_yarn group across 1 directory
Bumps the npm_and_yarn group with 1 update in the / directory: [tmp](https://github.com/raszi/node-tmp).


Removes `tmp`

---
updated-dependencies:
- dependency-name: tmp
  dependency-version:
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-30 00:17:25 +00:00
Tom Boucher
a7ed001b27 fix(#494): ci-test-scope selects checks a diff can break (tests->full matrix, docs->docs-parity) (#495)
classify() under-approximated breakable checks, so scoped PRs skipped the
check their diff would break and regressions reached next (#484 docs-parity,
#482 windows-22 EBUSY). Fail-safe widen: any tests/** change forces
full_matrix (OS-specific test failures); any docs/**, commands/**, agents/**
change marks code_changed and selects docs-parity-live-registry (its runtime
inputs). Updated the docs-only test that asserted the old buggy contract.

Fixes #494

Co-authored-by: CI Rebase Check <ci@gsd-redux>
2026-05-29 19:03:22 -04:00
Tom Boucher
a8ff46484b fix(#474): deterministic STATE dates via deepened clock seam (nowIso/today + GSD_NOW_MS adapter) (#477)
* fix(#474): route state date-stamping + installer lock loop through clock seam (nowIso/today + GSD_NOW_MS adapter)

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

* fix(#474): use process.ppid (not pid 1) as held-lock owner in install-lock timeout test

pid 1 is POSIX init/launchd (always alive) but does not exist on Windows,
so isPidAlive(1) returns false, the lock is reclaimed as stale, and
acquireInstallMigrationLock no longer throws -- failing the timeout
assertion on windows-latest,22. process.ppid is a live, non-self process
on every platform, so the lock is seen as held and the timeout path
throws deterministically cross-platform.

Refs #474

---------

Co-authored-by: CI Rebase Check <ci@gsd-redux>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 18:21:25 -04:00
Tom Boucher
75b29c2c08 fix(#490): restore bounded Windows EBUSY cleanup retry in bug-1974 afterEach (#493)
#482 removed the afterEach outer retry guard, trusting rmSync maxRetries:20
(~5s). Under windows-2022 CI load the temp dir stays EBUSY longer, so the
bare cleanup() throws and the hook fails (next went red on full test
(windows-latest, 22)). Restore a bounded retry with async setTimeout backoff
(no Atomics.wait, per no-magic-sleep-in-tests).

Fixes #490

Co-authored-by: CI Rebase Check <ci@gsd-redux>
2026-05-29 18:13:43 -04:00
Tom Boucher
28cf6b444f test(#489): stop docs-parity tokenizer matching repo path open-gsd/gsd-core as a command (#491)
extractCommandTokens regexes matched the /gsd-core substring inside the
org/repo path open-gsd/gsd-core#22. Add a negative lookbehind so only
actual invocations (BOL / space / backtick / paren) match, not path or
word-embedded segments. Add a regression test covering the repo-path
false positive while proving real broken command refs are still caught.

Refs #489

Co-authored-by: CI Rebase Check <ci@gsd-redux>
2026-05-29 18:08:27 -04:00
Tom Boucher
b9ea06fa8b ci(#483): resolve transitive dependencies in affected-test selection + zero-dependent widen backstop (#485)
Co-authored-by: CI Rebase Check <ci@gsd-redux>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 17:12:58 -04:00
Tom Boucher
48824f258c fix(#444): resolver preamble checks repo-local .claude install path (#476)
The gsd_run resolver preamble now probes
<repo-root>/.claude/get-shit-done/bin/${_GSD_SHIM_NAME} as the second
check — immediately after the existing get-shit-done/bin/ check and
before command -v / $HOME/.claude fallbacks. This covers the install
layout produced by npx @opengsd/get-shit-done-redux@latest --claude --local.

A _GSD_RUNTIME_ROOT variable is introduced to bind the repo-root
expression once and reuse it for both checks without repeating the
git rev-parse subshell.

76 workflow files regenerated via node scripts/sync-runtime-launcher.cjs.
All parity, size-budget, and new regression tests pass.

Co-authored-by: CI Rebase Check <ci@gsd-redux>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 17:12:54 -04:00
Tom Boucher
d7dafafd03 fix(#442): --config-dir= no longer truncates paths containing equals signs (#475)
Extract a pure `parseConfigDirFromArgs(argsArray)` seam from the
closure-based `parseConfigDirArg()` and fix the equals-form parser to
use `slice(indexOf('=') + 1)` instead of `split('=')[1]`, so that
paths like `/tmp/gsd=a` or `/tmp/a=b=c` are preserved in full.

Both `--config-dir=<path>` and `-c=<path>` are fixed.  The pure seam
is exported via `module.exports` so the 12-case unit test can assert
on typed return values without spawning a child process.

Co-authored-by: CI Rebase Check <ci@gsd-redux>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 17:12:50 -04:00
Tom Boucher
6687087627 fix(#481): remove residual dead silent-expiry poll helper + Atomics.wait afterEach retry in bug-1974 (racy caller already removed by #453) (#482)
The 45s detached-subprocess poll caller was removed by #453; this deletes the
residual dead waitForStateMatch helper (silent-expiry anti-pattern) and the
redundant Atomics.wait-based afterEach retry loop (cleanup() already retries via
fs.rmSync maxRetries:20). Net deletion; deterministic tests untouched.

Co-authored-by: CI Rebase Check <ci@gsd-redux>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 17:12:45 -04:00
Tom Boucher
5f18379da5 fix(#478): delete wall-clock elapsed-time assertions per ADR 456 (keep correctness invariants) (#480)
Co-authored-by: CI Rebase Check <ci@gsd-redux>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 17:12:41 -04:00
Tom Boucher
d2ff4ac092 docs(#22): add ADR for plan-vs-codebase drift guard (defaults + resolver seam) (#484)
Consolidated decision record: source-grounding verification default-on
(plan_review.source_grounding), intel.enabled stays opt-in, and the
three-valued symbol-resolver seam with a climbable adapter ladder.

Refs #22

Co-authored-by: CI Rebase Check <ci@gsd-redux>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 17:12:37 -04:00
Tom Boucher
d3eaf6aec1 docs(#23): document changeset extract CLI contract (#479)
Add scripts/changeset/README.md specifying the cli.cjs extract
subcommand: invocation, flags, version validation, exit-code table
(0/1/2), and output shapes for text and --json modes.

Corrects two inaccuracies from the triage table against the source:
v-prefixed versions ARE accepted (stripped), and it is pre-release/
build suffixes that are rejected — not the v prefix. Also documents
the full exit-1 surface (missing flags, invalid semver, missing
changelog) and the exit-2 overlap (empty range vs malformed argv) so
external callers do not conflate "no releases in range" with failure.

Closes #23

Co-authored-by: CI Rebase Check <ci@gsd-redux>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 17:12:33 -04:00
Tom Boucher
e22596be04 fix(#471): make perf-407 lock-buffer-alloc test deterministic via clock-seam; remove real-worker race (#472)
Co-authored-by: CI Rebase Check <ci@gsd-redux>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 13:20:32 -04:00
Tom Boucher
b735f270c5 chore(#469): clear residual warn-level lint in effort test files (#470)
Remove unused `os` import left by #463's effort-API conversion and fix
two no-useless-escape chars in codex-config test description string.
Part of ESLint harness cleanup effort (#452).

Co-authored-by: CI Rebase Check <ci@gsd-redux>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 12:25:27 -04:00
Tom Boucher
c7e5a88353 enh(#466): refresh opus-tier model IDs to current GA (Opus 4.8 / codex gpt-5.5) (#467)
* enh: bump opus-tier model IDs to current GA (Opus 4.8 / codex gpt-5.5)

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

* chore(#466): changeset for opus-tier model-ID refresh

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

---------

Co-authored-by: CI Rebase Check <ci@gsd-redux>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 11:52:47 -04:00