feat(3530): STATE.md Document Module via generator (Phase 1 of #3524) (#3531)

* feat(3530): STATE.md Document Module via generator (Phase 1 of #3524)

Phase 1 of the CJS↔SDK hard-seam migration (parent #3524).
Converts the hand-synced state-document.cjs/state-document.ts pair
into a generator-driven seam, modeled on the existing
command-aliases.generated.* precedent.

What landed:
- sdk/src/query/state-document.ts is the source of truth.
- sdk/scripts/gen-state-document.ts emits
  get-shit-done/bin/lib/state-document.generated.cjs from the
  compiled SDK dist via Function.prototype.toString() inspection
  for the 7 public exports and 3 internal helpers.
- sdk/scripts/check-state-document-fresh.mjs is the CI freshness
  gate; pre-commit hook also runs it when relevant files change.
- get-shit-done/bin/lib/state-document.cjs is reduced to a one-line
  re-export from state-document.generated.cjs so existing callers
  (state.cjs, workstream-inventory.cjs, init.cjs) need no changes.
- New CI step in .github/workflows/test.yml after the existing alias
  drift check.
- sdk/package.json: gen:state-document, check:state-document-fresh
  scripts. tsx added as devDep.
- Root package.json: proxy script for the freshness check.
- CONTEXT.md: one-sentence amendment on STATE.md Document Module
  recording the source-of-truth file path.

Tests:
- sdk/src/query/state-document.test.ts: 34 vitest fixtures across
  the 7 public exports (TDD pinning safety net).
- tests/state-document-generator.test.cjs: 31 node:test parity
  assertions comparing SDK source vs generated CJS for every
  fixture.
- Full suite: 9177/9177 pass (baseline was 9146; +31 new tests).

One subtle behavior change worth flagging: the old hand-written
state-document.cjs used String(str) coercion inside escapeRegex,
which the SDK source does not. The generator faithfully matches
the SDK (the source of truth per ADR-3524), so the new CJS no
longer coerces non-string input to string before regex-escaping.
No current caller passes non-string input, so no observable
regression in the test suite. Flagged in the PR body for
reviewers.

Closes #3530.

* fix(3530): address state-document review findings
This commit is contained in:
Tom Boucher
2026-05-14 22:17:20 -04:00
committed by GitHub
parent e437ded6fc
commit bfd7ddbad3
15 changed files with 1371 additions and 133 deletions

View File

@@ -1,5 +1,5 @@
{
"generated": "2026-05-13",
"generated": "2026-05-14",
"families": {
"agents": [
"gsd-advisor-researcher",
@@ -306,6 +306,7 @@
"shell-command-projection.cjs",
"state-command-router.cjs",
"state-document.cjs",
"state-document.generated.cjs",
"state.cjs",
"surface.cjs",
"template.cjs",

View File

@@ -360,7 +360,7 @@ The `gsd-planner` agent is decomposed into a core agent plus reference modules t
---
## CLI Modules (59 shipped)
## CLI Modules (60 shipped)
Full listing: `get-shit-done/bin/lib/*.cjs`.
@@ -415,6 +415,7 @@ Full listing: `get-shit-done/bin/lib/*.cjs`.
| `state-command-router.cjs` | Thin CJS subcommand router adapter for `gsd-tools state` |
| `state.cjs` | STATE.md parsing, updating, progression, metrics |
| `state-document.cjs` | Pure STATE.md field extraction, replacement, status normalization, and progress calculation transforms |
| `state-document.generated.cjs` | GENERATED — CJS artifact emitted from `sdk/src/query/state-document.ts` via `sdk/scripts/gen-state-document.ts`; do not edit directly |
| `surface.cjs` | Runtime surface module — manages the runtime enable/disable surface state independently of the install-time profile marker (ADR-0011 Phase 2) |
| `template.cjs` | Template selection and filling with variable substitution |
| `uat.cjs` | UAT file parsing, verification debt tracking, audit-uat support |