@tekyzinc/gsd-t 3.13.16 → 3.16.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.
- package/CHANGELOG.md +44 -0
- package/README.md +1 -0
- package/bin/gsd-t-benchmark-orchestrator.js +437 -0
- package/bin/gsd-t-capture-lint.cjs +276 -0
- package/bin/gsd-t-completion-check.cjs +106 -0
- package/bin/gsd-t-orchestrator-config.cjs +64 -0
- package/bin/gsd-t-orchestrator-queue.cjs +180 -0
- package/bin/gsd-t-orchestrator-recover.cjs +231 -0
- package/bin/gsd-t-orchestrator-worker.cjs +219 -0
- package/bin/gsd-t-orchestrator.js +534 -0
- package/bin/gsd-t-stream-feed-client.cjs +151 -0
- package/bin/gsd-t-task-brief-compactor.cjs +89 -0
- package/bin/gsd-t-task-brief-template.cjs +96 -0
- package/bin/gsd-t-task-brief.js +249 -0
- package/bin/gsd-t-token-backfill.cjs +366 -0
- package/bin/gsd-t-token-capture.cjs +306 -0
- package/bin/gsd-t-token-dashboard.cjs +318 -0
- package/bin/gsd-t-token-regenerate-log.cjs +129 -0
- package/bin/gsd-t-transcript-tee.cjs +246 -0
- package/bin/gsd-t-unattended-heartbeat.cjs +188 -0
- package/bin/gsd-t-unattended-platform.cjs +191 -27
- package/bin/gsd-t-unattended-safety.cjs +8 -1
- package/bin/gsd-t-unattended.cjs +192 -31
- package/bin/gsd-t.js +329 -2
- package/bin/supervisor-pid-fingerprint.cjs +126 -0
- package/commands/gsd-t-debug.md +63 -51
- package/commands/gsd-t-design-decompose.md +2 -7
- package/commands/gsd-t-doc-ripple.md +20 -11
- package/commands/gsd-t-execute.md +82 -50
- package/commands/gsd-t-integrate.md +43 -16
- package/commands/gsd-t-plan.md +20 -7
- package/commands/gsd-t-prd.md +19 -12
- package/commands/gsd-t-quick.md +64 -29
- package/commands/gsd-t-resume.md +51 -4
- package/commands/gsd-t-unattended.md +19 -20
- package/commands/gsd-t-verify.md +48 -32
- package/commands/gsd-t-visualize.md +19 -17
- package/commands/gsd-t-wave.md +29 -27
- package/docs/architecture.md +16 -0
- package/docs/m40-benchmark-report.md +35 -0
- package/docs/requirements.md +20 -0
- package/package.json +1 -1
- package/scripts/gsd-t-dashboard-server.js +291 -4
- package/scripts/gsd-t-dashboard.html +31 -1
- package/scripts/gsd-t-design-review-server.js +3 -1
- package/scripts/gsd-t-stream-feed-server.js +428 -0
- package/scripts/gsd-t-stream-feed.html +1168 -0
- package/scripts/gsd-t-token-aggregator.js +373 -0
- package/scripts/gsd-t-transcript.html +422 -0
- package/scripts/hooks/gsd-t-in-session-probe.js +62 -0
- package/scripts/hooks/pre-commit-capture-lint +26 -0
- package/templates/CLAUDE-global.md +69 -0
- package/scripts/gsd-t-agent-dashboard-server.js +0 -424
- package/scripts/gsd-t-agent-dashboard.html +0 -1043
|
@@ -358,9 +358,7 @@ After writing all contracts but BEFORE proceeding to partition or build, spawn a
|
|
|
358
358
|
|
|
359
359
|
> **Why a separate agent?** The decompose agent that classified the charts cannot objectively verify its own classifications. It has the same blind spots that caused the misclassification. This was proven repeatedly — the same agent rubber-stamps its own work. A fresh agent with only the contracts and Figma access catches what the classifier missed.
|
|
360
360
|
|
|
361
|
-
**OBSERVABILITY LOGGING (MANDATORY)
|
|
362
|
-
Before spawning — run via Bash:
|
|
363
|
-
`T_START=$(date +%s) && DT_START=$(date +"%Y-%m-%d %H:%M")`
|
|
361
|
+
**OBSERVABILITY LOGGING (MANDATORY) — wrap the Chart Classification Verifier spawn with `captureSpawn`:** route through `bin/gsd-t-token-capture.cjs` with `{command: 'gsd-t-design-decompose', step: 'Chart Classification Verifier', model: 'opus', projectDir: '.', notes: 'verification {PASSED/FAILED}'}`. The wrapper owns banner + timing + envelope parse + row write.
|
|
364
362
|
|
|
365
363
|
⚙ [opus] gsd-t-design-decompose → Chart Classification Verifier
|
|
366
364
|
|
|
@@ -443,10 +441,7 @@ If ALL ✅ MATCH:
|
|
|
443
441
|
"
|
|
444
442
|
```
|
|
445
443
|
|
|
446
|
-
After
|
|
447
|
-
`T_END=$(date +%s) && DT_END=$(date +"%Y-%m-%d %H:%M") && DURATION=$((T_END-T_START))`
|
|
448
|
-
|
|
449
|
-
Compute tokens/compaction per standard pattern. Append to `.gsd-t/token-log.md`.
|
|
444
|
+
After the `captureSpawn` wrapper returns, the row is already written to `.gsd-t/token-log.md` under the canonical header with Tokens = `in=N out=N cr=N cc=N $X.XX` (or `—` if no envelope). No post-processing needed.
|
|
450
445
|
|
|
451
446
|
**If VERIFICATION FAILED**: Fix every misclassified element contract before proceeding:
|
|
452
447
|
1. Rename the contract file to match the correct chart type
|
|
@@ -97,19 +97,28 @@ For each document or logical group:
|
|
|
97
97
|
⚙ [haiku] gsd-t-doc-ripple → update {document}
|
|
98
98
|
(Use sonnet for docs/architecture.md and docs/requirements.md — these need reasoning.)
|
|
99
99
|
|
|
100
|
-
**OBSERVABILITY LOGGING (MANDATORY) —
|
|
100
|
+
**OBSERVABILITY LOGGING (MANDATORY) — wrap each document-update subagent with `captureSpawn`:**
|
|
101
101
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
102
|
+
```
|
|
103
|
+
node -e "
|
|
104
|
+
const { captureSpawn } = require('./bin/gsd-t-token-capture.cjs');
|
|
105
|
+
(async () => {
|
|
106
|
+
await captureSpawn({
|
|
107
|
+
command: 'gsd-t-doc-ripple',
|
|
108
|
+
step: 'Step 5',
|
|
109
|
+
model: '{haiku|sonnet}',
|
|
110
|
+
description: 'update {document}',
|
|
111
|
+
projectDir: '.',
|
|
112
|
+
domain: 'doc-ripple',
|
|
113
|
+
task: '-',
|
|
114
|
+
notes: 'update:{document}',
|
|
115
|
+
spawnFn: async () => { /* Task subagent call for the document-update prompt below */ },
|
|
116
|
+
});
|
|
117
|
+
})();
|
|
118
|
+
"
|
|
119
|
+
```
|
|
110
120
|
|
|
111
|
-
|
|
112
|
-
`| {DT_START} | {DT_END} | gsd-t-doc-ripple | Step 5 | {model} | {DURATION}s | update:{document} | doc-ripple | — | {CTX_PCT} |`
|
|
121
|
+
`captureSpawn` parses `result.usage` and writes the row to `.gsd-t/token-log.md` under the canonical header. Tokens column renders as `in=N out=N cr=N cc=N $X.XX` or `—`, never `N/A`.
|
|
113
122
|
|
|
114
123
|
**Each document-update subagent prompt:**
|
|
115
124
|
```
|
|
@@ -170,18 +170,30 @@ Each domain's work runs via a lightweight domain task-dispatcher. The dispatcher
|
|
|
170
170
|
- Up to 5 prior task summaries (10-20 lines each, most recent first)
|
|
171
171
|
- Past failure/learning entries for this domain (max 5 lines)
|
|
172
172
|
|
|
173
|
-
**OBSERVABILITY LOGGING (MANDATORY) —
|
|
173
|
+
**OBSERVABILITY LOGGING (MANDATORY) — wrap every task subagent spawn with `captureSpawn`:**
|
|
174
174
|
|
|
175
|
-
|
|
176
|
-
`T_START=$(date +%s) && DT_START=$(date +"%Y-%m-%d %H:%M")`
|
|
175
|
+
Route the spawn through `bin/gsd-t-token-capture.cjs` so the real `usage` envelope is parsed. The wrapper owns banner + timing + envelope parse + row write + JSONL record. Example for a per-task dispatch:
|
|
177
176
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
177
|
+
```
|
|
178
|
+
node -e "
|
|
179
|
+
const { captureSpawn } = require('./bin/gsd-t-token-capture.cjs');
|
|
180
|
+
(async () => {
|
|
181
|
+
await captureSpawn({
|
|
182
|
+
command: 'gsd-t-execute',
|
|
183
|
+
step: 'task:{task-id}',
|
|
184
|
+
model: 'sonnet',
|
|
185
|
+
description: 'domain: {domain-name} task: {task-id}',
|
|
186
|
+
projectDir: '.',
|
|
187
|
+
domain: '{domain-name}',
|
|
188
|
+
task: '{task-id}',
|
|
189
|
+
notes: '{pass/fail}',
|
|
190
|
+
spawnFn: async () => { /* Task(...) or spawn('claude', ...) call */ },
|
|
191
|
+
});
|
|
192
|
+
})();
|
|
193
|
+
"
|
|
194
|
+
```
|
|
183
195
|
|
|
184
|
-
|
|
196
|
+
`captureSpawn` writes the row to `.gsd-t/token-log.md` under the canonical header (`| Datetime-start | Datetime-end | Command | Step | Model | Duration(s) | Tokens | Notes | Domain | Task | Ctx% |`) — upgrading old headers in place. The **Tokens** cell renders as `in=N out=N cr=N cc=N $X.XX` when `result.usage` is present, or `—` when absent. Never `0`. Never `N/A`. The wrapper also pulls `Ctx%` from `getSessionStatus()` automatically (Step 3.5 context) — `pct` reads the real `input_tokens` count from `.gsd-t/.context-meter-state.json` produced by the Context Meter PostToolUse hook; when the state file is absent or stale, it reads `N/A`.
|
|
185
197
|
|
|
186
198
|
**For each domain (in wave order), run the domain task-dispatcher:**
|
|
187
199
|
|
|
@@ -753,9 +765,7 @@ If it DOES exist AND this domain touched UI files — spawn the **Design Verific
|
|
|
753
765
|
|
|
754
766
|
⚙ [opus] Design Verification → visual comparison for domain {domain-name}
|
|
755
767
|
|
|
756
|
-
**OBSERVABILITY LOGGING (MANDATORY)
|
|
757
|
-
Before spawning — run via Bash:
|
|
758
|
-
`T_START=$(date +%s) && DT_START=$(date +"%Y-%m-%d %H:%M")`
|
|
768
|
+
**OBSERVABILITY LOGGING (MANDATORY) — wrap the Design Verification spawn with `captureSpawn`:**
|
|
759
769
|
|
|
760
770
|
Resolve the templated prompt path first so the orchestrator never holds the full ~3500-token verification protocol in its own context:
|
|
761
771
|
|
|
@@ -764,23 +774,35 @@ DV_PROMPT="$(npm root -g 2>/dev/null)/@tekyzinc/gsd-t/templates/prompts/design-v
|
|
|
764
774
|
[ -f "$DV_PROMPT" ] || DV_PROMPT="templates/prompts/design-verify-subagent.md"
|
|
765
775
|
```
|
|
766
776
|
|
|
767
|
-
Then spawn
|
|
768
|
-
|
|
769
|
-
```
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
777
|
+
Then spawn through `captureSpawn` — `spawnType: 'validation'` (always headless, `--watch` ignored):
|
|
778
|
+
|
|
779
|
+
```
|
|
780
|
+
node -e "
|
|
781
|
+
const { captureSpawn } = require('./bin/gsd-t-token-capture.cjs');
|
|
782
|
+
(async () => {
|
|
783
|
+
await captureSpawn({
|
|
784
|
+
command: 'gsd-t-execute',
|
|
785
|
+
step: 'Design Verify',
|
|
786
|
+
model: 'opus',
|
|
787
|
+
description: 'visual comparison for domain {domain-name}',
|
|
788
|
+
projectDir: '.',
|
|
789
|
+
domain: '{domain-name}',
|
|
790
|
+
task: '-',
|
|
791
|
+
notes: '{VERDICT} — {MATCH}/{TOTAL} elements',
|
|
792
|
+
spawnFn: async () => { /* Task subagent (spawnType: validation, general-purpose, model: opus):
|
|
793
|
+
'You are the Design Verification Agent. Read $DV_PROMPT and follow it exactly.
|
|
794
|
+
Do not deviate from that protocol. Context for this run:
|
|
795
|
+
- domain: {domain-name}
|
|
796
|
+
- design contract: .gsd-t/contracts/design-contract.md
|
|
797
|
+
- files modified by this domain: {list}
|
|
798
|
+
Report back the verdict, match count, breakpoints verified, deviation count
|
|
799
|
+
and summary, and the full comparison table per the protocol's Step 7.' */ },
|
|
800
|
+
});
|
|
801
|
+
})();
|
|
802
|
+
"
|
|
803
|
+
```
|
|
804
|
+
|
|
805
|
+
`captureSpawn` parses `result.usage` and appends a row to `.gsd-t/token-log.md` under the canonical header. Tokens column renders as `in=N out=N cr=N cc=N $X.XX` or `—`, never `N/A`.
|
|
784
806
|
|
|
785
807
|
**Artifact Gate (MANDATORY):**
|
|
786
808
|
After the Design Verification Agent returns, check `.gsd-t/contracts/design-contract.md`:
|
|
@@ -809,9 +831,7 @@ After all tasks in the CURRENT DOMAIN pass their tests, spawn an adversarial Red
|
|
|
809
831
|
|
|
810
832
|
⚙ [opus] Red Team → adversarial validation for domain {domain-name}
|
|
811
833
|
|
|
812
|
-
**OBSERVABILITY LOGGING (MANDATORY)
|
|
813
|
-
Before spawning — run via Bash:
|
|
814
|
-
`T_START=$(date +%s) && DT_START=$(date +"%Y-%m-%d %H:%M")`
|
|
834
|
+
**OBSERVABILITY LOGGING (MANDATORY) — wrap the Red Team spawn with `captureSpawn`:**
|
|
815
835
|
|
|
816
836
|
Resolve the templated prompt path so the orchestrator never holds the full ~3500-token Red Team protocol in its own context:
|
|
817
837
|
|
|
@@ -820,24 +840,36 @@ RT_PROMPT="$(npm root -g 2>/dev/null)/@tekyzinc/gsd-t/templates/prompts/red-team
|
|
|
820
840
|
[ -f "$RT_PROMPT" ] || RT_PROMPT="templates/prompts/red-team-subagent.md"
|
|
821
841
|
```
|
|
822
842
|
|
|
823
|
-
Then spawn
|
|
824
|
-
|
|
825
|
-
```
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
.
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
843
|
+
Then spawn through `captureSpawn` — `spawnType: 'validation'` (always headless, `--watch` ignored):
|
|
844
|
+
|
|
845
|
+
```
|
|
846
|
+
node -e "
|
|
847
|
+
const { captureSpawn } = require('./bin/gsd-t-token-capture.cjs');
|
|
848
|
+
(async () => {
|
|
849
|
+
await captureSpawn({
|
|
850
|
+
command: 'gsd-t-execute',
|
|
851
|
+
step: 'Red Team',
|
|
852
|
+
model: 'opus',
|
|
853
|
+
description: 'adversarial validation for domain {domain-name}',
|
|
854
|
+
projectDir: '.',
|
|
855
|
+
domain: '{domain-name}',
|
|
856
|
+
task: '-',
|
|
857
|
+
notes: '{VERDICT} — {N} bugs found',
|
|
858
|
+
spawnFn: async () => { /* Task subagent (spawnType: validation, general-purpose, model: opus):
|
|
859
|
+
'You are a Red Team QA adversary. Read $RT_PROMPT and follow it exactly.
|
|
860
|
+
Do not deviate from that protocol. Context for this run:
|
|
861
|
+
- domain: {domain-name}
|
|
862
|
+
- files modified by this domain: {list}
|
|
863
|
+
- tasks just completed: {task-id list}
|
|
864
|
+
Report back the verdict (FAIL or GRUDGING PASS), bugs found by severity,
|
|
865
|
+
attack categories exhausted, and the path to the written
|
|
866
|
+
.gsd-t/red-team-report.md.' */ },
|
|
867
|
+
});
|
|
868
|
+
})();
|
|
869
|
+
"
|
|
870
|
+
```
|
|
871
|
+
|
|
872
|
+
`captureSpawn` parses `result.usage` and appends a row to `.gsd-t/token-log.md`. Tokens column renders as `in=N out=N cr=N cc=N $X.XX` or `—`, never `N/A`.
|
|
841
873
|
|
|
842
874
|
**If Red Team VERDICT is FAIL:**
|
|
843
875
|
1. Fix all CRITICAL and HIGH bugs immediately (up to 2 fix attempts per bug)
|
|
@@ -209,13 +209,26 @@ After all scripted tests pass:
|
|
|
209
209
|
Note: Exploratory findings do NOT count against the scripted test pass/fail ratio."
|
|
210
210
|
```
|
|
211
211
|
|
|
212
|
-
**OBSERVABILITY LOGGING (MANDATORY)
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
212
|
+
**OBSERVABILITY LOGGING (MANDATORY) — wrap the Step 5 validation spawn with `captureSpawn`:**
|
|
213
|
+
|
|
214
|
+
```
|
|
215
|
+
node -e "
|
|
216
|
+
const { captureSpawn } = require('./bin/gsd-t-token-capture.cjs');
|
|
217
|
+
(async () => {
|
|
218
|
+
await captureSpawn({
|
|
219
|
+
command: 'gsd-t-integrate',
|
|
220
|
+
step: 'Step 5',
|
|
221
|
+
model: 'haiku',
|
|
222
|
+
description: 'cross-boundary integration QA',
|
|
223
|
+
projectDir: '.',
|
|
224
|
+
notes: '{pass/fail}, {N} boundaries tested',
|
|
225
|
+
spawnFn: async () => { /* Task validation subagent call */ },
|
|
226
|
+
});
|
|
227
|
+
})();
|
|
228
|
+
"
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
`captureSpawn` writes the row to `.gsd-t/token-log.md` under the canonical header. Tokens column renders as `in=N out=N cr=N cc=N $X.XX` or `—`, never `N/A`.
|
|
219
232
|
If QA found issues, append each to `.gsd-t/qa-issues.md` (create with header `| Date | Command | Step | Model | Duration(s) | Severity | Finding |` if missing):
|
|
220
233
|
`| {DT_START} | gsd-t-integrate | Step 5 | haiku | {DURATION}s | {severity} | {finding} |`
|
|
221
234
|
|
|
@@ -270,22 +283,36 @@ After integration tests pass, spawn an adversarial Red Team agent on the integra
|
|
|
270
283
|
⚙ [opus] Red Team → adversarial validation of integrated system
|
|
271
284
|
|
|
272
285
|
Resolve the templated prompt path via Bash:
|
|
273
|
-
```
|
|
286
|
+
```bash
|
|
274
287
|
RT_PROMPT="$(npm root -g 2>/dev/null)/@tekyzinc/gsd-t/templates/prompts/red-team-subagent.md"
|
|
275
288
|
[ -f "$RT_PROMPT" ] || RT_PROMPT="templates/prompts/red-team-subagent.md"
|
|
276
|
-
T_START=$(date +%s) && DT_START=$(date +"%Y-%m-%d %H:%M")
|
|
277
289
|
```
|
|
278
290
|
|
|
279
|
-
|
|
280
|
-
> "Read `$RT_PROMPT` and follow it. Context: cross-domain integration run. **Additional category for this run: Cross-Domain Boundaries** — test data flow across every domain boundary; does data arriving from domain A get validated by domain B; what happens when A sends malformed data that passed A's own validation. Write findings to `.gsd-t/red-team-report.md`."
|
|
291
|
+
Then spawn through `captureSpawn` — `spawnType: 'validation'` (always headless, `--watch` ignored):
|
|
281
292
|
|
|
282
|
-
After subagent returns — run via Bash:
|
|
283
293
|
```
|
|
284
|
-
|
|
285
|
-
|
|
294
|
+
node -e "
|
|
295
|
+
const { captureSpawn } = require('./bin/gsd-t-token-capture.cjs');
|
|
296
|
+
(async () => {
|
|
297
|
+
await captureSpawn({
|
|
298
|
+
command: 'gsd-t-integrate',
|
|
299
|
+
step: 'Red Team',
|
|
300
|
+
model: 'opus',
|
|
301
|
+
description: 'cross-domain adversarial validation',
|
|
302
|
+
projectDir: '.',
|
|
303
|
+
notes: '{VERDICT} — {N} bugs found',
|
|
304
|
+
spawnFn: async () => { /* Task subagent (spawnType: validation, general-purpose, model: opus):
|
|
305
|
+
'Read \$RT_PROMPT and follow it. Context: cross-domain integration run.
|
|
306
|
+
Additional category for this run: Cross-Domain Boundaries — test data flow across every
|
|
307
|
+
domain boundary; does data arriving from domain A get validated by domain B; what happens
|
|
308
|
+
when A sends malformed data that passed A own validation.
|
|
309
|
+
Write findings to .gsd-t/red-team-report.md.' */ },
|
|
310
|
+
});
|
|
311
|
+
})();
|
|
312
|
+
"
|
|
286
313
|
```
|
|
287
|
-
|
|
288
|
-
|
|
314
|
+
|
|
315
|
+
`captureSpawn` writes the row to `.gsd-t/token-log.md` under the canonical header. Tokens column renders as `in=N out=N cr=N cc=N $X.XX` or `—`, never `N/A`.
|
|
289
316
|
|
|
290
317
|
**If FAIL:** fix CRITICAL/HIGH bugs (≤2 cycles) → re-run. Persistent bugs → `.gsd-t/deferred-items.md`.
|
|
291
318
|
**If GRUDGING PASS:** proceed to doc-ripple.
|
package/commands/gsd-t-plan.md
CHANGED
|
@@ -415,13 +415,26 @@ Check:
|
|
|
415
415
|
Report: PASS (all checks pass) or FAIL with specific gaps listed."
|
|
416
416
|
```
|
|
417
417
|
|
|
418
|
-
**OBSERVABILITY LOGGING (MANDATORY)
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
418
|
+
**OBSERVABILITY LOGGING (MANDATORY) — wrap the validation spawn with `captureSpawn`:**
|
|
419
|
+
|
|
420
|
+
```
|
|
421
|
+
node -e "
|
|
422
|
+
const { captureSpawn } = require('./bin/gsd-t-token-capture.cjs');
|
|
423
|
+
(async () => {
|
|
424
|
+
await captureSpawn({
|
|
425
|
+
command: 'gsd-t-plan',
|
|
426
|
+
step: 'Step 7',
|
|
427
|
+
model: 'haiku',
|
|
428
|
+
description: 'plan validation, iteration {N}',
|
|
429
|
+
projectDir: '.',
|
|
430
|
+
notes: '{PASS/FAIL}, iteration {N}',
|
|
431
|
+
spawnFn: async () => { /* Task validation subagent call */ },
|
|
432
|
+
});
|
|
433
|
+
})();
|
|
434
|
+
"
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
`captureSpawn` parses `result.usage` and writes the row to `.gsd-t/token-log.md` under the canonical header (Tokens column renders as `in=N out=N cr=N cc=N $X.XX` or `—`, never `N/A`).
|
|
425
438
|
If validation FAIL, append each gap to `.gsd-t/qa-issues.md` (create with header `| Date | Command | Step | Model | Duration(s) | Severity | Finding |` if missing):
|
|
426
439
|
`| {DT_START} | gsd-t-plan | Step 7 | haiku | {DURATION}s | medium | {gap description} |`
|
|
427
440
|
|
package/commands/gsd-t-prd.md
CHANGED
|
@@ -10,22 +10,29 @@ To give PRD generation a fresh context window:
|
|
|
10
10
|
|
|
11
11
|
**If you are the orchestrating agent** (you received the slash command directly):
|
|
12
12
|
|
|
13
|
-
**OBSERVABILITY LOGGING (MANDATORY)
|
|
14
|
-
Before spawning — run via Bash:
|
|
15
|
-
`T_START=$(date +%s) && DT_START=$(date +"%Y-%m-%d %H:%M")`
|
|
13
|
+
**OBSERVABILITY LOGGING (MANDATORY) — wrap the PRD subagent spawn with `captureSpawn`:**
|
|
16
14
|
|
|
17
|
-
Spawn a fresh subagent using the Task tool:
|
|
18
15
|
```
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
node -e "
|
|
17
|
+
const { captureSpawn } = require('./bin/gsd-t-token-capture.cjs');
|
|
18
|
+
(async () => {
|
|
19
|
+
await captureSpawn({
|
|
20
|
+
command: 'gsd-t-prd',
|
|
21
|
+
step: 'Step 0',
|
|
22
|
+
model: 'sonnet',
|
|
23
|
+
description: 'prd: {topic summary}',
|
|
24
|
+
projectDir: '.',
|
|
25
|
+
notes: 'prd: {topic summary}',
|
|
26
|
+
spawnFn: async () => { /* Task subagent (subagent_type: general-purpose):
|
|
27
|
+
'You are running gsd-t-prd for this request: {\$ARGUMENTS}
|
|
28
|
+
Working directory: {current project root}
|
|
29
|
+
Read CLAUDE.md and .gsd-t/progress.md for project context, then execute gsd-t-prd starting at Step 1.' */ },
|
|
30
|
+
});
|
|
31
|
+
})();
|
|
32
|
+
"
|
|
23
33
|
```
|
|
24
34
|
|
|
25
|
-
|
|
26
|
-
`T_END=$(date +%s) && DT_END=$(date +"%Y-%m-%d %H:%M") && DURATION=$((T_END-T_START)) && CTX_PCT=$(node -e "const tb=require('./bin/token-budget.cjs'); process.stdout.write(String(tb.getSessionStatus('.').pct||'N/A'))" 2>/dev/null || echo "N/A")`
|
|
27
|
-
Append to `.gsd-t/token-log.md` (create with header `| Datetime-start | Datetime-end | Command | Step | Model | Duration(s) | Notes | Ctx% |` if missing):
|
|
28
|
-
`| {DT_START} | {DT_END} | gsd-t-prd | Step 0 | sonnet | {DURATION}s | prd: {topic summary} | {CTX_PCT} |`
|
|
35
|
+
`captureSpawn` parses `result.usage` and writes the row to `.gsd-t/token-log.md` under the canonical header. Tokens column renders as `in=N out=N cr=N cc=N $X.XX` or `—`, never `N/A`.
|
|
29
36
|
|
|
30
37
|
Relay the subagent's summary to the user. **Do not execute Steps 1–6 yourself.**
|
|
31
38
|
|
package/commands/gsd-t-quick.md
CHANGED
|
@@ -34,10 +34,6 @@ To give this task a fresh context window and prevent compaction during consecuti
|
|
|
34
34
|
|
|
35
35
|
**If you are the orchestrating agent** (you received the slash command directly):
|
|
36
36
|
|
|
37
|
-
**OBSERVABILITY LOGGING (MANDATORY):**
|
|
38
|
-
Before spawning — run via Bash:
|
|
39
|
-
`T_START=$(date +%s) && DT_START=$(date +"%Y-%m-%d %H:%M")`
|
|
40
|
-
|
|
41
37
|
**Token Budget Check (before spawning subagent):**
|
|
42
38
|
|
|
43
39
|
Run via Bash:
|
|
@@ -109,20 +105,32 @@ Violations are task failures, not warnings.
|
|
|
109
105
|
|
|
110
106
|
If STACK_RULES is empty (no templates/stacks/ dir or no matches), skip silently.
|
|
111
107
|
|
|
112
|
-
Spawn a fresh subagent
|
|
108
|
+
Spawn a fresh subagent via `captureSpawn` — `spawnType: 'primary'` (respects `--watch`: headless by default, in-context when `WATCH_FLAG=true`):
|
|
109
|
+
|
|
110
|
+
**OBSERVABILITY LOGGING (MANDATORY) — wrap the primary subagent spawn with `captureSpawn`:**
|
|
111
|
+
|
|
113
112
|
```
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
113
|
+
node -e "
|
|
114
|
+
const { captureSpawn } = require('./bin/gsd-t-token-capture.cjs');
|
|
115
|
+
(async () => {
|
|
116
|
+
await captureSpawn({
|
|
117
|
+
command: 'gsd-t-quick',
|
|
118
|
+
step: 'Step 0',
|
|
119
|
+
model: 'sonnet',
|
|
120
|
+
description: 'quick: {task summary}',
|
|
121
|
+
projectDir: '.',
|
|
122
|
+
notes: 'quick: {task summary}',
|
|
123
|
+
spawnFn: async () => { /* Task subagent (general-purpose, spawnType: primary, model: sonnet):
|
|
124
|
+
'You are running gsd-t-quick for this request: {\$ARGUMENTS}
|
|
125
|
+
Working directory: {current project root}
|
|
126
|
+
Read CLAUDE.md and .gsd-t/progress.md for project context, then execute gsd-t-quick starting at Step 1.
|
|
127
|
+
{STACK_RULES block — if non-empty, append the ## Stack Rules section defined above; omit if empty}' */ },
|
|
128
|
+
});
|
|
129
|
+
})();
|
|
130
|
+
"
|
|
120
131
|
```
|
|
121
132
|
|
|
122
|
-
|
|
123
|
-
`T_END=$(date +%s) && DT_END=$(date +"%Y-%m-%d %H:%M") && DURATION=$((T_END-T_START))`
|
|
124
|
-
Append to `.gsd-t/token-log.md` (create with header `| Datetime-start | Datetime-end | Command | Step | Model | Duration(s) | Notes | Ctx% |` if missing):
|
|
125
|
-
`| {DT_START} | {DT_END} | gsd-t-quick | Step 0 | sonnet | {DURATION}s | quick: {task summary} | {CTX_PCT} |`
|
|
133
|
+
`captureSpawn` parses `result.usage` and writes the row to `.gsd-t/token-log.md` under the canonical header. Tokens column renders as `in=N out=N cr=N cc=N $X.XX` or `—`, never `N/A`.
|
|
126
134
|
|
|
127
135
|
Relay the subagent's summary to the user. **Do not execute Steps 1–5 yourself.**
|
|
128
136
|
|
|
@@ -305,11 +313,30 @@ After tests pass, check if `.gsd-t/contracts/design-contract.md` exists. If it d
|
|
|
305
313
|
|
|
306
314
|
If it DOES exist and this task involved UI changes — spawn the Design Verification Agent. This agent's ONLY job is to open a browser, compare the built frontend against the original design, and produce a structured comparison table. It writes NO feature code.
|
|
307
315
|
|
|
308
|
-
⚙ [
|
|
316
|
+
⚙ [opus] Design Verification → visual comparison of built frontend vs design
|
|
317
|
+
|
|
318
|
+
**OBSERVABILITY LOGGING (MANDATORY) — wrap the Design Verification subagent spawn with `captureSpawn`:**
|
|
319
|
+
|
|
320
|
+
```
|
|
321
|
+
node -e "
|
|
322
|
+
const { captureSpawn } = require('./bin/gsd-t-token-capture.cjs');
|
|
323
|
+
(async () => {
|
|
324
|
+
await captureSpawn({
|
|
325
|
+
command: 'gsd-t-quick',
|
|
326
|
+
step: 'Design Verify',
|
|
327
|
+
model: 'opus',
|
|
328
|
+
description: 'visual comparison of built frontend vs design',
|
|
329
|
+
projectDir: '.',
|
|
330
|
+
notes: 'design-verify',
|
|
331
|
+
spawnFn: async () => { /* Task subagent (spawnType: validation, general-purpose, model: opus) — body below */ },
|
|
332
|
+
});
|
|
333
|
+
})();
|
|
334
|
+
"
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
`captureSpawn` parses `result.usage` and writes the row to `.gsd-t/token-log.md` under the canonical header. Tokens column renders as `in=N out=N cr=N cc=N $X.XX` or `—`, never `N/A`.
|
|
309
338
|
|
|
310
|
-
**
|
|
311
|
-
Before spawning — run via Bash:
|
|
312
|
-
`T_START=$(date +%s) && DT_START=$(date +"%Y-%m-%d %H:%M")`
|
|
339
|
+
**Design Verification subagent prompt body (passed to `spawnFn`):**
|
|
313
340
|
|
|
314
341
|
```
|
|
315
342
|
Task subagent (spawnType: validation, general-purpose, model: opus):
|
|
@@ -366,8 +393,6 @@ cannot be redeemed by visual polish.
|
|
|
366
393
|
10. Report: DESIGN VERIFIED | DESIGN DEVIATIONS FOUND ({count})"
|
|
367
394
|
```
|
|
368
395
|
|
|
369
|
-
After subagent returns — run observability Bash and append to token-log.md.
|
|
370
|
-
|
|
371
396
|
**Artifact Gate:** Read `.gsd-t/contracts/design-contract.md` — if no `## Verification Status` section with a comparison table exists, re-spawn (1 retry).
|
|
372
397
|
|
|
373
398
|
**If deviations found:** Fix them (max 2 cycles), re-verify. If persistent, log to `.gsd-t/deferred-items.md`.
|
|
@@ -386,19 +411,29 @@ Resolve the templated prompt path via Bash (same pattern as execute.md):
|
|
|
386
411
|
```
|
|
387
412
|
RT_PROMPT="$(npm root -g 2>/dev/null)/@tekyzinc/gsd-t/templates/prompts/red-team-subagent.md"
|
|
388
413
|
[ -f "$RT_PROMPT" ] || RT_PROMPT="templates/prompts/red-team-subagent.md"
|
|
389
|
-
T_START=$(date +%s) && DT_START=$(date +"%Y-%m-%d %H:%M")
|
|
390
414
|
```
|
|
391
415
|
|
|
392
|
-
|
|
393
|
-
> "Read `$RT_PROMPT` and follow it. Context for this run: quick task — adversarial validation of the code just changed. Write findings to `.gsd-t/red-team-report.md`."
|
|
416
|
+
**OBSERVABILITY LOGGING (MANDATORY) — wrap the Red Team subagent spawn with `captureSpawn`:**
|
|
394
417
|
|
|
395
|
-
After subagent returns — run via Bash:
|
|
396
418
|
```
|
|
397
|
-
|
|
398
|
-
|
|
419
|
+
node -e "
|
|
420
|
+
const { captureSpawn } = require('./bin/gsd-t-token-capture.cjs');
|
|
421
|
+
(async () => {
|
|
422
|
+
await captureSpawn({
|
|
423
|
+
command: 'gsd-t-quick',
|
|
424
|
+
step: 'Red Team',
|
|
425
|
+
model: 'opus',
|
|
426
|
+
description: 'adversarial validation of quick task',
|
|
427
|
+
projectDir: '.',
|
|
428
|
+
notes: '{VERDICT} — {N} bugs found',
|
|
429
|
+
spawnFn: async () => { /* Task subagent (spawnType: validation, general-purpose, model: opus) — always headless, --watch ignored:
|
|
430
|
+
'Read \$RT_PROMPT and follow it. Context for this run: quick task — adversarial validation of the code just changed. Write findings to .gsd-t/red-team-report.md.' */ },
|
|
431
|
+
});
|
|
432
|
+
})();
|
|
433
|
+
"
|
|
399
434
|
```
|
|
400
|
-
|
|
401
|
-
|
|
435
|
+
|
|
436
|
+
`captureSpawn` parses `result.usage` and writes the row to `.gsd-t/token-log.md` under the canonical header. Tokens column renders as `in=N out=N cr=N cc=N $X.XX` or `—`, never `N/A`.
|
|
402
437
|
|
|
403
438
|
**If Red Team VERDICT is FAIL:**
|
|
404
439
|
1. Fix all CRITICAL and HIGH bugs (up to 2 fix cycles)
|
package/commands/gsd-t-resume.md
CHANGED
|
@@ -17,12 +17,26 @@ Check whether an unattended supervisor is actively running for this project:
|
|
|
17
17
|
1. Check if `.gsd-t/.unattended/supervisor.pid` exists.
|
|
18
18
|
- **Does not exist** → no supervisor running. Fall through to Step 0.1.
|
|
19
19
|
|
|
20
|
-
2. **File exists**:
|
|
20
|
+
2. **File exists**: Run the liveness + fingerprint check via the helper:
|
|
21
21
|
```bash
|
|
22
|
-
|
|
22
|
+
node -e "
|
|
23
|
+
const { readPidFile, verifyFingerprint } = require('./bin/supervisor-pid-fingerprint.cjs');
|
|
24
|
+
const entry = readPidFile(process.cwd());
|
|
25
|
+
if (!entry) { console.log('no_pid_file'); process.exit(0); }
|
|
26
|
+
try { process.kill(entry.pid, 0); } catch { console.log('dead:' + entry.pid); process.exit(0); }
|
|
27
|
+
const r = verifyFingerprint(entry, process.cwd());
|
|
28
|
+
if (r.ok === true) console.log('alive_verified:' + entry.pid);
|
|
29
|
+
else if (r.ok === null) console.log('alive_legacy_pid:' + entry.pid);
|
|
30
|
+
else console.log('alive_but_stale:' + entry.pid + ':' + r.reason);
|
|
31
|
+
"
|
|
23
32
|
```
|
|
24
|
-
|
|
25
|
-
|
|
33
|
+
|
|
34
|
+
Five possible outcomes:
|
|
35
|
+
- `no_pid_file` → no supervisor running, fall through to Step 0.1.
|
|
36
|
+
- `dead:<pid>` → supervisor exited (cleanly or crashed). PID file stale. Log: `[resume] supervisor PID <pid> no longer alive — stale PID file, falling through to normal resume`. Fall through.
|
|
37
|
+
- `alive_verified:<pid>` → our supervisor, same project, ps confirms command line. Proceed to step 3 (AUTO-REATTACH).
|
|
38
|
+
- `alive_legacy_pid:<pid>` → PID file is legacy bare-integer form; we can only confirm "some process with this PID exists." Log a one-line warning: `[resume] supervisor PID <pid> file uses legacy bare-integer form — next supervisor launch will upgrade to JSON fingerprint`. Proceed to step 3 as if verified (preserves behavior for any already-running legacy supervisors).
|
|
39
|
+
- `alive_but_stale:<pid>:<reason>` → process alive but **not** our supervisor (different project recycled PID, or non-gsd-t process). Log: `[resume] supervisor PID <pid> no longer identifies our supervisor (reason: <reason>) — treating as stale, falling through to normal resume`. Fall through to Step 0.1.
|
|
26
40
|
|
|
27
41
|
3. **Supervisor is alive**: Read `.gsd-t/.unattended/state.json`. Check `state.status`:
|
|
28
42
|
- **Terminal status** (`done`, `failed`, `stopped`, `crashed`) → the supervisor has finished and is waiting for cleanup. Fall through to Step 0.1 so normal resume flow runs (it will see progress.md state and continue from where the supervisor left off).
|
|
@@ -74,6 +88,39 @@ This prevents the child side of a headless spawn from reading a partial continue
|
|
|
74
88
|
|
|
75
89
|
---
|
|
76
90
|
|
|
91
|
+
## Step 0.3: Orchestrator Run Recovery (M40 D6)
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
node scripts/gsd-t-watch-state.js advance --agent-id "$GSD_T_AGENT_ID" --parent-id "${GSD_T_PARENT_AGENT_ID:-null}" --command gsd-t-resume --step 0 --step-label ".3: Orchestrator Run Recovery (M40 D6)" 2>/dev/null || true
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
If an orchestrator run was interrupted (crash, SIGINT, kill, parent timeout), `.gsd-t/orchestrator/state.json` will still exist with a non-terminal `status`. Detect this and offer to resume it via the deterministic `--resume` path rather than attempting prose-driven reconciliation:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
node -e "
|
|
101
|
+
const fs = require('fs');
|
|
102
|
+
const path = require('path');
|
|
103
|
+
const fp = path.join('.gsd-t', 'orchestrator', 'state.json');
|
|
104
|
+
if (!fs.existsSync(fp)) process.exit(0);
|
|
105
|
+
let s; try { s = JSON.parse(fs.readFileSync(fp, 'utf8')); } catch { process.exit(0); }
|
|
106
|
+
const TERMINAL = new Set(['done','failed','stopped','interrupted','completed']);
|
|
107
|
+
if (!s || TERMINAL.has(s.status)) process.exit(0);
|
|
108
|
+
const running = Object.entries(s.tasks || {}).filter(([,t]) => t && t.status === 'running');
|
|
109
|
+
console.error('▶ Orchestrator run still in-flight (status=' + (s.status||'?') + ', ' + running.length + ' running task(s))');
|
|
110
|
+
console.error(' Resume via: node bin/gsd-t-orchestrator.js orchestrate --milestone ' + (s.milestone || '<id>') + ' --resume');
|
|
111
|
+
console.error(' This calls recoverRunState() to reconcile in-flight tasks (ok/ambiguous/failed) before continuing.');
|
|
112
|
+
" || true
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Rules:
|
|
116
|
+
- **State absent or terminal** → nothing to do; fall through.
|
|
117
|
+
- **Non-terminal** → surface the recovery hint and, at Level 3, auto-invoke the orchestrator with `--resume` when the current milestone matches `state.milestone`. Ambiguous tasks (commit but no progress entry) are flagged in the orchestrator output and require operator triage — do **not** silently claim them done.
|
|
118
|
+
- The recovery algorithm, archiving, and ambiguous handling are covered by unit tests in `test/m40-recovery.test.js` and implemented in `bin/gsd-t-orchestrator-recover.cjs`.
|
|
119
|
+
|
|
120
|
+
Contract: stream-json-sink v1.1.0, wave-join v1.x, completion-signal v1.x.
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
77
124
|
## Step 0.5: Headless Read-Back Banner (MANDATORY)
|
|
78
125
|
|
|
79
126
|
```bash
|