@tekyzinc/gsd-t 3.16.12 → 3.18.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/README.md +13 -3
  3. package/bin/gsd-t-depgraph-validate.cjs +140 -0
  4. package/bin/gsd-t-economics.cjs +287 -0
  5. package/bin/gsd-t-file-disjointness.cjs +227 -0
  6. package/bin/gsd-t-in-session-usage.cjs +213 -0
  7. package/bin/gsd-t-orchestrator-config.cjs +100 -3
  8. package/bin/gsd-t-orchestrator.js +2 -1
  9. package/bin/gsd-t-parallel.cjs +382 -0
  10. package/bin/gsd-t-report-tokens.cjs +549 -0
  11. package/bin/gsd-t-task-graph.cjs +366 -0
  12. package/bin/gsd-t-token-capture.cjs +29 -14
  13. package/bin/gsd-t-token-dashboard.cjs +35 -0
  14. package/bin/gsd-t-tool-attribution.cjs +377 -0
  15. package/bin/gsd-t-tool-cost.cjs +195 -0
  16. package/bin/gsd-t-unattended-platform.cjs +7 -1
  17. package/bin/gsd-t-unattended.cjs +2 -0
  18. package/bin/gsd-t.js +155 -5
  19. package/bin/headless-auto-spawn.cjs +69 -49
  20. package/bin/headless-auto-spawn.js +18 -24
  21. package/bin/runway-estimator.cjs +212 -0
  22. package/bin/spawn-plan-derive.cjs +163 -0
  23. package/bin/spawn-plan-status-updater.cjs +292 -0
  24. package/bin/spawn-plan-writer.cjs +204 -0
  25. package/commands/gsd-t-debug.md +26 -7
  26. package/commands/gsd-t-execute.md +36 -28
  27. package/commands/gsd-t-help.md +11 -0
  28. package/commands/gsd-t-integrate.md +27 -7
  29. package/commands/gsd-t-quick.md +30 -13
  30. package/commands/gsd-t-scan.md +5 -5
  31. package/commands/gsd-t-unattended-watch.md +4 -3
  32. package/commands/gsd-t-unattended.md +9 -3
  33. package/commands/gsd-t-verify.md +5 -5
  34. package/commands/gsd-t-wave.md +21 -8
  35. package/commands/gsd.md +45 -3
  36. package/docs/GSD-T-README.md +43 -5
  37. package/docs/architecture.md +423 -3
  38. package/docs/requirements.md +203 -0
  39. package/package.json +1 -1
  40. package/scripts/gsd-t-calibration-hook.js +256 -0
  41. package/scripts/gsd-t-compact-detector.js +223 -0
  42. package/scripts/gsd-t-compaction-scanner.js +305 -0
  43. package/scripts/gsd-t-dashboard-autostart.cjs +172 -0
  44. package/scripts/gsd-t-dashboard-server.js +179 -0
  45. package/scripts/gsd-t-heartbeat.js +50 -2
  46. package/scripts/gsd-t-post-commit-spawn-plan.sh +86 -0
  47. package/scripts/gsd-t-transcript.html +546 -43
  48. package/scripts/hooks/gsd-t-in-session-usage-hook.js +84 -0
  49. package/scripts/spawn-plan-fmt-tokens.cjs +80 -0
  50. package/templates/CLAUDE-global.md +8 -3
  51. package/templates/CLAUDE-project.md +17 -14
  52. package/templates/hooks/post-commit-spawn-plan.sh +85 -0
@@ -4,16 +4,16 @@ You are the wave orchestrator. You do NOT execute phases yourself. Instead, you
4
4
 
5
5
  ## Argument Parsing
6
6
 
7
- Parse `$ARGUMENTS`. Detect `--watch` (sets `WATCH_FLAG=true`; default `false`). Per `.gsd-t/contracts/headless-default-contract.md` §2, `--watch` propagates to **primary** phase-agent spawns only. Validation spawns (doc-ripple in Step 7) always go headless regardless of the flag.
7
+ Parse `$ARGUMENTS`. M43 D4 removed `--watch`; `--in-session`/`--headless` were never shipped. Under `.gsd-t/contracts/headless-default-contract.md` **v2.0.0** every phase-agent spawn goes headless unconditionally. A legacy `--watch` token in `$ARGUMENTS` is accepted but ignored (one-line stderr deprecation warning from the spawn primitive).
8
8
 
9
- ## Spawn Primitive — Default Headless (M38 Domain 1)
9
+ ## Spawn Primitive — Always Headless (M43 D4, v2.0.0)
10
10
 
11
- Per `.gsd-t/contracts/headless-default-contract.md` v1.0.0. Spawn classifications used below:
11
+ Per `.gsd-t/contracts/headless-default-contract.md` v2.0.0. Spawn classifications (kept for logging only — both always headless):
12
12
 
13
13
  - `spawnType: 'primary'` — per-phase agents (partition, discuss, plan, impact, execute, test-sync, integrate, verify+complete)
14
14
  - `spawnType: 'validation'` — post-phase spot-checks, doc-ripple agent
15
15
 
16
- Default path is `autoSpawnHeadless({command, spawnType, watch: WATCH_FLAG, projectDir, sessionContext})` with the read-back banner surfacing completion. When `WATCH_FLAG=true` AND `spawnType='primary'`, `autoSpawnHeadless` returns `{mode:'in-context'}` and the orchestrator falls back to the in-context Task-agent pattern documented inline.
16
+ Spawn path is `autoSpawnHeadless({command, spawnType, projectDir, sessionContext})` with the read-back banner surfacing completion.
17
17
 
18
18
  ## Model Assignment
19
19
 
@@ -35,7 +35,7 @@ Run via Bash:
35
35
  node -e "const tb = require('./bin/token-budget.cjs'); const s = tb.getSessionStatus('.'); console.log(JSON.stringify(s));"
36
36
  ```
37
37
 
38
- This calls `getSessionStatus()` which reads `.gsd-t/.context-meter-state.json` produced by the Context Meter PostToolUse hook. The returned `threshold` is `normal` or `threshold` (single-band model per `context-meter-contract.md` v1.3.0) and drives the gate logic in the Phase Agent Spawn Pattern below. When the state file is absent, `getSessionStatus()` returns `{pct: 0, threshold: 'normal'}`. `thresholdPct` (default `75`) and `modelWindowSize` are configured in `.gsd-t/context-meter-config.json`.
38
+ This calls `getSessionStatus()` which reads `.gsd-t/.context-meter-state.json` produced by the Context Meter PostToolUse hook. The returned `{pct, threshold}` is captured for the NEXT spawn's token-log Ctx% column — under headless-default-contract v2.0.0 the `threshold` band does NOT drive the spawn decision; every phase agent goes through `autoSpawnHeadless()` unconditionally. When the state file is absent, `getSessionStatus()` returns `{pct: 0, threshold: 'normal'}`. `thresholdPct` (default `75`) and `modelWindowSize` are configured in `.gsd-t/context-meter-config.json`.
39
39
 
40
40
  ## Step 1: Load State (Lightweight)
41
41
 
@@ -175,8 +175,7 @@ node -e "const tb=require('./bin/token-budget.cjs'); const s=tb.getSessionStatus
175
175
  The JSON on stdout contains `{pct, threshold}` where `threshold` is `normal` or `threshold` (single-band model per `context-meter-contract.md` v1.3.0).
176
176
 
177
177
  Handling:
178
- - `threshold === 'normal'` proceed to the next phase.
179
- - `threshold === 'threshold'` → the Context Meter's PostToolUse hook has already emitted the `next-spawn-headless:true` marker; the orchestrator routes subsequent subagent spawns through `autoSpawnHeadless()`. No manual checkpoint/halt — the meter + spawn primitive together handle handoff.
178
+ Capture `pct` for the next spawn's Ctx% log field. The `threshold` field is observational under headless-default-contract v2.0.0 — every spawn routes through `autoSpawnHeadless()` unconditionally, so the band does not gate phase progression.
180
179
 
181
180
  ### Phase Sequence
182
181
 
@@ -211,6 +210,20 @@ Spawn agent → `commands/gsd-t-impact.md`
211
210
  #### 5. EXECUTE
212
211
  Spawn agent → `commands/gsd-t-execute.md`
213
212
  - This is the heaviest phase. The execute agent uses **task-level dispatch** (fresh-dispatch-contract.md): one Task subagent per task within each domain, each receiving only scope.md + relevant contracts + single task + graph context + up to 5 prior summaries. The execute agent handles domain task-dispatching and QA internally.
213
+
214
+ ##### Optional — Parallel Dispatch (M44)
215
+
216
+ The spawned execute agent will itself decide whether to dispatch parallel workers via `gsd-t parallel` (see `commands/gsd-t-execute.md` Step 3 → "Optional — Parallel Dispatch (M44)"). The wave orchestrator does not need to configure this — it is automatic:
217
+
218
+ - If `.gsd-t/domains/` contains more than one pending task passing D4/D5/D6 gates, the execute agent dispatches via `gsd-t parallel` instead of sequentially.
219
+ - Mode is auto-detected from `GSD_T_UNATTENDED=1` — the wave orchestrator inherits this env from its own spawn. Do not hardcode `--mode`.
220
+ - Fallback is silent: any gate veto, unprovable disjointness, or single-task scope drops back to the sequential execute path without a user prompt.
221
+ - D2 owns the spawn observability; the parallel path writes the same `.gsd-t/events/YYYY-MM-DD.jsonl` records and `.gsd-t/token-log.md` rows as the sequential path via `captureSpawn`. D3 adds no new spawn machinery.
222
+ - `[unattended]` — D2 enforces the zero-compaction contract by splitting tasks when D6 estimates per-worker CW > 60%.
223
+ - `[in-session]` — NEVER interrupts the user with pause/resume. If headroom is tight, D2 reduces the worker count (floor N=1) and emits `parallelism_reduced`.
224
+
225
+ No wave-orchestrator-level flag exists to opt out; the parallel-vs-sequential decision is owned by the execute agent and the D2 gating math. Contract: `.gsd-t/contracts/wave-join-contract.md` v1.1.0.
226
+
214
227
  - **Adaptive replanning**: After each domain completes, the execute agent runs a replan check (per `adaptive-replan-contract.md`). If a completed domain's task summaries reveal new constraints (e.g., deprecated API, wrong column name, incompatible library), the execute agent checks remaining domains' `tasks.md` files for invalidated assumptions and revises them on disk before dispatching the next domain. Maximum 2 replan cycles per execute run — if exceeded, execution pauses for user input. All replan decisions are logged to the Decision Log in `progress.md`. The wave phase summary includes any replan actions taken.
215
228
  - **Team/parallel mode**: If the plan defines parallel domains (same wave), the execute agent dispatches each domain teammate with `isolation: "worktree"` (per worktree-isolation-contract.md). Each domain works in an isolated git worktree. After all domains complete, the execute agent runs the Sequential Merge Protocol: merge domain A → test → merge domain B → test. Per-domain rollback if tests fail. Worktrees are cleaned up after all merges complete.
216
229
  - After: Read `progress.md`, verify status = EXECUTED. Phase summary must include replan actions if any occurred:
@@ -246,7 +259,7 @@ After the final phase completes but before wave reports done:
246
259
 
247
260
  1. Run threshold check — read `git diff --name-only HEAD~1` and evaluate against doc-ripple-contract.md trigger conditions
248
261
  2. If SKIP: log "Doc-ripple: SKIP — {reason}" and proceed
249
- 3. If FIRE: spawn doc-ripple agent — `spawnType: 'validation'` (always headless, `--watch` ignored):
262
+ 3. If FIRE: spawn doc-ripple agent — `spawnType: 'validation'` (always headless per headless-default-contract v2.0.0):
250
263
 
251
264
  ⚙ [{model}] gsd-t-doc-ripple → blast radius analysis + parallel updates
252
265
 
package/commands/gsd.md CHANGED
@@ -26,7 +26,9 @@ Before semantic evaluation, determine if this is a **continuation** of an alread
26
26
 
27
27
  ## Step 2.5: Intent Classification
28
28
 
29
- For non-continuation messages, decide whether the request is **conversational** (user is thinking, exploring, or articulating no command spawn) or **workflow** (user wants work done route to a GSD-T command via Step 2).
29
+ > **Inverted default (M43 D4, v2.0.0)** the only in-session surface in GSD-T is this router itself, and only for dialog-only (exploratory) turns. Every **workflow** turn spawns a detached command unconditionally. There is no `--in-session` flag, no `--headless` flag, no context-meter threshold that reroutes. See `.gsd-t/contracts/headless-default-contract.md` v2.0.0 §Invariants.
30
+
31
+ For non-continuation messages, decide whether the request is **conversational** (user is thinking, exploring, or articulating — no command spawn; stays in the dialog channel) or **workflow** (user wants work done — route to a GSD-T command via Step 2; **always spawns detached**).
30
32
 
31
33
  This step replaces the retired `/gsd-t-prompt`, `/gsd-t-brainstorm`, and `/gsd-t-discuss` commands, whose use cases the router now handles inline.
32
34
 
@@ -41,12 +43,12 @@ This step replaces the retired `/gsd-t-prompt`, `/gsd-t-brainstorm`, and `/gsd-t
41
43
 
42
44
  ### Workflow triggers (proceed to Step 2 semantic evaluation):
43
45
 
44
- - Direct task requests: "fix", "add", "implement", "refactor", "ship", "build", "delete", "rename"
46
+ - Direct task requests / action verbs: "fix", "add", "implement", "refactor", "ship", "build", "run", "execute", "deploy", "delete", "rename"
45
47
  - Named artifacts: "run the tests", "scan the codebase", "verify the milestone", "status"
46
48
  - Design-to-code requests (see Step 2 design-to-code routing)
47
49
  - Anything where the user expects files to change or a command to run
48
50
 
49
- **Action for workflow triggers**: proceed to Step 2.
51
+ **Action for workflow triggers**: proceed to Step 2 — which then spawns detached unconditionally (v2.0.0 invariant).
50
52
 
51
53
  ### Default
52
54
 
@@ -218,4 +220,44 @@ I'll route to the right GSD-T command — or just think out loud with you
218
220
  if you're still figuring things out (no command spawn).
219
221
  ```
220
222
 
223
+ ## Step 5: Dialog-Channel Growth Warning (M43 D5)
224
+
225
+ After you've finished your response text (routing header + any conversational body + any command invocation), check whether dialog growth is trending toward `/compact` and, if so, append a one-line warning footer. This is a pure read/warn signal — it never refuses, never reroutes, never blocks.
226
+
227
+ ### When to check
228
+
229
+ - Always — every router turn ends with this check. Cost is a single JSONL read of `.gsd-t/metrics/token-usage.jsonl`.
230
+
231
+ ### How to check
232
+
233
+ Run the following (substitute the current session id; `$CLAUDE_SESSION_ID` works in most shells, otherwise fall back to the most recent `sessionType: "in-session"` session in the sink):
234
+
235
+ ```
236
+ node -e "
237
+ const { estimateDialogGrowth } = require('./bin/runway-estimator.cjs');
238
+ const r = estimateDialogGrowth({
239
+ projectDir: '.',
240
+ sessionId: process.env.CLAUDE_SESSION_ID || '',
241
+ });
242
+ if (r.shouldWarn) {
243
+ const n = r.predicted_turns_to_compact;
244
+ const k = r.k;
245
+ const d = Math.round(r.median_delta);
246
+ console.log('> ⚠ Dialog pressure: ~' + n + ' turns to /compact (last K=' + k + ' turns, growth ~' + d + '/turn).');
247
+ console.log('> Consider spawning the next action detached (\`/gsd ... --detach\`) or running \`/compact\` now.');
248
+ }
249
+ "
250
+ ```
251
+
252
+ ### What to emit
253
+
254
+ If the node call prints nothing (growth flat, insufficient history, no session, etc.), emit nothing. Otherwise append the printed block verbatim as the last lines of your response. It MUST render as a blockquote — two lines, starting with `> ⚠`. Never reformat it, never prepend explanation, never turn it into a modal or a `/clear` command.
255
+
256
+ ### What NOT to do
257
+
258
+ - Do NOT refuse or defer the user's request based on this signal.
259
+ - Do NOT silently route to a different command because of growth.
260
+ - Do NOT emit the warning more than once per turn.
261
+ - Do NOT write to any file from this step — it is pure read + footer print.
262
+
221
263
  $ARGUMENTS
@@ -101,12 +101,12 @@ GSD-T reads all state files and tells you exactly where you left off.
101
101
  | `/gsd-t-discuss` | Multi-perspective design exploration | In wave |
102
102
  | `/gsd-t-plan` | Create atomic task lists per domain (tasks auto-split to fit one context window) | In wave |
103
103
  | `/gsd-t-impact` | Analyze downstream effects | In wave |
104
- | `/gsd-t-execute` | Run tasks — task-level fresh dispatch, worktree isolation, adaptive replanning, stack rules injection | In wave |
104
+ | `/gsd-t-execute` | Run tasks — task-level fresh dispatch, worktree isolation, adaptive replanning, stack rules injection. M44 (D3): conditionally dispatches >1 gate-passing task via `gsd-t parallel`; single-task or veto falls back to sequential silently. | In wave |
105
105
  | `/gsd-t-test-sync` | Sync tests with code changes | In wave |
106
106
  | `/gsd-t-qa` | QA agent — test generation, execution, gap reporting | Auto-spawned |
107
107
  | *Red Team* | Adversarial QA — spawns after QA passes to find bugs the builder missed | Auto-spawned |
108
108
  | `/gsd-t-doc-ripple` | Automated document ripple — update downstream docs after code changes | Auto-spawned |
109
- | `/gsd-t-integrate` | Wire domains together | In wave |
109
+ | `/gsd-t-integrate` | Wire domains together. M44 (D3): conditionally dispatches multi-domain integration tasks via `gsd-t parallel`; single-domain wiring unchanged. | In wave |
110
110
  | `/gsd-t-verify` | Run quality gates + goal-backward verification → auto-invokes complete-milestone | In wave |
111
111
  | `/gsd-t-complete-milestone` | Archive + git tag (auto-invoked by verify, also standalone) | In wave |
112
112
 
@@ -117,12 +117,12 @@ GSD-T reads all state files and tells you exactly where you left off.
117
117
  | `/gsd-t-unattended` | Launch detached supervisor — runs active milestone to completion with zero human intervention | Manual |
118
118
  | `/gsd-t-unattended-watch` | Watch tick — fires every 270s via ScheduleWakeup, reports supervisor status | Auto |
119
119
  | `/gsd-t-unattended-stop` | Touch stop sentinel — supervisor halts after current worker finishes | Manual |
120
- | `/gsd-t-wave` | Full cycle, auto-advances all phases | Manual |
120
+ | `/gsd-t-wave` | Full cycle, auto-advances all phases. M44 (D3): EXECUTE phase inherits parallel dispatch from execute agent; no wave-level flag needed — mode auto-detected from `GSD_T_UNATTENDED`. | Manual |
121
121
  | `/gsd-t-status` | Cross-domain progress view with token breakdown, global ELO and cross-project rankings | Manual |
122
122
  | `/gsd-t-resume` | Restore context, continue | Manual |
123
- | `/gsd-t-quick` | Fast task with GSD-T guarantees | Manual |
123
+ | `/gsd-t-quick` | Fast task with GSD-T guarantees. M44 (D3): lightweight — conditional parallel dispatch only when >1 pending task AND all gates pass; single-task (the common case) runs sequentially unchanged. | Manual |
124
124
  | `/gsd-t-visualize` | Launch browser dashboard — SSE server + React Flow agent visualization | Manual |
125
- | `/gsd-t-debug` | Systematic debugging with state | Manual |
125
+ | `/gsd-t-debug` | Systematic debugging with state. M44 (D3): conditional parallel dispatch only for multi-domain contract-boundary/gap debug sessions; single-domain debug runs sequentially unchanged. | Manual |
126
126
  | `/gsd-t-metrics` | View task telemetry, process ELO, signal distribution, domain health, and cross-project comparison (`--cross-project`) | Manual |
127
127
  | `/gsd-t-health` | Validate .gsd-t/ structure, optionally repair | Manual |
128
128
  | `/gsd-t-pause` | Save exact position for reliable resume | Manual |
@@ -351,6 +351,44 @@ gsd-t headless --debug-loop [--max-iterations=N] [--test-cmd=CMD] [--fix-scope=P
351
351
 
352
352
  ---
353
353
 
354
+ ## Parallel CLI (M44)
355
+
356
+ Run task-level parallel workers with mode-aware gating (D4 depgraph → D5 file-disjointness → D6 economics + headroom/split).
357
+
358
+ ```bash
359
+ gsd-t parallel --help # Usage, flags, gates, contract ref
360
+ gsd-t parallel --dry-run # Plan table + worker count + mode (no spawn)
361
+ gsd-t parallel --mode in-session --dry-run # 85% orchestrator-CW ceiling; N=1 floor
362
+ gsd-t parallel --mode unattended --dry-run # 60% per-worker ceiling; > 60% → task_split
363
+ gsd-t parallel --milestone M44 --domain m44-d2-parallel-cli --dry-run
364
+ ```
365
+
366
+ **Flags:**
367
+
368
+ | Flag | Default | Description |
369
+ |------|---------|-------------|
370
+ | `--mode in-session\|unattended` | auto | auto-detect: `GSD_T_UNATTENDED=1` → unattended, else in-session. Explicit flag overrides env. |
371
+ | `--milestone Mxx` | active | Milestone filter |
372
+ | `--domain <name>` | all | Domain filter |
373
+ | `--dry-run` | false | Print plan table + exit; never spawns workers |
374
+ | `--help / -h` | — | Usage + flags + gates |
375
+
376
+ **Three upstream gates** (strict sequence before any fan-out):
377
+ 1. **D4 depgraph validation** — every task's `Dependencies:` must be `done`; otherwise `gate_veto{gate:"deps"}` → sequential.
378
+ 2. **D5 file-disjointness** — tasks' `Touches:` sets must have empty intersection; overlap → `gate_veto{gate:"disjointness"}` for every pair (both sequential).
379
+ 3. **D6 economics estimator** — per-task CW footprint prediction from the token-usage corpus; informs but never vetoes on its own.
380
+
381
+ **Mode-aware final gate:**
382
+
383
+ | Mode | Threshold | Math | On exceed |
384
+ |------|-----------|------|-----------|
385
+ | in-session | 85% orchestrator-CW | `ctxPct + N × summarySize ≤ 85` | Reduce `N` to fit; floor `N=1` (never refuses) — emits `parallelism_reduced` |
386
+ | unattended | 60% per-worker CW | `estimatedCwPct ≤ 60` | `split=true`; caller slices into iters — emits `task_split` |
387
+
388
+ **Contract:** `.gsd-t/contracts/wave-join-contract.md` v1.1.0 (§Mode-Aware Gating Math) is the authoritative reference for thresholds, fallback behavior, and event schemas.
389
+
390
+ ---
391
+
354
392
  ## Key Principles
355
393
 
356
394
  1. **Contracts are the source of truth.** Code implements contracts, not the other way around. If code and contract disagree, fix one or the other — never leave them inconsistent.