@tekyzinc/gsd-t 2.45.11 → 2.50.10
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 +23 -0
- package/README.md +26 -5
- package/bin/debug-ledger.js +193 -0
- package/bin/gsd-t.js +259 -1
- package/commands/gsd-t-complete-milestone.md +2 -1
- package/commands/gsd-t-debug.md +48 -2
- package/commands/gsd-t-doc-ripple.md +148 -0
- package/commands/gsd-t-execute.md +102 -5
- package/commands/gsd-t-help.md +25 -2
- package/commands/gsd-t-integrate.md +41 -1
- package/commands/gsd-t-qa.md +26 -5
- package/commands/gsd-t-quick.md +39 -1
- package/commands/gsd-t-test-sync.md +26 -1
- package/commands/gsd-t-verify.md +8 -2
- package/commands/gsd-t-wave.md +57 -0
- package/docs/GSD-T-README.md +84 -1
- package/docs/architecture.md +9 -1
- package/docs/framework-comparison-scorecard.md +160 -0
- package/docs/requirements.md +33 -0
- package/examples/rules/desktop.ini +2 -0
- package/package.json +2 -2
- package/templates/CLAUDE-global.md +82 -4
- package/templates/stacks/_security.md +243 -0
- package/templates/stacks/desktop.ini +2 -0
- package/templates/stacks/docker.md +202 -0
- package/templates/stacks/firebase.md +166 -0
- package/templates/stacks/flutter.md +205 -0
- package/templates/stacks/github-actions.md +201 -0
- package/templates/stacks/graphql.md +216 -0
- package/templates/stacks/neo4j.md +218 -0
- package/templates/stacks/nextjs.md +184 -0
- package/templates/stacks/node-api.md +196 -0
- package/templates/stacks/playwright.md +528 -0
- package/templates/stacks/postgresql.md +225 -0
- package/templates/stacks/python.md +243 -0
- package/templates/stacks/react-native.md +216 -0
- package/templates/stacks/react.md +293 -0
- package/templates/stacks/redux.md +193 -0
- package/templates/stacks/rest-api.md +202 -0
- package/templates/stacks/supabase.md +188 -0
- package/templates/stacks/tailwind.md +169 -0
- package/templates/stacks/typescript.md +176 -0
- package/templates/stacks/vite.md +176 -0
- package/templates/stacks/vue.md +189 -0
- package/templates/stacks/zustand.md +203 -0
package/commands/gsd-t-debug.md
CHANGED
|
@@ -8,6 +8,22 @@ To give this debug session a fresh context window and prevent compaction, always
|
|
|
8
8
|
|
|
9
9
|
**If you are the orchestrating agent** (you received the slash command directly):
|
|
10
10
|
|
|
11
|
+
**Stack Rules Detection (before spawning subagent):**
|
|
12
|
+
Run via Bash to detect project stack and collect matching rules:
|
|
13
|
+
`GSD_T_DIR=$(npm root -g 2>/dev/null)/@tekyzinc/gsd-t; STACKS_DIR="$GSD_T_DIR/templates/stacks"; STACK_RULES=""; if [ -d "$STACKS_DIR" ]; then for f in "$STACKS_DIR"/_*.md; do [ -f "$f" ] && STACK_RULES="${STACK_RULES}$(cat "$f")"$'\n\n'; done; if [ -f "package.json" ]; then grep -q '"react-native"' package.json 2>/dev/null && [ -f "$STACKS_DIR/react-native.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/react-native.md")"$'\n\n'; grep -q '"react"' package.json 2>/dev/null && ! grep -q '"react-native"' package.json 2>/dev/null && [ -f "$STACKS_DIR/react.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/react.md")"$'\n\n'; grep -q '"next"' package.json 2>/dev/null && [ -f "$STACKS_DIR/nextjs.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/nextjs.md")"$'\n\n'; grep -q '"vue"' package.json 2>/dev/null && [ -f "$STACKS_DIR/vue.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/vue.md")"$'\n\n'; (grep -q '"typescript"' package.json 2>/dev/null || [ -f "tsconfig.json" ]) && [ -f "$STACKS_DIR/typescript.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/typescript.md")"$'\n\n'; grep -qE '"(express|fastify|hono|koa)"' package.json 2>/dev/null && [ -f "$STACKS_DIR/node-api.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/node-api.md")"$'\n\n'; grep -q '"tailwindcss"' package.json 2>/dev/null && [ -f "$STACKS_DIR/tailwind.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/tailwind.md")"$'\n\n'; grep -q '"vite"' package.json 2>/dev/null && [ -f "$STACKS_DIR/vite.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/vite.md")"$'\n\n'; grep -q '"@supabase/supabase-js"' package.json 2>/dev/null && [ -f "$STACKS_DIR/supabase.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/supabase.md")"$'\n\n'; grep -q '"firebase"' package.json 2>/dev/null && [ -f "$STACKS_DIR/firebase.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/firebase.md")"$'\n\n'; grep -qE '"(graphql|@apollo/client|urql)"' package.json 2>/dev/null && [ -f "$STACKS_DIR/graphql.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/graphql.md")"$'\n\n'; grep -q '"zustand"' package.json 2>/dev/null && [ -f "$STACKS_DIR/zustand.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/zustand.md")"$'\n\n'; grep -q '"@reduxjs/toolkit"' package.json 2>/dev/null && [ -f "$STACKS_DIR/redux.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/redux.md")"$'\n\n'; grep -q '"neo4j-driver"' package.json 2>/dev/null && [ -f "$STACKS_DIR/neo4j.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/neo4j.md")"$'\n\n'; grep -qE '"(pg|prisma|drizzle-orm|knex)"' package.json 2>/dev/null && [ -f "$STACKS_DIR/postgresql.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/postgresql.md")"$'\n\n'; grep -qE '"(express|fastify|hono|koa)"' package.json 2>/dev/null && [ -f "$STACKS_DIR/rest-api.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/rest-api.md")"$'\n\n'; fi; ([ -f "requirements.txt" ] || [ -f "pyproject.toml" ] || [ -f "Pipfile" ]) && [ -f "$STACKS_DIR/python.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/python.md")"$'\n\n'; ([ -f "requirements.txt" ] && grep -q "psycopg" requirements.txt 2>/dev/null || [ -f "pyproject.toml" ] && grep -q "psycopg" pyproject.toml 2>/dev/null) && [ -f "$STACKS_DIR/postgresql.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/postgresql.md")"$'\n\n'; ([ -f "requirements.txt" ] && grep -q "neo4j" requirements.txt 2>/dev/null) && [ -f "$STACKS_DIR/neo4j.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/neo4j.md")"$'\n\n'; [ -f "pubspec.yaml" ] && [ -f "$STACKS_DIR/flutter.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/flutter.md")"$'\n\n'; [ -f "Dockerfile" ] && [ -f "$STACKS_DIR/docker.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/docker.md")"$'\n\n'; [ -d ".github/workflows" ] && [ -f "$STACKS_DIR/github-actions.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/github-actions.md")"$'\n\n'; ([ -f "playwright.config.ts" ] || [ -f "playwright.config.js" ]) && [ -f "$STACKS_DIR/playwright.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/playwright.md")"$'\n\n'; [ -f "go.mod" ] && [ -f "$STACKS_DIR/go.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/go.md")"$'\n\n'; [ -f "Cargo.toml" ] && [ -f "$STACKS_DIR/rust.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/rust.md")"$'\n\n'; fi`
|
|
14
|
+
|
|
15
|
+
If STACK_RULES is non-empty, append to the subagent prompt:
|
|
16
|
+
```
|
|
17
|
+
## Stack Rules (MANDATORY — violations fail this task)
|
|
18
|
+
|
|
19
|
+
{STACK_RULES}
|
|
20
|
+
|
|
21
|
+
These standards have the same enforcement weight as contract compliance.
|
|
22
|
+
Violations are task failures, not warnings.
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
If STACK_RULES is empty (no templates/stacks/ dir or no matches), skip silently.
|
|
26
|
+
|
|
11
27
|
**OBSERVABILITY LOGGING (MANDATORY):**
|
|
12
28
|
Before spawning — run via Bash:
|
|
13
29
|
`T_START=$(date +%s) && DT_START=$(date +"%Y-%m-%d %H:%M") && TOK_START=${CLAUDE_CONTEXT_TOKENS_USED:-0} && TOK_MAX=${CLAUDE_CONTEXT_TOKENS_MAX:-200000}`
|
|
@@ -215,7 +231,16 @@ When you encounter unexpected situations during the fix:
|
|
|
215
231
|
3. **Blocker (missing file, wrong API response)** → Fix blocker and continue. Log if non-trivial.
|
|
216
232
|
4. **Architectural change required to fix correctly** → STOP. Explain what exists, what needs to change, what breaks, and a migration path. Wait for user approval. Never self-approve.
|
|
217
233
|
|
|
218
|
-
**3-attempt limit**: If your fix doesn't work after 3 attempts within this session, treat it as a loop. Do NOT keep trying the same approach.
|
|
234
|
+
**3-attempt limit**: If your fix doesn't work after 3 attempts within this session, treat it as a loop. Do NOT keep trying the same approach. Before entering Deep Research Mode, first try the headless debug-loop:
|
|
235
|
+
1. Write current failure context to `.gsd-t/debug-state.jsonl` via appendEntry
|
|
236
|
+
2. Log: "Delegating to headless debug-loop (3 in-context attempts exhausted)"
|
|
237
|
+
3. Run: `gsd-t headless --debug-loop --max-iterations 10`
|
|
238
|
+
4. Check exit code:
|
|
239
|
+
- 0: Tests pass, continue
|
|
240
|
+
- 1/4: Log to `.gsd-t/deferred-items.md`, then enter Deep Research Mode
|
|
241
|
+
- 3: Report error, stop
|
|
242
|
+
|
|
243
|
+
If the debug-loop also fails (exit 1/4), log the attempt to `.gsd-t/progress.md` Decision Log with a `[failure]` prefix, return to Step 1.5 and run Deep Research Mode before any further attempts. Present findings and options to the user before proceeding.
|
|
219
244
|
|
|
220
245
|
### Solo Mode
|
|
221
246
|
1. Reproduce the issue — **reproduction script must exist before step 2** (see Step 2.5)
|
|
@@ -288,7 +313,8 @@ Before committing, ensure the fix is solid:
|
|
|
288
313
|
d. Report ALL results: "Unit: X/Y pass | E2E: X/Y pass"
|
|
289
314
|
3. **Verify passing**: All tests must pass. If any fail, fix before proceeding (up to 2 attempts)
|
|
290
315
|
4. **If the project has a UI but no E2E specs cover the fixed area**: WRITE THEM.
|
|
291
|
-
5. **
|
|
316
|
+
5. **Functional test quality**: Every E2E assertion must verify an action produced the correct outcome (state changed, data loaded, content updated) — not just that elements exist. Tests that only check `isVisible`/`toBeEnabled` are shallow layout tests and don't catch real bugs. If a test would pass on an empty HTML page with the right IDs, rewrite it.
|
|
317
|
+
6. **Regression check**: Confirm the fix doesn't break any adjacent functionality
|
|
292
318
|
|
|
293
319
|
Commit: `[debug] Fix {description} — root cause: {explanation}`
|
|
294
320
|
|
|
@@ -302,6 +328,26 @@ Signal type is always `debug-invoked` for debug sessions.
|
|
|
302
328
|
Emit task_complete event — run via Bash:
|
|
303
329
|
`node ~/.claude/scripts/gsd-t-event-writer.js --type task_complete --command gsd-t-debug --reasoning "signal_type=debug-invoked, domain={domain}" --outcome {success|failure} || true`
|
|
304
330
|
|
|
331
|
+
## Step 6: Doc-Ripple (Automated)
|
|
332
|
+
|
|
333
|
+
After all work is committed but before reporting completion:
|
|
334
|
+
|
|
335
|
+
1. Run threshold check — read `git diff --name-only HEAD~1` and evaluate against doc-ripple-contract.md trigger conditions
|
|
336
|
+
2. If SKIP: log "Doc-ripple: SKIP — {reason}" and proceed to completion
|
|
337
|
+
3. If FIRE: spawn doc-ripple agent:
|
|
338
|
+
|
|
339
|
+
⚙ [{model}] gsd-t-doc-ripple → blast radius analysis + parallel updates
|
|
340
|
+
|
|
341
|
+
Task subagent (general-purpose, model: sonnet):
|
|
342
|
+
"Execute the doc-ripple workflow per commands/gsd-t-doc-ripple.md.
|
|
343
|
+
Git diff context: {files changed list}
|
|
344
|
+
Command that triggered: debug
|
|
345
|
+
Produce manifest at .gsd-t/doc-ripple-manifest.md.
|
|
346
|
+
Update all affected documents.
|
|
347
|
+
Report: 'Doc-ripple: {N} checked, {N} updated, {N} skipped'"
|
|
348
|
+
|
|
349
|
+
4. After doc-ripple returns, verify manifest exists and report summary inline
|
|
350
|
+
|
|
305
351
|
$ARGUMENTS
|
|
306
352
|
|
|
307
353
|
## Auto-Clear
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# GSD-T: Doc-Ripple — Automated Document Ripple Enforcement
|
|
2
|
+
|
|
3
|
+
You are the doc-ripple agent. You identify and update all downstream documents after code changes. You are spawned by execute, integrate, quick, debug, and wave after primary work is committed.
|
|
4
|
+
|
|
5
|
+
## Step 1: Load Context
|
|
6
|
+
|
|
7
|
+
Read:
|
|
8
|
+
1. `CLAUDE.md` — project conventions and Pre-Commit Gate (project-specific extensions)
|
|
9
|
+
2. `.gsd-t/contracts/doc-ripple-contract.md` — trigger conditions, manifest format, update protocol
|
|
10
|
+
3. `.gsd-t/contracts/pre-commit-gate.md` — the gate checklist you cross-reference
|
|
11
|
+
|
|
12
|
+
Run via Bash:
|
|
13
|
+
`git diff --name-only HEAD~1 2>/dev/null || git diff --cached --name-only`
|
|
14
|
+
|
|
15
|
+
Store the changed file list for Steps 2–3.
|
|
16
|
+
|
|
17
|
+
## Step 2: Threshold Check
|
|
18
|
+
|
|
19
|
+
Evaluate the changed file list against trigger conditions from `doc-ripple-contract.md`.
|
|
20
|
+
|
|
21
|
+
Output exactly:
|
|
22
|
+
```
|
|
23
|
+
DOC-RIPPLE THRESHOLD: {FIRE|SKIP}
|
|
24
|
+
Files changed: {N} across {N} directories
|
|
25
|
+
Cross-cutting signals: {list or "none"}
|
|
26
|
+
Reason: {brief explanation}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**If SKIP**: log the decision, output `Doc-ripple: SKIP — {reason}`, and stop. No manifest. No updates.
|
|
30
|
+
|
|
31
|
+
**If FIRE**: proceed to Step 3.
|
|
32
|
+
|
|
33
|
+
## Step 3: Blast Radius Analysis
|
|
34
|
+
|
|
35
|
+
For each changed file, classify its type: source, test, contract, template, command, doc, config.
|
|
36
|
+
|
|
37
|
+
Cross-reference `.gsd-t/contracts/pre-commit-gate.md` gate checklist:
|
|
38
|
+
- API endpoint/shape changed → api-contract.md, Swagger spec, CLAUDE.md, README.md
|
|
39
|
+
- Database schema changed → schema-contract.md, docs/schema.md
|
|
40
|
+
- UI component interface changed → component-contract.md
|
|
41
|
+
- New files or directories added → owning domain scope.md
|
|
42
|
+
- Requirement implemented or changed → docs/requirements.md
|
|
43
|
+
- Component or data flow changed → docs/architecture.md
|
|
44
|
+
- Any file modified → .gsd-t/progress.md (Decision Log entry)
|
|
45
|
+
- Architectural decision made → .gsd-t/progress.md (with rationale)
|
|
46
|
+
- Tech debt discovered or fixed → .gsd-t/techdebt.md
|
|
47
|
+
- New convention established → CLAUDE.md or domain constraints.md
|
|
48
|
+
- Command file added/changed → GSD-T-README.md, README.md, templates/CLAUDE-global.md, commands/gsd-t-help.md
|
|
49
|
+
- Command added/removed → all 4 above + package.json version + bin/gsd-t.js count
|
|
50
|
+
- Wave flow changed → gsd-t-wave.md, GSD-T-README.md, README.md
|
|
51
|
+
- Template changed → verify gsd-t-init output
|
|
52
|
+
|
|
53
|
+
Build the final list: `{ document, status (UPDATED|SKIPPED), action, reason }`.
|
|
54
|
+
|
|
55
|
+
## Step 4: Generate Manifest
|
|
56
|
+
|
|
57
|
+
Write `.gsd-t/doc-ripple-manifest.md` (overwrite):
|
|
58
|
+
|
|
59
|
+
```markdown
|
|
60
|
+
# Doc-Ripple Manifest — {date}
|
|
61
|
+
|
|
62
|
+
## Trigger
|
|
63
|
+
- Command: {triggering command}
|
|
64
|
+
- Files changed: {N}
|
|
65
|
+
- Threshold: FIRE — {reason}
|
|
66
|
+
|
|
67
|
+
## Blast Radius
|
|
68
|
+
|
|
69
|
+
| Document | Status | Action | Reason |
|
|
70
|
+
|----------|--------|--------|--------|
|
|
71
|
+
| {path} | {UPDATED|SKIPPED} | {action} | {reason} |
|
|
72
|
+
|
|
73
|
+
## Summary
|
|
74
|
+
- Documents checked: {N}
|
|
75
|
+
- Documents updated: {N}
|
|
76
|
+
- Documents skipped (already current): {N}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Step 5: Update Documents
|
|
80
|
+
|
|
81
|
+
Count documents marked UPDATED.
|
|
82
|
+
|
|
83
|
+
**Fewer than 3 updates — inline:**
|
|
84
|
+
For each document: read current content → determine minimal edit → apply via Edit tool (not Write) → verify after edit.
|
|
85
|
+
|
|
86
|
+
**3 or more updates — parallel subagents:**
|
|
87
|
+
|
|
88
|
+
For each document or logical group:
|
|
89
|
+
|
|
90
|
+
⚙ [haiku] gsd-t-doc-ripple → update {document}
|
|
91
|
+
(Use sonnet for docs/architecture.md and docs/requirements.md — these need reasoning.)
|
|
92
|
+
|
|
93
|
+
**OBSERVABILITY LOGGING (MANDATORY) — for each subagent spawn:**
|
|
94
|
+
|
|
95
|
+
Before spawning — run via Bash:
|
|
96
|
+
`T_START=$(date +%s) && DT_START=$(date +"%Y-%m-%d %H:%M") && TOK_START=${CLAUDE_CONTEXT_TOKENS_USED:-0} && TOK_MAX=${CLAUDE_CONTEXT_TOKENS_MAX:-200000}`
|
|
97
|
+
|
|
98
|
+
After subagent returns — run via Bash:
|
|
99
|
+
`T_END=$(date +%s) && DT_END=$(date +"%Y-%m-%d %H:%M") && TOK_END=${CLAUDE_CONTEXT_TOKENS_USED:-0} && DURATION=$((T_END-T_START))`
|
|
100
|
+
|
|
101
|
+
Compute tokens:
|
|
102
|
+
- No compaction (TOK_END >= TOK_START): `TOKENS=$((TOK_END-TOK_START))`, COMPACTED=null
|
|
103
|
+
- Compaction detected (TOK_END < TOK_START): `TOKENS=$(((TOK_MAX-TOK_START)+TOK_END))`, COMPACTED=$DT_END
|
|
104
|
+
|
|
105
|
+
Compute context utilization:
|
|
106
|
+
`if [ "${CLAUDE_CONTEXT_TOKENS_MAX:-0}" -gt 0 ]; then CTX_PCT=$(echo "scale=1; ${CLAUDE_CONTEXT_TOKENS_USED:-0} * 100 / ${CLAUDE_CONTEXT_TOKENS_MAX}" | bc); else CTX_PCT="N/A"; fi`
|
|
107
|
+
|
|
108
|
+
Alert thresholds:
|
|
109
|
+
- CTX_PCT >= 85: `echo "🔴 CRITICAL: Context at ${CTX_PCT}% — compaction likely. Task MUST be split."`
|
|
110
|
+
- CTX_PCT >= 70: `echo "⚠️ WARNING: Context at ${CTX_PCT}% — approaching compaction threshold. Consider splitting."`
|
|
111
|
+
|
|
112
|
+
Append to `.gsd-t/token-log.md` (create with header `| Datetime-start | Datetime-end | Command | Step | Model | Duration(s) | Notes | Tokens | Compacted | Domain | Task | Ctx% |` if missing):
|
|
113
|
+
`| {DT_START} | {DT_END} | gsd-t-doc-ripple | Step 5 | {model} | {DURATION}s | update:{document} | {TOKENS} | {COMPACTED} | doc-ripple | — | {CTX_PCT} |`
|
|
114
|
+
|
|
115
|
+
**Each document-update subagent prompt:**
|
|
116
|
+
```
|
|
117
|
+
Task subagent (general-purpose, model: {haiku|sonnet}):
|
|
118
|
+
"Update a single document as part of doc-ripple enforcement.
|
|
119
|
+
|
|
120
|
+
Document to update: {path}
|
|
121
|
+
Action: {action from manifest}
|
|
122
|
+
Reason: {reason from manifest}
|
|
123
|
+
Git diff context (changed files): {file list}
|
|
124
|
+
|
|
125
|
+
Instructions:
|
|
126
|
+
1. Read the current document
|
|
127
|
+
2. Apply the minimal edit — add/update only the affected section
|
|
128
|
+
3. Use the Edit tool (not Write) — preserve all existing content
|
|
129
|
+
4. Re-read after edit to confirm correctness
|
|
130
|
+
5. Report: 'Updated {document} — {one-line summary of change}'"
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Step 6: Report Summary
|
|
134
|
+
|
|
135
|
+
Output:
|
|
136
|
+
```
|
|
137
|
+
Doc-ripple: {N} checked, {N} updated, {N} skipped
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
List each updated document with a one-line summary of what changed.
|
|
141
|
+
|
|
142
|
+
If any update failed, list it under `Failures:` and flag for manual review.
|
|
143
|
+
|
|
144
|
+
$ARGUMENTS
|
|
145
|
+
|
|
146
|
+
## Auto-Clear
|
|
147
|
+
|
|
148
|
+
All work is written to project files. Execute `/clear` to free the context window for the next command.
|
|
@@ -119,6 +119,22 @@ Run via Bash:
|
|
|
119
119
|
If rules fire: inject up to 10 lines of rule warnings into each task subagent prompt (concise format: `RULE: {name} — {description}`). These inform the subagent of known patterns — non-blocking.
|
|
120
120
|
If no rules fire: log "No active rules for {domain-name}" and continue.
|
|
121
121
|
|
|
122
|
+
**Stack Rules Detection (before spawning subagent):**
|
|
123
|
+
Run via Bash to detect project stack and collect matching rules:
|
|
124
|
+
`GSD_T_DIR=$(npm root -g 2>/dev/null)/@tekyzinc/gsd-t; STACKS_DIR="$GSD_T_DIR/templates/stacks"; STACK_RULES=""; if [ -d "$STACKS_DIR" ]; then for f in "$STACKS_DIR"/_*.md; do [ -f "$f" ] && STACK_RULES="${STACK_RULES}$(cat "$f")"$'\n\n'; done; if [ -f "package.json" ]; then grep -q '"react-native"' package.json 2>/dev/null && [ -f "$STACKS_DIR/react-native.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/react-native.md")"$'\n\n'; grep -q '"react"' package.json 2>/dev/null && ! grep -q '"react-native"' package.json 2>/dev/null && [ -f "$STACKS_DIR/react.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/react.md")"$'\n\n'; grep -q '"next"' package.json 2>/dev/null && [ -f "$STACKS_DIR/nextjs.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/nextjs.md")"$'\n\n'; grep -q '"vue"' package.json 2>/dev/null && [ -f "$STACKS_DIR/vue.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/vue.md")"$'\n\n'; (grep -q '"typescript"' package.json 2>/dev/null || [ -f "tsconfig.json" ]) && [ -f "$STACKS_DIR/typescript.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/typescript.md")"$'\n\n'; grep -qE '"(express|fastify|hono|koa)"' package.json 2>/dev/null && [ -f "$STACKS_DIR/node-api.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/node-api.md")"$'\n\n'; grep -qE '"(express|fastify|hono|koa)"' package.json 2>/dev/null && [ -f "$STACKS_DIR/rest-api.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/rest-api.md")"$'\n\n'; grep -q '"tailwindcss"' package.json 2>/dev/null && [ -f "$STACKS_DIR/tailwind.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/tailwind.md")"$'\n\n'; grep -q '"vite"' package.json 2>/dev/null && [ -f "$STACKS_DIR/vite.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/vite.md")"$'\n\n'; grep -q '"@supabase/supabase-js"' package.json 2>/dev/null && [ -f "$STACKS_DIR/supabase.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/supabase.md")"$'\n\n'; grep -q '"firebase"' package.json 2>/dev/null && [ -f "$STACKS_DIR/firebase.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/firebase.md")"$'\n\n'; grep -qE '"(graphql|@apollo/client|urql)"' package.json 2>/dev/null && [ -f "$STACKS_DIR/graphql.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/graphql.md")"$'\n\n'; grep -q '"zustand"' package.json 2>/dev/null && [ -f "$STACKS_DIR/zustand.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/zustand.md")"$'\n\n'; grep -q '"@reduxjs/toolkit"' package.json 2>/dev/null && [ -f "$STACKS_DIR/redux.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/redux.md")"$'\n\n'; grep -q '"neo4j-driver"' package.json 2>/dev/null && [ -f "$STACKS_DIR/neo4j.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/neo4j.md")"$'\n\n'; grep -qE '"(pg|prisma|drizzle-orm|knex)"' package.json 2>/dev/null && [ -f "$STACKS_DIR/postgresql.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/postgresql.md")"$'\n\n'; fi; ([ -f "requirements.txt" ] || [ -f "pyproject.toml" ] || [ -f "Pipfile" ]) && [ -f "$STACKS_DIR/python.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/python.md")"$'\n\n'; ([ -f "requirements.txt" ] && grep -q "psycopg" requirements.txt 2>/dev/null || [ -f "pyproject.toml" ] && grep -q "psycopg" pyproject.toml 2>/dev/null) && [ -f "$STACKS_DIR/postgresql.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/postgresql.md")"$'\n\n'; ([ -f "requirements.txt" ] && grep -q "neo4j" requirements.txt 2>/dev/null) && [ -f "$STACKS_DIR/neo4j.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/neo4j.md")"$'\n\n'; [ -f "pubspec.yaml" ] && [ -f "$STACKS_DIR/flutter.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/flutter.md")"$'\n\n'; [ -f "Dockerfile" ] && [ -f "$STACKS_DIR/docker.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/docker.md")"$'\n\n'; [ -d ".github/workflows" ] && [ -f "$STACKS_DIR/github-actions.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/github-actions.md")"$'\n\n'; ([ -f "playwright.config.ts" ] || [ -f "playwright.config.js" ]) && [ -f "$STACKS_DIR/playwright.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/playwright.md")"$'\n\n'; [ -f "go.mod" ] && [ -f "$STACKS_DIR/go.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/go.md")"$'\n\n'; [ -f "Cargo.toml" ] && [ -f "$STACKS_DIR/rust.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/rust.md")"$'\n\n'; fi`
|
|
125
|
+
|
|
126
|
+
If STACK_RULES is non-empty, append to the subagent prompt:
|
|
127
|
+
```
|
|
128
|
+
## Stack Rules (MANDATORY — violations fail this task)
|
|
129
|
+
|
|
130
|
+
{STACK_RULES}
|
|
131
|
+
|
|
132
|
+
These standards have the same enforcement weight as contract compliance.
|
|
133
|
+
Violations are task failures, not warnings.
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
If STACK_RULES is empty (no templates/stacks/ dir or no matches), skip silently.
|
|
137
|
+
|
|
122
138
|
**Domain task-dispatcher (lightweight — sequences tasks, passes summaries):**
|
|
123
139
|
|
|
124
140
|
For each task in `.gsd-t/domains/{domain-name}/tasks.md` (in order, skip completed):
|
|
@@ -150,6 +166,9 @@ Task subagent (general-purpose, model: sonnet, mode: bypassPermissions):
|
|
|
150
166
|
## Prior Task Summaries (most recent first, max 5)
|
|
151
167
|
{contents of task-{N}-summary.md files — 10-20 lines each}
|
|
152
168
|
|
|
169
|
+
## Stack Rules
|
|
170
|
+
{STACK_RULES if non-empty — omit entire section if empty}
|
|
171
|
+
|
|
153
172
|
## Instructions
|
|
154
173
|
|
|
155
174
|
Execute the task above:
|
|
@@ -168,6 +187,26 @@ Execute the task above:
|
|
|
168
187
|
- If the project has a UI but no Playwright E2E specs exist for the features being
|
|
169
188
|
touched: WRITE THEM. A placeholder spec is not sufficient — write real E2E tests
|
|
170
189
|
that exercise the actual UI functionality being built or changed.
|
|
190
|
+
- **FUNCTIONAL E2E TESTS — NOT LAYOUT TESTS (MANDATORY)**:
|
|
191
|
+
E2E tests that only check element existence (isVisible, isEnabled, toBeAttached)
|
|
192
|
+
are LAYOUT tests, not functional tests. Layout tests pass even when every feature
|
|
193
|
+
is broken. Every Playwright spec MUST verify functional behavior:
|
|
194
|
+
a. **State changes**: After an action (click, type, submit), assert the app STATE
|
|
195
|
+
changed — not just that the button was clickable. Example: clicking a tab must
|
|
196
|
+
load different content; verify the content changed, not just that the tab exists.
|
|
197
|
+
b. **Data flow**: Form submissions must verify data arrived (API call made, response
|
|
198
|
+
rendered, list updated). Don't just assert the form rendered.
|
|
199
|
+
c. **Navigation/routing**: Tab/page switches must verify the NEW content loaded.
|
|
200
|
+
Assert on content unique to the destination, not the navigation element itself.
|
|
201
|
+
d. **Interactive widgets**: Terminals must accept input and produce output. Editors
|
|
202
|
+
must save changes. Panels must load their functional content after opening.
|
|
203
|
+
e. **Network integration**: If a feature requires WebSocket/API connection, verify
|
|
204
|
+
the connection status changes (e.g., "Disconnected" → "Connected") and that
|
|
205
|
+
messages flow through the connection.
|
|
206
|
+
f. **Error recovery**: Don't just check error messages render — verify the app
|
|
207
|
+
recovers (retry button works, form can be resubmitted, etc.).
|
|
208
|
+
A test that would pass on an empty HTML page with the right element IDs is useless.
|
|
209
|
+
Every assertion must prove the FEATURE WORKS, not that the ELEMENT EXISTS.
|
|
171
210
|
7. Run ALL test suites — this is NOT optional, not conditional, not "if applicable":
|
|
172
211
|
a. Detect configured test runners: check for vitest/jest config, playwright.config.*, cypress.config.*
|
|
173
212
|
b. Run EVERY detected suite. Unit tests alone are NEVER sufficient when E2E exists.
|
|
@@ -187,8 +226,15 @@ Execute the task above:
|
|
|
187
226
|
b. E2E tests: check for playwright.config.* or cypress.config.* — if found, run the FULL E2E suite
|
|
188
227
|
c. NEVER skip E2E when a config file exists. Running only unit tests is a QA FAILURE.
|
|
189
228
|
d. Read .gsd-t/contracts/ for contract definitions. Check contract compliance.
|
|
190
|
-
|
|
191
|
-
|
|
229
|
+
e. AUDIT E2E test quality: Review each Playwright spec — if any test only checks
|
|
230
|
+
element existence (isVisible, toBeAttached, toBeEnabled) without verifying functional
|
|
231
|
+
behavior (state changes, data loaded, content updated after actions), flag it as
|
|
232
|
+
"SHALLOW TEST — needs functional assertions" in the gap report. A test suite where
|
|
233
|
+
every spec passes but no feature actually works is a QA FAILURE.
|
|
234
|
+
Report format: "Unit: X/Y pass | E2E: X/Y pass (or N/A if no config) | Contract: compliant/violations | Shallow tests: N (list) | Stack rules: compliant/N violations"
|
|
235
|
+
f. Validate compliance with Stack Rules (if injected in the work subagent's prompt).
|
|
236
|
+
Stack rule violations have the same severity as contract violations — report as failures, not warnings.'
|
|
237
|
+
If QA fails OR shallow tests are found, fix before proceeding. Append issues to .gsd-t/qa-issues.md.
|
|
192
238
|
12. Write task summary to .gsd-t/domains/{domain-name}/task-{task-id}-summary.md:
|
|
193
239
|
## Task {task-id} Summary — {domain-name}
|
|
194
240
|
- **Status**: PASS | FAIL
|
|
@@ -198,8 +244,15 @@ Execute the task above:
|
|
|
198
244
|
- **Notes**: {10-20 lines max — key decisions, patterns, warnings}
|
|
199
245
|
|
|
200
246
|
Deviation rules:
|
|
201
|
-
- Bug blocking progress → fix, max 3 attempts;
|
|
202
|
-
.gsd-t/
|
|
247
|
+
- Bug blocking progress → fix, max 3 attempts; after fix attempt 2 fails:
|
|
248
|
+
1. Write current failure context to .gsd-t/debug-state.jsonl via appendEntry
|
|
249
|
+
2. Log: "Delegating to headless debug-loop (2 in-context attempts exhausted)"
|
|
250
|
+
3. Run: `gsd-t headless --debug-loop --max-iterations 15`
|
|
251
|
+
4. Check exit code:
|
|
252
|
+
- 0: Tests pass, continue with task
|
|
253
|
+
- 1/4: Log to .gsd-t/deferred-items.md and stop (report FAIL in summary)
|
|
254
|
+
- 3: Report error, stop
|
|
255
|
+
If still blocked after debug-loop, log to .gsd-t/deferred-items.md and stop (report FAIL in summary)
|
|
203
256
|
- Missing dependency → add minimum needed, document in commit message
|
|
204
257
|
- Non-trivial blocker → log to .gsd-t/deferred-items.md
|
|
205
258
|
- Architectural change required → write NEEDS-APPROVAL to .gsd-t/deferred-items.md,
|
|
@@ -275,10 +328,11 @@ RULES FOR ALL TEAMMATES:
|
|
|
275
328
|
- **Destructive Action Guard**: NEVER drop tables, remove columns, delete data, replace architecture patterns, or remove working modules without messaging the lead first. The lead must get user approval before any destructive action proceeds.
|
|
276
329
|
- Only modify files listed in your domain's scope.md
|
|
277
330
|
- Implement interfaces EXACTLY as specified in contracts
|
|
278
|
-
- **Write comprehensive tests with every task** — no feature code without test code:
|
|
331
|
+
- **Write comprehensive FUNCTIONAL tests with every task** — no feature code without test code:
|
|
279
332
|
- Unit/integration tests: happy path + edge cases + error cases for every new/changed function
|
|
280
333
|
- Playwright E2E specs (if UI/routes/flows/modes changed): new specs for new features, cover all modes/flags, form validation, empty/loading/error states, common edge cases
|
|
281
334
|
- Tests are part of the deliverable, not a follow-up
|
|
335
|
+
- **E2E tests MUST be functional, not layout tests**: Every assertion must verify an action produced the correct outcome (state changed, data loaded, content updated) — NOT just that an element is visible/clickable. A test that passes on an empty HTML shell with correct IDs is worthless. See the Functional E2E Test Requirements in the solo mode instructions above.
|
|
282
336
|
- If a task is marked BLOCKED, message the lead and wait
|
|
283
337
|
- Run the Pre-Commit Gate checklist from CLAUDE.md BEFORE every commit — update all affected docs
|
|
284
338
|
- **Commit immediately after each task**: `feat({domain}/task-{N}): {description}` — do NOT batch commits
|
|
@@ -399,6 +453,29 @@ After all merges complete (whether all passed, some rolled back, or errors occur
|
|
|
399
453
|
Cleanup is not optional — orphaned worktrees waste disk space and can confuse subsequent executions. Always run cleanup, even if earlier steps failed.
|
|
400
454
|
```
|
|
401
455
|
|
|
456
|
+
## Step 3.5: Orchestrator Context Self-Check (MANDATORY)
|
|
457
|
+
|
|
458
|
+
After EVERY domain completes (and after every checkpoint), the orchestrator MUST check its own context utilization:
|
|
459
|
+
|
|
460
|
+
Run via Bash:
|
|
461
|
+
`if [ "${CLAUDE_CONTEXT_TOKENS_MAX:-0}" -gt 0 ]; then CTX_PCT=$(echo "scale=1; ${CLAUDE_CONTEXT_TOKENS_USED:-0} * 100 / ${CLAUDE_CONTEXT_TOKENS_MAX}" | bc); else CTX_PCT="N/A"; fi && echo "Orchestrator context: ${CTX_PCT}%"`
|
|
462
|
+
|
|
463
|
+
**If CTX_PCT >= 70:**
|
|
464
|
+
1. **Save checkpoint to disk** — update `.gsd-t/progress.md` with:
|
|
465
|
+
- Which domains are complete, which remain
|
|
466
|
+
- Current wave, next domain to execute
|
|
467
|
+
- Any checkpoint results
|
|
468
|
+
2. **Instruct user**: Output exactly:
|
|
469
|
+
```
|
|
470
|
+
⚠️ Orchestrator context at {CTX_PCT}% — approaching limit.
|
|
471
|
+
Progress saved. Run `/clear` then `/user:gsd-t-execute` to continue from the next domain.
|
|
472
|
+
```
|
|
473
|
+
3. **STOP execution.** Do NOT spawn another domain subagent. The next session will resume from saved state.
|
|
474
|
+
|
|
475
|
+
**If CTX_PCT < 70:** Continue normally to the next domain/wave.
|
|
476
|
+
|
|
477
|
+
This prevents the orchestrator from running out of context mid-milestone, which causes session breaks and summary-based recovery.
|
|
478
|
+
|
|
402
479
|
## Step 4: Checkpoint Handling
|
|
403
480
|
|
|
404
481
|
When a checkpoint is reached (solo or team):
|
|
@@ -451,6 +528,26 @@ When all tasks in all domains are complete:
|
|
|
451
528
|
|
|
452
529
|
**Level 1–2**: Report completion summary and recommend proceeding to integrate phase. Wait for confirmation.
|
|
453
530
|
|
|
531
|
+
## Step 7: Doc-Ripple (Automated)
|
|
532
|
+
|
|
533
|
+
After all work is committed but before reporting completion:
|
|
534
|
+
|
|
535
|
+
1. Run threshold check — read `git diff --name-only HEAD~1` and evaluate against doc-ripple-contract.md trigger conditions
|
|
536
|
+
2. If SKIP: log "Doc-ripple: SKIP — {reason}" and proceed to completion
|
|
537
|
+
3. If FIRE: spawn doc-ripple agent:
|
|
538
|
+
|
|
539
|
+
⚙ [{model}] gsd-t-doc-ripple → blast radius analysis + parallel updates
|
|
540
|
+
|
|
541
|
+
Task subagent (general-purpose, model: sonnet):
|
|
542
|
+
"Execute the doc-ripple workflow per commands/gsd-t-doc-ripple.md.
|
|
543
|
+
Git diff context: {files changed list}
|
|
544
|
+
Command that triggered: execute
|
|
545
|
+
Produce manifest at .gsd-t/doc-ripple-manifest.md.
|
|
546
|
+
Update all affected documents.
|
|
547
|
+
Report: 'Doc-ripple: {N} checked, {N} updated, {N} skipped'"
|
|
548
|
+
|
|
549
|
+
4. After doc-ripple returns, verify manifest exists and report summary inline
|
|
550
|
+
|
|
454
551
|
## Document Ripple
|
|
455
552
|
|
|
456
553
|
Execute modifies source code, so the Pre-Commit Gate (referenced in Step 9) covers document updates. For clarity, the key documents affected by execution:
|
package/commands/gsd-t-help.md
CHANGED
|
@@ -38,6 +38,7 @@ MILESTONE WORKFLOW [auto] = in wave
|
|
|
38
38
|
execute [auto] Run tasks (solo or team mode)
|
|
39
39
|
test-sync [auto] Sync tests with code changes
|
|
40
40
|
qa [auto] QA agent — test generation, execution, gap reporting
|
|
41
|
+
doc-ripple [auto] Automated document ripple — update docs after code changes
|
|
41
42
|
integrate [auto] Wire domains together at boundaries
|
|
42
43
|
verify [auto] Run quality gates → auto-invokes complete-milestone
|
|
43
44
|
complete-milestone [auto] Archive milestone + git tag (auto-invoked by verify)
|
|
@@ -64,6 +65,12 @@ UTILITIES Manual
|
|
|
64
65
|
triage-and-merge Auto-review, merge, and publish GitHub branches
|
|
65
66
|
global-change Apply file changes across all registered GSD-T projects
|
|
66
67
|
|
|
68
|
+
HEADLESS (CI/CD) CLI
|
|
69
|
+
───────────────────────────────────────────────────────────────────────────────
|
|
70
|
+
headless exec Run any GSD-T command non-interactively via claude -p
|
|
71
|
+
headless query Read project state without LLM (<100ms)
|
|
72
|
+
headless --debug-loop Compaction-proof test-fix-retest loop (fresh sessions)
|
|
73
|
+
|
|
67
74
|
BACKLOG Manual
|
|
68
75
|
───────────────────────────────────────────────────────────────────────────────
|
|
69
76
|
backlog-add Capture item, auto-categorize, append to backlog
|
|
@@ -251,6 +258,7 @@ Use these when user asks for help on a specific command:
|
|
|
251
258
|
- **Use when**: Ready to implement
|
|
252
259
|
- **Note (M22)**: Task-level fresh dispatch (one subagent per task, ~10-20% context each). Team mode uses worktree isolation (`isolation: "worktree"`) — zero file conflicts. Adaptive replanning between domain completions.
|
|
253
260
|
- **Note (M26)**: Active rule injection — evaluates declarative rules from rules.jsonl before dispatching each domain's tasks. Fires matching rules as warnings in subagent prompts.
|
|
261
|
+
- **Note (M29)**: Stack Rules Engine — auto-detects project tech stack from manifest files and injects mandatory best-practice rules into each task subagent prompt. Universal rules (`_security.md`) always apply; stack-specific rules layer on top. Violations are task failures (same weight as contract violations).
|
|
254
262
|
|
|
255
263
|
### test-sync
|
|
256
264
|
- **Summary**: Keep tests aligned with code changes
|
|
@@ -264,6 +272,12 @@ Use these when user asks for help on a specific command:
|
|
|
264
272
|
- **Creates**: Contract test skeletons, acceptance tests, edge case tests, test audit reports
|
|
265
273
|
- **Use when**: Automatically spawned — never needs manual invocation. Standalone use for ad-hoc test audits.
|
|
266
274
|
|
|
275
|
+
### doc-ripple
|
|
276
|
+
- **Summary**: Automated document ripple — identifies and updates all downstream docs after code changes
|
|
277
|
+
- **Auto-invoked**: Yes (after primary work in execute, integrate, quick, debug, wave)
|
|
278
|
+
- **Creates**: `.gsd-t/doc-ripple-manifest.md`
|
|
279
|
+
- **Use when**: Automatically spawned — never needs manual invocation. Standalone use for ad-hoc doc sync audits.
|
|
280
|
+
|
|
267
281
|
### integrate
|
|
268
282
|
- **Summary**: Wire domains together at their boundaries
|
|
269
283
|
- **Auto-invoked**: Yes (in wave, after execute)
|
|
@@ -332,11 +346,20 @@ Use these when user asks for help on a specific command:
|
|
|
332
346
|
- **Use when**: Reviewing process health, first-pass rates, ELO trends, anomaly flags, or comparing signal distributions across projects
|
|
333
347
|
|
|
334
348
|
### debug
|
|
335
|
-
- **Summary**: Systematic debugging with persistent state
|
|
349
|
+
- **Summary**: Systematic debugging with persistent state; delegates to `gsd-t headless --debug-loop` after 2 failed in-context fix attempts
|
|
336
350
|
- **Auto-invoked**: No
|
|
337
|
-
- **Creates**: Debug session state
|
|
351
|
+
- **Creates**: Debug session state, `.gsd-t/debug-state.jsonl` (when delegating to headless loop)
|
|
338
352
|
- **Use when**: Tracking down a bug methodically
|
|
339
353
|
|
|
354
|
+
### headless --debug-loop
|
|
355
|
+
- **Summary**: Compaction-proof automated test-fix-retest loop — each iteration is a fresh `claude -p` session; a cumulative ledger (`.gsd-t/debug-state.jsonl`) preserves all hypothesis/fix/learning history; anti-repetition preamble prevents retrying failed approaches
|
|
356
|
+
- **Auto-invoked**: Yes — by `execute`, `test-sync`, `verify`, `debug`, and `wave` after 2 failed in-context fix attempts
|
|
357
|
+
- **Flags**: `--max-iterations=N` (default 20), `--test-cmd=CMD`, `--fix-scope=PATTERN`, `--json`, `--log`
|
|
358
|
+
- **Escalation**: sonnet (iterations 1–5) → opus (6–15) → STOP with diagnostic summary (16–20)
|
|
359
|
+
- **Exit codes**: `0` pass · `1` max iterations · `2` compaction error · `3` process error · `4` needs human
|
|
360
|
+
- **Creates**: `.gsd-t/debug-state.jsonl`, optional `.gsd-t/headless-{ts}.log`
|
|
361
|
+
- **Use when**: Running automated fix loops in CI, or delegated from in-context commands that exhausted fix attempts
|
|
362
|
+
|
|
340
363
|
### promote-debt
|
|
341
364
|
- **Summary**: Convert techdebt.md items into milestones
|
|
342
365
|
- **Auto-invoked**: No
|
|
@@ -62,6 +62,22 @@ If rolled-back domains exist, report them to the user (or if Level 3: log to `.g
|
|
|
62
62
|
|
|
63
63
|
## Step 3: Wire Integration Points
|
|
64
64
|
|
|
65
|
+
**Stack Rules Detection (before spawning subagent):**
|
|
66
|
+
Run via Bash to detect project stack and collect matching rules:
|
|
67
|
+
`GSD_T_DIR=$(npm root -g 2>/dev/null)/@tekyzinc/gsd-t; STACKS_DIR="$GSD_T_DIR/templates/stacks"; STACK_RULES=""; if [ -d "$STACKS_DIR" ]; then for f in "$STACKS_DIR"/_*.md; do [ -f "$f" ] && STACK_RULES="${STACK_RULES}$(cat "$f")"$'\n\n'; done; if [ -f "package.json" ]; then grep -q '"react"' package.json 2>/dev/null && [ -f "$STACKS_DIR/react.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/react.md")"$'\n\n'; (grep -q '"typescript"' package.json 2>/dev/null || [ -f "tsconfig.json" ]) && [ -f "$STACKS_DIR/typescript.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/typescript.md")"$'\n\n'; grep -qE '"(express|fastify|hono|koa)"' package.json 2>/dev/null && [ -f "$STACKS_DIR/node-api.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/node-api.md")"$'\n\n'; fi; [ -f "requirements.txt" ] || [ -f "pyproject.toml" ] && [ -f "$STACKS_DIR/python.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/python.md")"$'\n\n'; [ -f "go.mod" ] && [ -f "$STACKS_DIR/go.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/go.md")"$'\n\n'; [ -f "Cargo.toml" ] && [ -f "$STACKS_DIR/rust.md" ] && STACK_RULES="${STACK_RULES}$(cat "$STACKS_DIR/rust.md")"$'\n\n'; fi`
|
|
68
|
+
|
|
69
|
+
If STACK_RULES is non-empty, append to the subagent prompt:
|
|
70
|
+
```
|
|
71
|
+
## Stack Rules (MANDATORY — violations fail this task)
|
|
72
|
+
|
|
73
|
+
{STACK_RULES}
|
|
74
|
+
|
|
75
|
+
These standards have the same enforcement weight as contract compliance.
|
|
76
|
+
Violations are task failures, not warnings.
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
If STACK_RULES is empty (no templates/stacks/ dir or no matches), skip silently.
|
|
80
|
+
|
|
65
81
|
Work through each integration point in `integration-points.md`. If integration work spans multiple domains with independent tasks, use the **task-level dispatch pattern** (per fresh-dispatch-contract.md): spawn one Task subagent per integration task, passing only the relevant contracts, the specific integration point to wire, and summaries from prior integration tasks (max 5, 10-20 lines each). This prevents context accumulation across integration tasks.
|
|
66
82
|
|
|
67
83
|
**Multi-domain integration merging**: If integration work itself requires merging domain outputs that weren't merged during execute (e.g., domains executed in separate waves and integration needs to combine them), use the Sequential Merge Protocol from `.gsd-t/contracts/worktree-isolation-contract.md`:
|
|
@@ -126,7 +142,10 @@ Run ALL configured test suites — detect and run every one:
|
|
|
126
142
|
a. Unit tests (vitest/jest/mocha): run the full suite
|
|
127
143
|
b. E2E tests: check for playwright.config.* or cypress.config.* — if found, run the FULL E2E suite
|
|
128
144
|
c. NEVER skip E2E when a config file exists. Running only unit tests is a QA FAILURE.
|
|
129
|
-
|
|
145
|
+
d. AUDIT E2E test quality: Review each Playwright spec — if any test only checks element existence
|
|
146
|
+
(isVisible, toBeAttached, toBeEnabled) without verifying functional behavior (state changes,
|
|
147
|
+
data loaded, content updated after actions), flag it as 'SHALLOW TEST — needs functional assertions'.
|
|
148
|
+
Report: 'Unit: X/Y pass | E2E: X/Y pass (or N/A if no config) | Boundary: pass/fail by contract | Shallow tests: N'"
|
|
130
149
|
```
|
|
131
150
|
|
|
132
151
|
**OBSERVABILITY LOGGING (MANDATORY):**
|
|
@@ -176,8 +195,29 @@ After integration and doc ripple, verify everything works together:
|
|
|
176
195
|
c. Unit tests alone are NEVER sufficient when E2E exists
|
|
177
196
|
d. Report: "Unit: X/Y pass | E2E: X/Y pass"
|
|
178
197
|
3. **Verify passing**: All tests must pass. If any fail, fix before proceeding (up to 2 attempts)
|
|
198
|
+
4. **Functional test quality**: Spot-check E2E specs — every assertion must verify functional behavior (state changed, data loaded, content updated after action), not just element existence. Shallow tests that would pass on an empty HTML page are not acceptable.
|
|
179
199
|
5. **Smoke test results**: Ensure the Step 4 smoke test results are still valid after any fixes
|
|
180
200
|
|
|
201
|
+
## Step 7.5: Doc-Ripple (Automated)
|
|
202
|
+
|
|
203
|
+
After all integration work is committed but before reporting completion:
|
|
204
|
+
|
|
205
|
+
1. Run threshold check — read `git diff --name-only HEAD~1` and evaluate against doc-ripple-contract.md trigger conditions
|
|
206
|
+
2. If SKIP: log "Doc-ripple: SKIP — {reason}" and proceed to completion
|
|
207
|
+
3. If FIRE: spawn doc-ripple agent:
|
|
208
|
+
|
|
209
|
+
⚙ [{model}] gsd-t-doc-ripple → blast radius analysis + parallel updates
|
|
210
|
+
|
|
211
|
+
Task subagent (general-purpose, model: sonnet):
|
|
212
|
+
"Execute the doc-ripple workflow per commands/gsd-t-doc-ripple.md.
|
|
213
|
+
Git diff context: {files changed list}
|
|
214
|
+
Command that triggered: integrate
|
|
215
|
+
Produce manifest at .gsd-t/doc-ripple-manifest.md.
|
|
216
|
+
Update all affected documents.
|
|
217
|
+
Report: 'Doc-ripple: {N} checked, {N} updated, {N} skipped'"
|
|
218
|
+
|
|
219
|
+
4. After doc-ripple returns, verify manifest exists and report summary inline
|
|
220
|
+
|
|
181
221
|
## Step 8: Handle Integration Issues
|
|
182
222
|
|
|
183
223
|
For each issue found:
|
package/commands/gsd-t-qa.md
CHANGED
|
@@ -81,13 +81,16 @@ Your behavior depends on which phase spawned you:
|
|
|
81
81
|
|
|
82
82
|
### During Verify
|
|
83
83
|
**Trigger**: Lead invokes verify phase
|
|
84
|
-
**Action**: Full test audit
|
|
84
|
+
**Action**: Full test audit + shallow test detection
|
|
85
85
|
|
|
86
86
|
1. Run ALL tests — contract tests, acceptance tests, edge case tests, existing project tests
|
|
87
87
|
2. Coverage audit: For every contract, confirm tests exist and pass
|
|
88
88
|
3. For every new feature/mode/flow, confirm Playwright specs cover happy path, error states, edge cases
|
|
89
|
-
4.
|
|
90
|
-
5.
|
|
89
|
+
4. **Shallow test audit**: Read every Playwright spec file. For each `test()` block, check whether the assertions verify functional behavior (state changes, data flow, content updates after actions) or only check element existence (isVisible, toBeAttached, toBeEnabled). Flag any test that would pass on an empty HTML shell as `SHALLOW — needs functional assertions`.
|
|
90
|
+
5. Gap report: List any untested contracts, code paths, AND shallow tests
|
|
91
|
+
6. Report: `QA: {pass|fail} — {N} contract tests, {N} acceptance tests, {N} edge case tests. Gaps: {list or "none"}. Shallow E2E tests: {N} (list or "none")`
|
|
92
|
+
|
|
93
|
+
**Shallow tests block verification.** A passing E2E suite where tests don't actually verify feature behavior is equivalent to a failing suite.
|
|
91
94
|
|
|
92
95
|
### During Quick
|
|
93
96
|
**Trigger**: Lead runs a quick task
|
|
@@ -189,10 +192,28 @@ For each table in `schema-contract.md`:
|
|
|
189
192
|
For each component in `component-contract.md`:
|
|
190
193
|
- Each `## ComponentName` → one `test.describe` block
|
|
191
194
|
- `Props:` → renders with required props, handles missing optional props
|
|
192
|
-
- `Events:` → event handlers fire correctly
|
|
193
|
-
- API references → verify correct API calls made
|
|
195
|
+
- `Events:` → event handlers fire correctly AND produce the expected state change
|
|
196
|
+
- API references → verify correct API calls made AND responses rendered correctly
|
|
194
197
|
- Auto-generate: empty form, partial form, network error handling
|
|
195
198
|
|
|
199
|
+
### Functional E2E Test Standard (MANDATORY for all Playwright specs)
|
|
200
|
+
|
|
201
|
+
**E2E tests that only verify element existence are LAYOUT tests, not functional tests. Layout tests pass even when every feature is broken. This is a QA failure.**
|
|
202
|
+
|
|
203
|
+
Every Playwright spec MUST verify functional behavior — that actions produce the correct outcome:
|
|
204
|
+
|
|
205
|
+
| Test Pattern | WRONG (layout test) | RIGHT (functional test) |
|
|
206
|
+
|---|---|---|
|
|
207
|
+
| Tab switching | `expect(tab).toBeVisible()` | Click tab → assert NEW content loaded (text, data unique to that tab) |
|
|
208
|
+
| Form submit | `expect(submitBtn).toBeEnabled()` | Fill form → submit → assert success message AND data persisted (API call, list updated) |
|
|
209
|
+
| Terminal/editor | `expect(terminal).toBeAttached()` | Open terminal → type command → assert output appears |
|
|
210
|
+
| WebSocket | `expect(statusBadge).toBeVisible()` | Wait for connection → assert status text changes to "Connected" → send message → assert response |
|
|
211
|
+
| Navigation | `expect(link).toHaveAttribute('href')` | Click link → assert URL changed AND destination content rendered |
|
|
212
|
+
| Toggle/mode | `expect(toggle).toBeVisible()` | Click toggle → assert the EFFECT (dark mode CSS applied, panel expanded with content, feature enabled) |
|
|
213
|
+
| Error state | `expect(errorDiv).toBeVisible()` | Trigger error → assert message content → assert recovery action works |
|
|
214
|
+
|
|
215
|
+
**Rule: If a test would pass on an empty HTML shell with the right element IDs, it is not a functional test. Every assertion must prove the feature works, not that the element exists.**
|
|
216
|
+
|
|
196
217
|
## Test File Conventions
|
|
197
218
|
|
|
198
219
|
- **Location**: Project's test directory (detected from `playwright.config.*` or `package.json`)
|