Merge origin/main into feat/3597-split-suites-node-matrix
Resolves conflict in .github/workflows/test.yml: keep the 6 new drift-check steps from main (plan-scan, secrets, schema-detect, decisions, workstream-name-policy, Shared Module hand-sync) before the split-lane test runs from this PR. PR's dedicated `coverage` job replaces main's per-matrix `Run tests with coverage` step. Other conflicting files (CONTRIBUTING.md, get-shit-done/bin/lib/init.cjs, package.json) auto-merged cleanly. Changeset files (.changeset/*) brought in from main as adds.
This commit is contained in:
@@ -264,6 +264,7 @@
|
||||
"artifacts.cjs",
|
||||
"audit.cjs",
|
||||
"cjs-command-router-adapter.cjs",
|
||||
"cjs-sdk-bridge.cjs",
|
||||
"clusters.cjs",
|
||||
"command-aliases.generated.cjs",
|
||||
"commands.cjs",
|
||||
@@ -273,6 +274,7 @@
|
||||
"context-utilization.cjs",
|
||||
"core.cjs",
|
||||
"decisions.cjs",
|
||||
"decisions.generated.cjs",
|
||||
"docs.cjs",
|
||||
"drift.cjs",
|
||||
"fallow-runner.cjs",
|
||||
@@ -295,6 +297,7 @@
|
||||
"phase.cjs",
|
||||
"phases-command-router.cjs",
|
||||
"plan-scan.cjs",
|
||||
"plan-scan.generated.cjs",
|
||||
"planning-workspace.cjs",
|
||||
"profile-output.cjs",
|
||||
"profile-pipeline.cjs",
|
||||
@@ -305,7 +308,9 @@
|
||||
"runtime-homes.cjs",
|
||||
"runtime-slash.cjs",
|
||||
"schema-detect.cjs",
|
||||
"schema-detect.generated.cjs",
|
||||
"secrets.cjs",
|
||||
"secrets.generated.cjs",
|
||||
"security.cjs",
|
||||
"shell-command-projection.cjs",
|
||||
"state-command-router.cjs",
|
||||
@@ -321,6 +326,7 @@
|
||||
"workstream-inventory-builder.generated.cjs",
|
||||
"workstream-inventory.cjs",
|
||||
"workstream-name-policy.cjs",
|
||||
"workstream-name-policy.generated.cjs",
|
||||
"workstream.cjs",
|
||||
"worktree-safety.cjs"
|
||||
],
|
||||
|
||||
@@ -361,7 +361,7 @@ The `gsd-planner` agent is decomposed into a core agent plus reference modules t
|
||||
|
||||
---
|
||||
|
||||
## CLI Modules (64 shipped)
|
||||
## CLI Modules (70 shipped)
|
||||
|
||||
Full listing: `get-shit-done/bin/lib/*.cjs`.
|
||||
|
||||
@@ -372,6 +372,7 @@ Full listing: `get-shit-done/bin/lib/*.cjs`.
|
||||
| `artifacts.cjs` | Canonical artifact registry — known `.planning/` root file names; used by `gsd-health` W019 lint |
|
||||
| `audit.cjs` | Audit dispatch, audit open sessions, audit storage helpers |
|
||||
| `cjs-command-router-adapter.cjs` | Shared compatibility adapter for manifest-backed CJS command-family routers |
|
||||
| `cjs-sdk-bridge.cjs` | Shared SDK runtime-bridge loader (`tryLoadSdk`/`getExecuteForCjs`); consumed by every CJS router and `gsd-tools.cjs` to delegate canonical commands to the SDK in-process |
|
||||
| `clusters.cjs` | Skill cluster definitions for the runtime surface module (ADR-0011 Phase 2) |
|
||||
| `command-aliases.generated.cjs` | Generated CJS alias/subcommand metadata for manifest-backed family routers |
|
||||
| `commands.cjs` | Misc CLI commands (slug, timestamp, todos, scaffolding, stats) |
|
||||
@@ -380,7 +381,8 @@ Full listing: `get-shit-done/bin/lib/*.cjs`.
|
||||
| `configuration.generated.cjs` | Generated Configuration Module — canonical config loading, legacy-key normalization, defaults merge, and explicit on-disk migration; source of truth for both SDK and CJS consumers |
|
||||
| `context-utilization.cjs` | Pure classifier for `gsd-health --context` — turns (tokensUsed, contextWindow) into a `{ percent, state }` triage result against the 60%/70% fracture-point thresholds (#2792) |
|
||||
| `core.cjs` | Error handling, output formatting, shared utilities, runtime fallbacks; compatibility re-exports for planning-workspace helpers |
|
||||
| `decisions.cjs` | Shared parser for CONTEXT.md `<decisions>` blocks (D-NN entries); used by `gap-checker.cjs` and intended for #2492 plan/verify decision gates |
|
||||
| `decisions.cjs` | CJS shim adapter — re-exports from `decisions.generated.cjs` (Phase 6/#3575 Shared Module migration) |
|
||||
| `decisions.generated.cjs` | GENERATED — CJS artifact emitted from `sdk/src/query/decisions.ts` via `sdk/scripts/gen-decisions.mjs`; parses CONTEXT.md `<decisions>` blocks, accepts numeric (D-42) and alphanumeric (D-INFRA-01) IDs, returns `{id, text, category, tags, trackable}`; do not edit directly |
|
||||
| `docs.cjs` | Docs-update workflow init, Markdown scanning, monorepo detection |
|
||||
| `drift.cjs` | Post-execute codebase structural drift detector (#2003): classifies file changes into new-dir/barrel/migration/route categories and round-trips `last_mapped_commit` frontmatter |
|
||||
| `fallow-runner.cjs` | Fallow audit adapter for `/gsd-code-review`: binary resolution (`PATH` then `node_modules/.bin`), actionable missing-binary errors, and structural findings normalization |
|
||||
@@ -402,7 +404,8 @@ Full listing: `get-shit-done/bin/lib/*.cjs`.
|
||||
| `phase-command-router.cjs` | Thin CJS subcommand router adapter for `gsd-tools phase` |
|
||||
| `phase.cjs` | Phase directory operations, decimal numbering, plan indexing |
|
||||
| `phases-command-router.cjs` | Thin CJS subcommand router adapter for `gsd-tools phases` |
|
||||
| `plan-scan.cjs` | Canonical phase-plan scanner — shared helper for detecting plan and summary files in flat and nested layouts (k014); consumed by state, roadmap, init, and workstream inventory paths |
|
||||
| `plan-scan.cjs` | CJS shim adapter — re-exports from `plan-scan.generated.cjs` (Phase 6/#3575 Shared Module migration) |
|
||||
| `plan-scan.generated.cjs` | GENERATED — CJS artifact emitted from `sdk/src/query/plan-scan.ts` via `sdk/scripts/gen-plan-scan.mjs`; canonical phase-plan scanner for detecting plan and summary files in flat and nested layouts (k014); do not edit directly |
|
||||
| `planning-workspace.cjs` | Planning path/workstream seam (`planningDir`, `planningPaths`, active-workstream routing, `.planning/.lock` orchestration) |
|
||||
| `project-root.generated.cjs` | GENERATED — CJS artifact emitted from `sdk/src/project-root/index.ts` via `sdk/scripts/gen-project-root.mjs`; resolves a project root from a starting directory using four heuristics (own `.planning/` guard, `sub_repos` config, `multiRepo` flag, `.git` heuristic); do not edit directly |
|
||||
| `profile-output.cjs` | Profile rendering, USER-PROFILE.md and dev-preferences.md generation |
|
||||
@@ -412,8 +415,10 @@ Full listing: `get-shit-done/bin/lib/*.cjs`.
|
||||
| `roadmap.cjs` | ROADMAP.md parsing, phase extraction, plan progress |
|
||||
| `runtime-homes.cjs` | Canonical runtime → global config/skills directory mapping; first-class support for all 15 runtimes including Hermes nested layout and Cline rules-based exclusion (#3126) |
|
||||
| `runtime-slash.cjs` | Runtime-aware slash-command formatter — single source of truth for emitting `/gsd-<cmd>` (skills-based runtimes) and `$gsd-<cmd>` (codex) in user-facing output and persisted artifacts (#3584) |
|
||||
| `schema-detect.cjs` | Schema-drift detection for ORM patterns (Prisma, Drizzle, etc.) |
|
||||
| `secrets.cjs` | Secret-config masking convention (`****<last-4>`) for integration keys managed by `/gsd-config --integrations` — keeps plaintext out of `config-set` output |
|
||||
| `schema-detect.cjs` | CJS shim adapter — re-exports from `schema-detect.generated.cjs` (Phase 6/#3575 Shared Module migration) |
|
||||
| `schema-detect.generated.cjs` | GENERATED — CJS artifact emitted from `sdk/src/query/schema-detect.ts` via `sdk/scripts/gen-schema-detect.mjs`; schema-drift detection for ORM patterns (Prisma, Drizzle, Supabase, TypeORM, Payload); exports `detectSchemaFiles`, `detectSchemaOrm`, `checkSchemaDrift`, `SCHEMA_PATTERNS`, `ORM_INFO`; do not edit directly |
|
||||
| `secrets.cjs` | CJS shim adapter — re-exports from `secrets.generated.cjs` (Phase 6/#3575 Shared Module migration) |
|
||||
| `secrets.generated.cjs` | GENERATED — CJS artifact emitted from `sdk/src/query/secrets.ts` via `sdk/scripts/gen-secrets.mjs`; secret-config masking convention (`****<last-4>`) for integration keys; exports `SECRET_CONFIG_KEYS`, `isSecretKey`, `maskSecret`, `maskIfSecret`; do not edit directly |
|
||||
| `security.cjs` | Path traversal prevention, prompt injection detection, safe JSON/shell helpers |
|
||||
| `shell-command-projection.cjs` | Runtime-aware shell command projection for managed hook serialization: decides PowerShell call-operator usage by runtime/platform and normalizes Windows script path tokens |
|
||||
| `state-command-router.cjs` | Thin CJS subcommand router adapter for `gsd-tools state` |
|
||||
@@ -428,7 +433,8 @@ Full listing: `get-shit-done/bin/lib/*.cjs`.
|
||||
| `verify.cjs` | Plan structure, phase completeness, reference, commit validation |
|
||||
| `workstream-inventory-builder.generated.cjs` | GENERATED — pure workstream inventory projection builder; CJS artifact emitted from `sdk/src/workstream-inventory/builder.ts` via `sdk/scripts/gen-workstream-inventory-builder.mjs`; do not edit directly |
|
||||
| `workstream-inventory.cjs` | Shared workstream inventory projection: state fields, phase/plan/summary counts, roadmap phase count, and active marker — thin orchestrator that delegates pure projection to `workstream-inventory-builder.generated.cjs` |
|
||||
| `workstream-name-policy.cjs` | Canonical workstream name validation (`isValidActiveWorkstreamName`) and slug normalization (`toWorkstreamSlug`); shared by all workstream callers |
|
||||
| `workstream-name-policy.cjs` | CJS shim adapter — re-exports from `workstream-name-policy.generated.cjs` (Phase 6/#3575 Shared Module migration) |
|
||||
| `workstream-name-policy.generated.cjs` | GENERATED — CJS artifact emitted from `sdk/src/workstream-name-policy.ts` via `sdk/scripts/gen-workstream-name-policy.mjs`; canonical workstream name validation (`isValidActiveWorkstreamName`, `hasInvalidPathSegment`, `validateWorkstreamName`) and slug normalization (`toWorkstreamSlug`); do not edit directly |
|
||||
| `workstream.cjs` | Workstream CRUD, migration, session-scoped active pointer |
|
||||
| `worktree-safety.cjs` | Worktree-root resolution and non-destructive prune policy decisions; owns W017 health-check logic |
|
||||
|
||||
|
||||
269
docs/agents/cjs-sdk-seam.md
Normal file
269
docs/agents/cjs-sdk-seam.md
Normal file
@@ -0,0 +1,269 @@
|
||||
# CJS↔SDK Hard-Seam Migration: Complete Reference
|
||||
## Issue #3575 (Parent: #3524)
|
||||
|
||||
---
|
||||
|
||||
## Migration overview
|
||||
|
||||
The CJS↔SDK hard-seam migration (#3524) eliminates a class of config-schema drift bugs by introducing single sources of truth at every decision point where CJS and SDK code previously diverged. The migration proceeded in six phases:
|
||||
|
||||
| Phase | PR | Summary |
|
||||
|-------|----|---------|
|
||||
| Phase 1 | [#3531](https://github.com/gsd-build/get-shit-done/pull/3531) | `state-document` Shared Module — source-of-truth at `sdk/src/state-document/`, generator, freshness check, CJS Adapter (`state-document.generated.cjs`). Worked example for the pattern. |
|
||||
| Phase 2 | [#3540](https://github.com/gsd-build/get-shit-done/pull/3540) | `configuration` Shared Module — `sdk/shared/config-schema.manifest.json` + `sdk/shared/config-defaults.manifest.json` as data manifests; generator + freshness check + CJS Adapter. |
|
||||
| Phase 3 | [#3548](https://github.com/gsd-build/get-shit-done/pull/3548) | `workstream-inventory` Shared Module — source-of-truth at `sdk/src/workstream-inventory/`, builder, generator, freshness check, CJS Adapter. |
|
||||
| Phase 4 | [#3554](https://github.com/gsd-build/get-shit-done/pull/3554) | `project-root` Shared Module — source-of-truth at `sdk/src/project-root/`, generator, freshness check, CJS Adapter. |
|
||||
| Phase 5.0 | [#3558](https://github.com/gsd-build/get-shit-done/pull/3558) | `runtime-bridge-sync` worker — enables CJS-side execution of SDK native handlers; state.* family initial router delegation via `executeForCjs`. |
|
||||
| Phase 5.1 | [#3574](https://github.com/gsd-build/get-shit-done/pull/3574) | `state.*` router delegation complete — all known state subcommands delegated via `executeForCjs`; Phase 5.0 worker bug fix. |
|
||||
| Phase 6 | [#3577](https://github.com/gsd-build/get-shit-done/pull/3577) (closes [#3575](https://github.com/gsd-build/get-shit-done/issues/3575)) | Enforcement hardening + Final completion — hand-sync drift lint, CODEOWNERS, 6 family-router migrations, 5 Shared Module migrations (plan-scan, secrets, schema-detect, decisions, workstream-name-policy), workstream native support, parity fixes. Migration feature-complete: 22 cooperating siblings, 0 backlog pairs. |
|
||||
|
||||
---
|
||||
|
||||
## Phase 6 Retrospective: 15 config-schema drift bugs
|
||||
|
||||
This section captures 15 recurring config-schema drift bugs that motivated the migration. For each, we record what drifted, the surgical fix, and which Phase 6 enforcement layer would have prevented it.
|
||||
|
||||
---
|
||||
|
||||
### #1535 — Silent failure on unrecognized config.json keys
|
||||
- **Drifted:** `loadConfig` silently ignored any top-level key in `.planning/config.json` not in `VALID_CONFIG_KEYS`, giving users no feedback when hand-edited or external-tool-added keys had no effect.
|
||||
- **Fix landed:** PR #1542 — added stderr warning listing unrecognized keys.
|
||||
- **Would have been blocked by:** **handsync lint** — a seam-aware linter would forbid having parallel hand-authored config validators (CJS `config.cjs` and SDK `config-mutation.ts`) that could silently diverge.
|
||||
|
||||
---
|
||||
|
||||
### #1542 — fix(config): warn on unrecognized keys in config.json instead of silent drop
|
||||
- **Drifted:** No drift in this bug itself; it *fixed* #1535's silent-drop behavior by adding the warning.
|
||||
- **Fix landed:** PR #1542 — merged as the direct fix for #1535.
|
||||
- **Would have been blocked by:** **per-Module drift lint** (freshness check on config validation) — both CJS and SDK config paths would be regenerated from a single source-of-truth schema module, eliminating the silent-drop risk.
|
||||
|
||||
---
|
||||
|
||||
### #2047 — bug: config-set rejects intel.enabled despite being a documented config key
|
||||
- **Drifted:** `intel.enabled` was documented in workflows and gated in runtime code (`intel.cjs:58`), but missing from `VALID_CONFIG_KEYS` in `config.cjs`, so `config-set` rejected it.
|
||||
- **Fix landed:** PR #2021 — added `intel.enabled` to `VALID_CONFIG_KEYS` in CJS.
|
||||
- **Would have been blocked by:** **handsync lint** — linter would enforce that every config key gated in runtime code or documented in workflows must appear in the validator allowlist.
|
||||
|
||||
---
|
||||
|
||||
### #2052 — fix(config): add intel.enabled to VALID_CONFIG_KEYS
|
||||
- **Drifted:** Same as #2047 (missing from allowlist).
|
||||
- **Fix landed:** PR #2021 (same PR as #2047 fix).
|
||||
- **Would have been blocked by:** **handsync lint** — same as #2047.
|
||||
|
||||
---
|
||||
|
||||
### #2638 — bug: loadConfig writes sub_repos to top-level, then warns it's unknown
|
||||
- **Drifted:** After #2561 canonicalized `sub_repos` to `planning.sub_repos`, the legacy migration and filesystem auto-sync in `loadConfig` still wrote to top-level `parsed.sub_repos`, which was then flagged as unknown.
|
||||
- **Fix landed:** PR #2668 — rewrote both paths to target `parsed.planning.sub_repos` and deleted stale top-level copy.
|
||||
- **Would have been blocked by:** **per-Module drift lint** (freshness check for config shape) — the canonical location for `sub_repos` would be codified in a schema, and any code path writing to it would be verified against that schema at lint time.
|
||||
|
||||
---
|
||||
|
||||
### #2655 — fix(core): write sub_repos to planning.sub_repos, not top-level
|
||||
- **Drifted:** Same as #2638.
|
||||
- **Fix landed:** PR #2668 (same as #2638 fix).
|
||||
- **Would have been blocked by:** **per-Module drift lint** — same as #2638.
|
||||
|
||||
---
|
||||
|
||||
### #2653 — bug: SDK config-set rejects documented config keys accepted by CJS config-set
|
||||
- **Drifted:** SDK's `config-mutation.ts` had a hand-maintained `VALID_CONFIG_KEYS` set that had drifted **28 keys** behind CJS's `config-schema.cjs`, so documented commands like `gsd-sdk query config-set planning.sub_repos` were rejected.
|
||||
- **Fix landed:** PR #2670 — extracted shared `sdk/src/query/config-schema.ts` module mirroring CJS exactly; added parity test to fail on future drift.
|
||||
- **Would have been blocked by:** **manifest data isolation** — the config schema would live in one place (e.g., `sdk/shared/config.manifest.json`), and both CJS and SDK would read it, eliminating the possibility of independent drift.
|
||||
|
||||
---
|
||||
|
||||
### #2670 — fix(#2653): eliminate SDK↔CJS config-schema drift
|
||||
- **Drifted:** Same as #2653 (28-key drift).
|
||||
- **Fix landed:** PR #2670 (same as #2653 fix).
|
||||
- **Would have been blocked by:** **manifest data isolation** — same as #2653.
|
||||
|
||||
---
|
||||
|
||||
### #2687 — bug: loadConfig warns on valid dynamic-pattern containers in .planning/config.json
|
||||
- **Drifted:** Keys like `review.models.<cli>` were registered in `config-schema.cjs`'s `DYNAMIC_KEY_PATTERNS` but absent from the hand-maintained `KNOWN_TOP_LEVEL` set in `core.cjs`, causing false-positive "unknown key" warnings.
|
||||
- **Fix landed:** PR #2706 — added `topLevel` field to `DYNAMIC_KEY_PATTERNS` entries; derived `KNOWN_TOP_LEVEL` from schema instead of maintaining it manually.
|
||||
- **Would have been blocked by:** **per-Module drift lint** — the validator that builds `KNOWN_TOP_LEVEL` would be regenerated from the schema each run, not hand-maintained.
|
||||
|
||||
---
|
||||
|
||||
### #2706 — fix(#2687): loadConfig no longer warns on valid dynamic-pattern containers
|
||||
- **Drifted:** Same as #2687 (false warnings on valid dynamic keys).
|
||||
- **Fix landed:** PR #2706 (same as #2687 fix).
|
||||
- **Would have been blocked by:** **per-Module drift lint** — same as #2687.
|
||||
|
||||
---
|
||||
|
||||
### #2798 — context_window missing from VALID_CONFIG_KEYS
|
||||
- **Drifted:** `context_window` was documented in workflows and read in SDK runtime (`init.js:190`, `validate.js:575`), but missing from allowlists in both `config-mutation.ts` and `config-schema.cjs`, so writes were rejected.
|
||||
- **Fix landed:** PR #2816 — added `context_window` to `VALID_CONFIG_KEYS` in both SDK and CJS.
|
||||
- **Would have been blocked by:** **handsync lint** — linter would enforce that every key read at runtime must be in the allowlist.
|
||||
|
||||
---
|
||||
|
||||
### #2816 — fix(#2798): add context_window to VALID_CONFIG_KEYS allowlist
|
||||
- **Drifted:** Same as #2798 (missing from allowlists).
|
||||
- **Fix landed:** PR #2816 (same as #2798 fix).
|
||||
- **Would have been blocked by:** **handsync lint** — same as #2798.
|
||||
|
||||
---
|
||||
|
||||
### #3055 — bug: top-level branching_strategy silently becomes "none"
|
||||
- **Drifted:** `.planning/config.json` with top-level `branching_strategy: "phase"` was flagged as unknown and dropped by validator, causing `loadConfig` to fall back to the `"none"` default, so phase commits landed on the operator's current branch instead of creating `gsd/phase-{N}` branches.
|
||||
- **Fix landed:** PR #3116 — SDK-side only; added legacy normalization in `mergeDefaults()` to graft top-level value into canonical `git.branching_strategy` slot before validation.
|
||||
- **Would have been blocked by:** **per-Module drift lint** — the canonical location for `branching_strategy` would be codified in schema; validator would not strip the value before migrations had a chance to run, or CJS and SDK would share the same migration code.
|
||||
|
||||
---
|
||||
|
||||
### #3116 — fix: normalize legacy top-level branching_strategy into git config
|
||||
- **Drifted:** Same as #3055 (legacy top-level shape not normalized before validator strips it).
|
||||
- **Fix landed:** PR #3116 (SDK-side normalization in `mergeDefaults()`).
|
||||
- **Would have been blocked by:** **per-Module drift lint** — same as #3055, but SDK-side fix would be shared with CJS via seam layer instead of being ported separately.
|
||||
|
||||
---
|
||||
|
||||
### #3523 — bug: CJS loadConfig warns top-level branching_strategy 'will be ignored', but actively reads it
|
||||
- **Drifted:** After PR #3116 fixed the SDK side, the CJS path still emitted false "will be ignored" warnings on the same legacy top-level key, because `KNOWN_TOP_LEVEL` derivation extracted top-level names from `VALID_CONFIG_KEYS` (which contains `'git.branching_strategy'` but not `'branching_strategy'`), and the warning was factually incorrect — `core.cjs:485` does read the legacy value via fallback logic.
|
||||
- **Fix landed:** PR #3527 — added `'branching_strategy'` to the `KNOWN_TOP_LEVEL` hand-maintained list under the deprecated-keys bucket, suppressing the false warning.
|
||||
- **Would have been blocked by:** **runtime-bridge delegation** — if CJS and SDK config loading shared a common normalization routine (via `executeForCjs` or a shared seam module), the SDK fix in #3116 would automatically apply to CJS; no separate CJS-side warning would be possible.
|
||||
|
||||
---
|
||||
|
||||
## Surprises
|
||||
|
||||
None. All 15 bugs are genuine CJS↔SDK schema/validation drift, exactly the class the seam migration prevents.
|
||||
|
||||
## Phase 6 Enforcement Summary
|
||||
|
||||
The seam migration introduces these layers:
|
||||
|
||||
1. **handsync lint** (`scripts/lint-shared-module-handsync.cjs`) — Forbids parallel hand-authored validator modules; catches #1535, #2047, #2798.
|
||||
2. **freshness check** (`sdk/scripts/check-<module>-fresh.mjs`) — Regenerates config validators from schema each run; catches #2687, #3055.
|
||||
3. **manifest data isolation** (`sdk/shared/*.manifest.json`) — Single source-of-truth for schema; catches #2653.
|
||||
4. **per-Module drift lint** — Combination of freshness checks and schema-derived allowlists; catches #2638, #2687, #3055.
|
||||
5. **runtime-bridge delegation** (`executeForCjs` + shared seam modules) — Eliminates parallel CJS/SDK implementations; catches #3523 by preventing separate CJS warning logic.
|
||||
|
||||
Together, these layers eliminate the 15-bug class by enforcing single sources of truth at each decision point.
|
||||
|
||||
---
|
||||
|
||||
## Guide: Adding a new Shared Module
|
||||
|
||||
Use this when you want to extract a new piece of data or logic that both CJS and SDK currently duplicate hand-by-hand. Phase 1's `state-document` migration is the worked example.
|
||||
|
||||
**Step 1 — Create the source-of-truth file**
|
||||
|
||||
```text
|
||||
sdk/src/<module>/index.ts
|
||||
```
|
||||
|
||||
This is the canonical definition. It may export a schema, a set of keys, a type, or a data object. It must not import from CJS or from generated files.
|
||||
|
||||
**Step 2 — Write the generator script**
|
||||
|
||||
```text
|
||||
sdk/scripts/gen-<module>.mjs
|
||||
```
|
||||
|
||||
The generator reads `sdk/src/<module>/index.ts` (or `sdk/shared/<module>.manifest.json` for pure-data manifests), produces a generated output file (either `sdk/src/<module>.generated.ts` or `get-shit-done/bin/lib/<module>.generated.cjs`), and exits 0. It must be idempotent: running it twice produces the same output.
|
||||
|
||||
**Step 3 — Write the freshness check**
|
||||
|
||||
```text
|
||||
sdk/scripts/check-<module>-fresh.mjs
|
||||
```
|
||||
|
||||
The freshness check re-runs the generator into a temp location, diffs against the committed file, and exits 1 with a clear message if they diverge. This is what CI runs.
|
||||
|
||||
**Step 4 — Write the parity test** (optional but recommended)
|
||||
|
||||
```text
|
||||
tests/<module>-parity.test.cjs
|
||||
```
|
||||
|
||||
Assert that the CJS Adapter and the SDK source-of-truth agree on every field that matters (key sets, defaults, schema shape). This test catches generator bugs that the freshness check cannot.
|
||||
|
||||
**Step 5 — Wire CI**
|
||||
|
||||
Add a step in `.github/workflows/test.yml` after the existing freshness-check block (before "Run tests with coverage"), gated on `matrix.os == 'ubuntu-latest' && matrix.node-version == 24`:
|
||||
|
||||
```yaml
|
||||
- name: SDK generated <module> artifact drift check
|
||||
if: matrix.os == 'ubuntu-latest' && matrix.node-version == 24
|
||||
shell: bash
|
||||
run: node sdk/scripts/check-<module>-fresh.mjs
|
||||
```
|
||||
|
||||
**Step 6 — Run inventory regen**
|
||||
|
||||
If the module affects `CONTEXT.md`'s module inventory, update that section. Also update `scripts/shared-module-handsync-allowlist.json`: move any matching entry from `migrateMeBacklog` to `cooperatingSiblings` (or remove it entirely if the CJS hand-copy is now deleted).
|
||||
|
||||
**Step 7 — Update CODEOWNERS**
|
||||
|
||||
Add the new source-of-truth path to `.github/CODEOWNERS` under the Phase 6 block to make the architectural ownership explicit.
|
||||
|
||||
**Reference:** Phase 1 PR [#3531](https://github.com/gsd-build/get-shit-done/pull/3531) — `state-document` migration.
|
||||
|
||||
---
|
||||
|
||||
## Guide: Adding a new canonical command
|
||||
|
||||
Use this when adding a new `gsd-sdk query <family>.<subcommand>` that should be handled natively in the SDK (not delegated to CJS). Phase 5.1's `state.update` migration (PR [#3574](https://github.com/gsd-build/get-shit-done/pull/3574)) is the worked example.
|
||||
|
||||
**Step 1 — Declare in the command manifest**
|
||||
|
||||
Add the command definition to `sdk/src/query/command-manifest.<family>.ts`. Include the full argument schema and a `handler` reference.
|
||||
|
||||
**Step 2 — Implement the SDK handler**
|
||||
|
||||
Write the handler in `sdk/src/query/<subcommand>.ts` (or inline in the manifest file for simple cases). The handler receives validated args and the runtime context; it must not shell out to CJS.
|
||||
|
||||
**Step 3 — Add CJS router delegate (Phase 5.1+ pattern)**
|
||||
|
||||
In the family's CJS command router (e.g. `get-shit-done/bin/lib/state-command-router.cjs`), add a delegate case that calls `executeForCjs(subcommand, args)` from `cjs-command-router-adapter.cjs`. This ensures the CJS binary dispatches to the SDK native handler rather than re-implementing the logic.
|
||||
|
||||
**Step 4 — Add a golden parity test**
|
||||
|
||||
Add a test in `tests/<family>-command-router.test.cjs` (or a new file if the family has no test yet) that:
|
||||
1. Invokes the command via the SDK query path.
|
||||
2. Invokes the command via the CJS router path.
|
||||
3. Asserts both produce identical output.
|
||||
|
||||
This test enforces that the delegate and the native handler stay aligned.
|
||||
|
||||
**Reference:** Phase 5.1 PR [#3574](https://github.com/gsd-build/get-shit-done/pull/3574) — `state.update` delegation.
|
||||
|
||||
---
|
||||
|
||||
## Phase 6 Final Completion Summary
|
||||
|
||||
Phase 6 (issue #3575, PR #3577) is feature-complete. The migration is done.
|
||||
|
||||
**What shipped in Phase 6:**
|
||||
|
||||
- **Shared Modules migrated (5 total in Phase 6):** `plan-scan`, `secrets`, `schema-detect`, `decisions`, `workstream-name-policy`. Each follows the full pattern: SDK source-of-truth, generator (`gen-<name>.mjs`), freshness check (`check-<name>-fresh.mjs`), generated CJS artifact (`<name>.generated.cjs`), CJS shim re-export, parity test, CI step, pre-commit hook, CODEOWNERS entry.
|
||||
- **Workstream native support:** The sync bridge worker now correctly threads `workstream` through to `registry.dispatch()`. `GSDTransport` no longer forces subprocess for workstream-scoped requests. Workstream-scoped state commands execute natively.
|
||||
- **State parity divergences resolved:** `state.record-metric` and `state.prune` SDK handlers now match CJS semantics exactly.
|
||||
- **MIGRATE_ME pairs resolved:** `decisions` and `workstream-name-policy` migrated from `migrateMeBacklog` to `cooperatingSiblings` as ADAPTER-OVER-MODULE.
|
||||
- **Lint final state:** 22 cooperating siblings, 0 backlog pairs.
|
||||
|
||||
**Decisions migration specifics (B1):**
|
||||
- SDK `decisions.ts` regex aligned to CJS: `D-([A-Za-z0-9_-]+)` (alphanumeric IDs like `D-INFRA-01` accepted).
|
||||
- SDK returns richer `{id, text, category, tags, trackable}`; CJS callers using only `{id, text}` safely ignore extras.
|
||||
- Parity test: `tests/decisions-generator.test.cjs` (15 tests covering numeric IDs, alphanumeric IDs, richer schema fields).
|
||||
|
||||
**Workstream-name-policy migration specifics (B2):**
|
||||
- Added `hasInvalidPathSegment` and `isValidActiveWorkstreamName` to SDK `workstream-name-policy.ts`.
|
||||
- `validateWorkstreamName` is now an alias for `isValidActiveWorkstreamName` (consistent with CJS semantics).
|
||||
- Parity test: `tests/workstream-name-policy-generator.test.cjs` (19 tests covering all four exports).
|
||||
|
||||
---
|
||||
|
||||
## Open follow-ups
|
||||
|
||||
No migration items remain. The following are future quality candidates, not defects:
|
||||
|
||||
- **`config.cjs` / `sdk/src/config.ts`** — These files are CJS-CLI-ONLY (per allowlist classification). The `config.cjs` file contains only CLI command handlers that use sync CJS APIs; `sdk/src/config.ts` provides the async SDK layer. They serve disjoint surfaces. A future migration would require converting the CLI handlers to async + SDK patterns, which is a larger refactor out of scope for this migration cycle.
|
||||
- **`intel.cjs` / `sdk/src/query/intel.ts`** — Intentional architectural divergence (different file naming conventions between CJS and SDK; documented in allowlist). A future migration would require reconciling INTEL_FILES naming, which is a breaking change for existing consumers.
|
||||
- **`model-catalog.cjs` / `sdk/src/model-catalog.ts`** — Both sides read from `sdk/shared/model-catalog.json` independently (ADAPTER-OVER-MODULE pattern). This is intentional; the shared JSON is the source-of-truth. No duplication of logic between CJS and SDK consumers.
|
||||
244
docs/discussions/grok-build-support-2026-05.md
Normal file
244
docs/discussions/grok-build-support-2026-05.md
Normal file
@@ -0,0 +1,244 @@
|
||||
# Grok Build + GSD Compatibility & Local Multi-Runtime Sync (May 2026)
|
||||
|
||||
**Date:** 2026-05-16
|
||||
**Status:** Discussion active on closed issue. Awaiting maintainer response.
|
||||
**Purpose of this document:** Serve as the primary context file for future Grok (or other) agent sessions started inside this repository (`/home/cristian/bum/get-shit-done`) so they can work on local Grok Build support and improved synchronization across multiple AI coding harnesses.
|
||||
|
||||
---
|
||||
|
||||
## 1. Executive Summary & Goals
|
||||
|
||||
**Goal:** Achieve reliable, first-class GSD support when using **Grok Build**, while maintaining excellent compatibility and low-friction synchronization across the four runtimes the author uses daily:
|
||||
|
||||
- Grok Build (current primary TUI)
|
||||
- Claude Code
|
||||
- Gemini CLI
|
||||
- Codex
|
||||
|
||||
Currently, Grok Build is only supported via its Claude compatibility layer. This creates daily friction in paths, skill discovery, command surfaces, hooks, `grok inspect` output, and mental models.
|
||||
|
||||
**Long-term vision:**
|
||||
- Run GSD natively and cleanly inside Grok Build.
|
||||
- Maintain a single source of truth in this repository.
|
||||
- Have a robust, automated (or semi-automated) sync mechanism that deploys adapted skills/agents/hooks to all four runtime environments (`~/.agents/`, `~/.claude/`, `~/.grok/`, Gemini location, Codex location).
|
||||
- Keep the work clean enough that high-quality pieces can eventually be contributed upstream.
|
||||
|
||||
---
|
||||
|
||||
## 2. Current Multi-Runtime Setup (as of May 2026)
|
||||
|
||||
### Development Source (Single Source of Truth)
|
||||
- **Path:** `/home/cristian/bum/get-shit-done` (this repo — your working fork of `gsd-build/get-shit-done`)
|
||||
|
||||
### Installed Locations
|
||||
- `~/.agents/get-shit-done/` — Core workflows, references, templates, `gsd-tools.cjs`, `bin/`
|
||||
- `~/.agents/skills/gsd-*` — ~125 skills (heavily GSD + many large reference skills like `userinterface-wiki`, `react-best-practices`, etc.)
|
||||
- `~/.agents/agents/` — 22 GSD sub-agents (with `.md` + `.toml`)
|
||||
- `~/.claude/skills/gsd-*` + `~/.claude/get-shit-done/` + `~/.claude/agents/` — Parallel Claude Code install (~208 skills total)
|
||||
- `~/.grok/skills/` — Mostly empty (only the 7 official bundled Grok skills)
|
||||
- `~/.grok/` — Not yet properly used by GSD
|
||||
|
||||
### Existing Sync Tooling
|
||||
- `gsd-sync-skills` skill exists in `~/.agents/skills/gsd-sync-skills/`
|
||||
- Its stated purpose: "Sync managed GSD skills across runtime roots so multi-runtime users stay aligned after an update"
|
||||
- Currently uses a combination of manual processes + this skill.
|
||||
|
||||
### Codex-Style Adaptations Already in Use
|
||||
- Many `gsd-*` skills in `~/.agents/skills/` contain a `<codex_skill_adapter>` section at the top.
|
||||
- This adapter translates Claude Code patterns (`AskUserQuestion`, `Task()`) into Codex/Grok-compatible ones (`request_user_input`, `spawn_agent`).
|
||||
- This pattern was developed because Grok Build / Codex use a different skill invocation and subagent model than Claude Code.
|
||||
|
||||
---
|
||||
|
||||
## 3. History & Prior Art
|
||||
|
||||
### Previous Upstream Attempt (May 2026)
|
||||
- **Issue #3603**: "Add Grok Build (`--grok`) as a first-class runtime"
|
||||
- **PR #3604** (by `lordgraysith`): Very large, high-quality implementation attempt.
|
||||
|
||||
The PR included:
|
||||
- Full `--grok` installer support
|
||||
- Conversion functions (`convertClaudeToGrokMarkdown`, `convertClaudeCommandToGrokSkill`, `convertClaudeAgentToGrokAgent`)
|
||||
- JSON hook manifest generation for Grok
|
||||
- Model catalog entries for Grok models
|
||||
- `GROK_CONFIG_DIR` support
|
||||
- Extensive tests and documentation
|
||||
- A complete planning folder: `docs/grok-build-support/` containing 7 detailed documents:
|
||||
- 01-runtime-detection-and-config.md
|
||||
- 02-installer-logic.md
|
||||
- 03-model-catalog-and-profiles.md
|
||||
- 04-skills-agents-hooks-conversion.md
|
||||
- 05-documentation-and-user-experience.md
|
||||
- 06-testing-strategy.md
|
||||
- 07-phased-implementation-and-rollout.md
|
||||
|
||||
**Outcome:** Both issue and PR were closed the next day by `trek-e` as `not_planned`.
|
||||
|
||||
### Maintainer’s Position (Critical Context)
|
||||
From `trek-e`’s detailed closing comment on #3603:
|
||||
|
||||
- **Biggest blockers right now:**
|
||||
- Grok Build is extremely new (launched May 14, 2026) and still in early beta. Hook events and config surface are unstable.
|
||||
- Strong desire to protect GSD’s reputation for stability ("vibe coded piece of junk" reputation risk).
|
||||
- Recent painful experience with Codex making breaking changes shortly after GSD stabilized something.
|
||||
- **Price was clarified as low priority** ("honestly price is probably the lowest of the factors").
|
||||
- **Claude-compat already works**, so native support is seen as polish rather than a must-have.
|
||||
- **Process concern:** Implementation was done before the issue was properly approved.
|
||||
- **Recommendation:** Revisit once Grok Build has stabilized (versioned config surface held for at least one minor release) **and** is reachable on a more realistic solo-dev price tier.
|
||||
|
||||
**Important:** The 7 planning documents in `docs/grok-build-support/` remain excellent reference material even if the code from that PR is not merged.
|
||||
|
||||
---
|
||||
|
||||
## 4. Recommended Work Plan for Future Grok Sessions in This Repo
|
||||
|
||||
When a new Grok session is started inside `/home/cristian/bum/get-shit-done`, it should follow something like this phased approach:
|
||||
|
||||
### Phase 0 — Orientation (Current Session Context)
|
||||
- Read this document fully.
|
||||
- Read the 7 files in `docs/grok-build-support/`.
|
||||
- Explore the current local multi-runtime setup (see Section 2 above).
|
||||
- Understand the existing `gsd-sync-skills` skill and any Codex adapters already present.
|
||||
|
||||
### Phase 1 — Audit Current State
|
||||
- Map exactly what is installed where across `~/.agents/`, `~/.claude/`, `~/.grok/`, and Gemini/Codex locations.
|
||||
- Identify duplication, drift, and friction points when using GSD in Grok Build today.
|
||||
- Run `grok inspect` and analyze what it shows for GSD skills.
|
||||
- Document gaps specific to Grok Build (command surface, hooks, `grok inspect` cleanliness, agent spawning, etc.).
|
||||
|
||||
### Phase 2 — Study Prior Art
|
||||
- Deeply study the conversion specifications in `docs/grok-build-support/04-skills-agents-hooks-conversion.md`.
|
||||
- Understand what a proper Grok `SKILL.md` should look like (frontmatter, description style, runtime hints).
|
||||
- Understand Grok hook JSON manifest requirements.
|
||||
- Review how the previous PR handled model catalog and runtime homes.
|
||||
- Look for any existing local experiments or partial adapters in this fork.
|
||||
|
||||
### Phase 3 — Design Local Grok Adapter (MVP)
|
||||
Design a practical local solution that works for **this user’s four-runtime reality**, not necessarily a full upstream `--grok` installer yet.
|
||||
|
||||
Possible components:
|
||||
- A local Grok conversion layer (or extension of existing Codex adapters).
|
||||
- Proper `gsd-*` skills under `~/.grok/skills/` with correct Grok frontmatter + `codex_skill_adapter` sections where needed.
|
||||
- Grok-compatible agent definitions (`.md` + any required TOML/config).
|
||||
- JSON hook manifests in `~/.grok/hooks/`.
|
||||
- Updates to the sync mechanism (`gsd-sync-skills` or a new `gsd-multi-runtime-sync` tool) so one source can deploy cleanly to all four targets.
|
||||
|
||||
**Key principle:** Prefer extending/improving the existing sync tooling rather than creating yet another parallel install path.
|
||||
|
||||
### Phase 4 — Implementation & Testing
|
||||
- Implement the MVP Grok adapter in this local fork.
|
||||
- Create or enhance sync logic.
|
||||
- Test end-to-end inside an actual Grok Build session:
|
||||
- `grok inspect` cleanliness
|
||||
- Command discovery (`/gsd-*` or Grok-native form)
|
||||
- Agent spawning
|
||||
- Hook firing
|
||||
- Full `gsd-new-project` → `gsd-progress` → `gsd-execute-phase` flow
|
||||
- Verify no regression in Claude / Gemini / Codex usage.
|
||||
|
||||
### Phase 5 — Documentation & Future Upstream Path
|
||||
- Update this discussion note and any relevant docs in the repo.
|
||||
- Document the local sync architecture clearly.
|
||||
- Identify which pieces of the local solution would be good candidates for upstream contribution later (when Grok Build is more mature).
|
||||
|
||||
---
|
||||
|
||||
## 5. Key Files & Areas to Study
|
||||
|
||||
**In this repo:**
|
||||
- `docs/grok-build-support/` (all 7 documents — highest priority)
|
||||
- `bin/install.js` (installer logic, especially runtime handling and conversion functions)
|
||||
- `get-shit-done/bin/lib/runtime-homes.cjs`
|
||||
- `get-shit-done/bin/lib/shell-command-projection.cjs` (hook projection)
|
||||
- `sdk/shared/model-catalog.json`
|
||||
- Existing `gsd-sync-skills` skill (in `~/.agents/skills/gsd-sync-skills/`)
|
||||
- Any skills that already contain `<codex_skill_adapter>` sections (study the pattern)
|
||||
|
||||
**External / Prior Art:**
|
||||
- The original PR #3604 (study the actual conversion code if accessible via the author’s fork)
|
||||
- Grok Build documentation on skill format, agent format, and hook JSON manifests (as of the session date)
|
||||
|
||||
---
|
||||
|
||||
## 6. How to Test Grok Build Compatibility Locally
|
||||
|
||||
Useful commands and checks when working on this:
|
||||
|
||||
- `grok inspect` (and `grok inspect --json`) — check skill discovery, sources, and token counts.
|
||||
- `grok` TUI inside a real project that uses GSD.
|
||||
- Full workflow test: `/gsd-progress`, `/gsd-discuss-phase`, `/gsd-plan-phase`, `/gsd-execute-phase`, etc.
|
||||
- Verify hooks fire correctly via Grok’s JSON hook system.
|
||||
- Check that subagents (the 22 GSD agents in `~/.agents/agents/`) can be spawned from Grok.
|
||||
|
||||
---
|
||||
|
||||
## 7. Sync Strategy Principles (for Multi-Runtime)
|
||||
|
||||
When designing improvements to sync:
|
||||
|
||||
- Single source of truth = this repository (`/home/cristian/bum/get-shit-done`).
|
||||
- Runtime-specific transformations should be as declarative and maintainable as possible.
|
||||
- The `<codex_skill_adapter>` pattern is already proven for Grok/Codex — extend it rather than reinvent.
|
||||
- Prefer generating the runtime-specific artifacts during sync rather than maintaining four separate copies.
|
||||
- Make it easy to add a fifth runtime later if needed.
|
||||
|
||||
---
|
||||
|
||||
## 8. Open Questions & Decisions to Make (for Future Sessions)
|
||||
|
||||
- Should we aim for a full local `--grok` installer equivalent, or just excellent skill/agent/hook generation + sync?
|
||||
- How much of the previous PR’s conversion logic can/should be reused locally?
|
||||
- What is the right balance between “make Grok work great for me now” vs “keep it clean for potential upstream contribution”?
|
||||
- Should the sync tool become a first-class GSD skill (`gsd-multi-runtime-sync` or similar)?
|
||||
- How do we handle model profiles and agent routing differences for Grok models?
|
||||
|
||||
---
|
||||
|
||||
## 9. How to Resume This Work
|
||||
|
||||
When starting a new Grok session in this repository, begin by reading:
|
||||
|
||||
1. This file: `docs/discussions/grok-build-support-2026-05.md`
|
||||
2. All files in `docs/grok-build-support/`
|
||||
3. The existing `gsd-sync-skills` skill
|
||||
|
||||
Then follow the phased plan in Section 4.
|
||||
|
||||
---
|
||||
|
||||
**Last updated:** 2026-05-16 (by Grok, in this session)
|
||||
|
||||
---
|
||||
|
||||
## 10. Progress — May 2026 Session (Current)
|
||||
|
||||
### Audit Findings (Phase 1)
|
||||
- **Version drift confirmed**: `~/.agents/get-shit-done/` (Grok Build primary) was on 1.38.4; `~/.claude/` on 1.42.2; `~/.codex/` and `~/.gemini/` on 1.41.2.
|
||||
- `~/.agents/hooks/` was empty (no hooks active for Grok Build sessions).
|
||||
- `grok inspect` successfully discovers 80+ `gsd-*` skills via the `~/.agents/skills/` layout + the existing `<codex_skill_adapter>` blocks.
|
||||
- No `grok` or `agents` runtime existed in installer or sync logic.
|
||||
- `~/.grok/` itself contains only the 7 official bundled skills; GSD lives entirely in the shared `~/.agents/` layout.
|
||||
|
||||
### Immediate Actions Taken
|
||||
- **Engine drift fixed ASAP**: Backed up old `~/.agents/get-shit-done/` to `.backup-1.38.4/`, then rsynced the current source `get-shit-done/` tree into `~/.agents/get-shit-done/`. Now running the latest from this repo (v1.50.0-canary.0). New modules (active-workstream-store, adr-parser, etc.) and updated workflows are live for Grok Build sessions.
|
||||
- **First-class 'grok' runtime added** (pragmatic choice: maps to `~/.agents/`):
|
||||
- [get-shit-done/bin/lib/runtime-homes.cjs](/home/cristian/bum/get-shit-done/get-shit-done/bin/lib/runtime-homes.cjs): Added `grok` case (honors `GROK_AGENTS_HOME` env, defaults to `~/.agents`).
|
||||
- [bin/install.js](/home/cristian/bum/get-shit-done/bin/install.js): Added `--grok` flag, `hasGrok`, `getDirName('grok') → '.agents'`, `getGlobalDir('grok')`, `getConfigDirFromHome`, inclusion in `--all` and help text. Reuses existing Codex conversion logic (skill adapters + agent .toml generation) because Grok Build uses the same invocation model.
|
||||
- [get-shit-done/workflows/sync-skills.md](/home/cristian/bum/get-shit-done/get-shit-done/workflows/sync-skills.md): Added `grok` to supported runtimes and the `--to all` list.
|
||||
- Verified: `node bin/install.js --skills-root grok` correctly returns `~/.agents/skills`.
|
||||
|
||||
### Next Steps (for follow-up sessions)
|
||||
- Full `gsd install --grok --global` end-to-end (hook projection, agent .toml generation with correct sandbox, skill wrapping with adapters, statusline, etc.). Currently the flag is recognized but some codex-specific install branches may need `|| runtime === 'grok'`.
|
||||
- Run `gsd update --sync --from claude --to grok --apply` (or `--from grok --to claude`) once the runtime is fully wired, to keep the 4 harnesses in sync without manual rsync.
|
||||
- Slim the `<codex_skill_adapter>` blocks (currently ~60 lines inlined in every gsd-* SKILL.md). Options: extract detailed mapping to a shared `@reference/codex-skill-adapter.md` that skills include, or make the adapter header shorter/optional for lower `grok inspect` token cost.
|
||||
- Investigate Grok Build native hook support (JSON manifests under `~/.grok/hooks/` vs the shell hooks in `~/.agents/hooks/`).
|
||||
- Update `grok inspect` output cleanliness (remove "unknown tool prefix: Skill(gsd:*)" warnings if possible via settings or skill manifest).
|
||||
- Consider whether to also populate a native `~/.grok/skills/gsd-*` tree in addition to the working `.agents` layout.
|
||||
|
||||
This session delivered working `grok` runtime resolution + immediate version parity for the user's primary Grok Build harness.
|
||||
|
||||
---
|
||||
|
||||
**Last updated:** 2026-05-16 (by Grok, in this session)
|
||||
|
||||
This document is intended to be living. Update it as the local Grok Build work progresses.
|
||||
Reference in New Issue
Block a user