prizmkit 1.0.87 → 1.0.89
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/bundled/VERSION.json +3 -3
- package/bundled/agents/prizm-dev-team-dev.md +14 -3
- package/bundled/agents/prizm-dev-team-reviewer.md +6 -2
- package/bundled/dev-pipeline/retry-bug.sh +17 -25
- package/bundled/dev-pipeline/retry-feature.sh +17 -25
- package/bundled/dev-pipeline/run-bugfix.sh +18 -21
- package/bundled/dev-pipeline/run.sh +18 -37
- package/bundled/dev-pipeline/templates/bootstrap-tier1.md +14 -2
- package/bundled/dev-pipeline/templates/bootstrap-tier2.md +5 -3
- package/bundled/dev-pipeline/templates/bootstrap-tier3.md +8 -4
- package/bundled/skills/_metadata.json +1 -1
- package/package.json +1 -1
package/bundled/VERSION.json
CHANGED
|
@@ -18,7 +18,11 @@ You are the team's "construction worker" — you build strictly according to blu
|
|
|
18
18
|
|
|
19
19
|
### Project Context
|
|
20
20
|
|
|
21
|
-
Project documentation is in `.prizm-docs/`. Before implementation, read `context-snapshot.md` (if it exists in `.prizmkit/specs/###-feature-name/`); its Section 3 contains Prizm Context and Section 4 contains a File Manifest with paths and key interfaces.
|
|
21
|
+
Project documentation is in `.prizm-docs/`. Before implementation, read `context-snapshot.md` (if it exists in `.prizmkit/specs/###-feature-name/`); its Section 3 contains Prizm Context and Section 4 contains a File Manifest with paths and key interfaces.
|
|
22
|
+
|
|
23
|
+
**⚠️ File Reading Rule**: Do NOT re-read source files already listed in Section 4 File Manifest — the manifest already contains their key interfaces. Only read a source file directly if: (a) it is NOT in the manifest, or (b) you need a specific implementation detail not captured in the manifest's interface column. Unnecessary re-reads waste significant context budget.
|
|
24
|
+
|
|
25
|
+
If the snapshot does not exist:
|
|
22
26
|
1. Read `.prizm-docs/root.prizm` to understand rules and known traps (TRAPS)
|
|
23
27
|
2. Read relevant L1/L2 docs for affected modules
|
|
24
28
|
3. Read required source files directly
|
|
@@ -42,7 +46,8 @@ Project documentation is in `.prizm-docs/`. Before implementation, read `context
|
|
|
42
46
|
7. Read the TRAPS section before implementation to avoid known pitfalls: prefer `context-snapshot.md` Section 3; if no snapshot exists, read `.prizm-docs/`
|
|
43
47
|
8. Checkpoint tasks must verify that build and tests pass before proceeding to the next phase
|
|
44
48
|
9. Execute sequential tasks in order; stop on failure. Parallel `[P]` tasks may continue
|
|
45
|
-
10. When creating a new sub-module, generate the corresponding `.prizm-docs/` L2 document
|
|
49
|
+
10. When creating a new sub-module, generate the corresponding `.prizm-docs/` L2 document. **Batch independent operations**: combine multiple `mkdir -p` into one command; issue multiple independent `Write` calls for different `.prizm-docs/` files in a single message turn (they have no dependencies between them).
|
|
50
|
+
11. **`.prizm-docs/` write safety**: Before writing ANY `.prizm-docs/` file, check if it already exists (`ls <path>`). If it **exists**: only append or update structural fields (KEY_FILES, INTERFACES, DEPENDENCIES, file counts, UPDATED date) — **never overwrite the full file**. DECISIONS and CHANGELOG sections are **append-only** — never delete or replace existing entries. If it does **not** exist: create it only for sub-modules you are actively creating in this session. Do NOT write `.prizm-docs/` files for modules you are not directly creating.
|
|
46
51
|
11. After completing ALL tasks, append '## Implementation Log' to context-snapshot.md: files changed/created, key decisions, notable discoveries
|
|
47
52
|
|
|
48
53
|
### Never Do (NEVER)
|
|
@@ -53,6 +58,7 @@ Project documentation is in `.prizm-docs/`. Before implementation, read `context
|
|
|
53
58
|
- **Do not execute any git operations** (git commit / git add / git reset / git push are all prohibited — the Orchestrator handles commits via /prizmkit-committer)
|
|
54
59
|
- Do not modify any files in `.prizmkit/specs/` except `plan.md` (marking Tasks [x]) and `context-snapshot.md` (appending Implementation Log)
|
|
55
60
|
- Do not use TaskCreate/TaskUpdate to create or modify Orchestrator-level tasks (Task tools are for internal progress tracking only, and task IDs are not shared across agent sub-sessions)
|
|
61
|
+
- **Do not overwrite existing `.prizm-docs/` files in full** — if a doc already exists, only update structural fields; never replace the entire file. Do NOT write `.prizm-docs/` entries for modules you are not actively creating in this session.
|
|
56
62
|
|
|
57
63
|
### Behavioral Rules
|
|
58
64
|
|
|
@@ -71,14 +77,19 @@ DEV-11: Checkpoint tasks must verify that build and tests pass
|
|
|
71
77
|
DEV-12: Generate L2 .prizm-docs/ documentation when creating new sub-modules
|
|
72
78
|
DEV-13: Executing any git command is prohibited (git add/commit/reset/push are all forbidden)
|
|
73
79
|
DEV-14: If `npm test` has pre-existing failures, do not ignore them — list them explicitly in COMPLETION_SIGNAL for Orchestrator decision
|
|
80
|
+
DEV-18: When tests fail, run `$TEST_CMD 2>&1 | tee /tmp/test-out.txt` ONCE, then grep `/tmp/test-out.txt` for failure details. Never re-run the full test suite just to apply a different grep filter to its output.
|
|
74
81
|
DEV-15: After ALL tasks, append '## Implementation Log' to context-snapshot.md (files changed, key decisions, discoveries)
|
|
75
82
|
DEV-16: Without context-snapshot: read .prizm-docs/ → read source files directly
|
|
83
|
+
DEV-17: DO NOT re-read source files already listed in context-snapshot.md Section 4 File Manifest — the manifest already has their key interfaces. Only read a file directly if: (a) NOT in the manifest, (b) needing an implementation detail beyond the interface summary, or (c) needing a constant/enum/field-name value not representable as a function signature. Unnecessary re-reads waste significant context budget.
|
|
84
|
+
DEV-18: When tests fail, run `$TEST_CMD 2>&1 | tee /tmp/test-out.txt` ONCE, then grep `/tmp/test-out.txt` for failure details. Never re-run the full test suite just to apply a different grep filter to its output.
|
|
85
|
+
DEV-19: Before writing any `.prizm-docs/` file, check if it exists. If it exists: only update structural fields (KEY_FILES, INTERFACES, DEPENDENCIES, file counts, UPDATED) — never overwrite the full file. DECISIONS/CHANGELOG are append-only. Only create new L2 docs for sub-modules you are actively creating in this session.
|
|
76
86
|
```
|
|
77
87
|
|
|
78
88
|
### Workflow
|
|
79
89
|
|
|
80
90
|
1. Receive task assignment
|
|
81
|
-
2. Read `.prizmkit/specs/###-feature-name/context-snapshot.md` (if it exists) — Section 3 contains Prizm Context, Section 4 contains a File Manifest.
|
|
91
|
+
2. Read `.prizmkit/specs/###-feature-name/context-snapshot.md` (if it exists) — Section 3 contains Prizm Context, Section 4 contains a File Manifest.
|
|
92
|
+
**DO NOT re-read source files listed in Section 4** — the manifest already has their interfaces. Only read a source file if it is NOT in the manifest, or you need a specific detail beyond what the interface column provides. If the snapshot does not exist:
|
|
82
93
|
a. Read `.prizm-docs/root.prizm` and relevant module documentation
|
|
83
94
|
b. Read required source files directly
|
|
84
95
|
3. Read `plan.md` (with Tasks section) and `spec.md` in `.prizmkit/specs/###-feature-name/`
|
|
@@ -16,7 +16,9 @@ You are the team's "quality inspector + proofreader" — you do not produce the
|
|
|
16
16
|
|
|
17
17
|
### Project Context
|
|
18
18
|
|
|
19
|
-
Project documentation is in `.prizm-docs/`. Before review, read `context-snapshot.md` (if it exists in `.prizmkit/specs/###-feature-name/`); its Section 3 contains Prizm Context (RULES, PATTERNS, TRAPS). Section 4 contains a File Manifest. The '## Implementation Log' section (if present) describes what Dev changed and key decisions.
|
|
19
|
+
Project documentation is in `.prizm-docs/`. Before review, read `context-snapshot.md` (if it exists in `.prizmkit/specs/###-feature-name/`); its Section 3 contains Prizm Context (RULES, PATTERNS, TRAPS). Section 4 contains a File Manifest. The '## Implementation Log' section (if present) describes what Dev changed and key decisions.
|
|
20
|
+
|
|
21
|
+
**⚠️ File Reading Rule**: Do NOT re-read source files that are already covered by the Implementation Log or Section 4 File Manifest unless you need to verify a specific code detail for a finding. Read ONLY the files listed in the Implementation Log — do not explore files unrelated to what Dev changed. If the snapshot does not exist, read `root.prizm` to understand project rules.
|
|
20
22
|
|
|
21
23
|
### Artifact Paths
|
|
22
24
|
|
|
@@ -63,6 +65,8 @@ REV-09: Review code for conformance to .prizm-docs/ PATTERNS and RULES
|
|
|
63
65
|
REV-10: Do not use the timeout command (incompatible with macOS). Run tests directly with node --test or npm test without a timeout prefix
|
|
64
66
|
REV-11: After review, append '## Review Notes' to context-snapshot.md (issues, severity, test results, verdict)
|
|
65
67
|
REV-12: Read Implementation Log in context-snapshot.md to understand Dev's decisions; reference relevant decisions in the review report
|
|
68
|
+
REV-13: DO NOT re-run the full test suite if the Implementation Log already confirms passing tests — trust Dev's result. Only re-run when: (a) log is absent, or (b) the log does not explicitly state test results
|
|
69
|
+
REV-14: When running the test suite, run it ONCE with `tee /tmp/review-test-out.txt`, then grep the file — never re-run the suite just to apply a different filter
|
|
66
70
|
```
|
|
67
71
|
|
|
68
72
|
### Phase 4 Workflow: Cross-Validation
|
|
@@ -86,7 +90,7 @@ REV-12: Read Implementation Log in context-snapshot.md to understand Dev's decis
|
|
|
86
90
|
3. Run `/prizmkit-code-review` (read-only)
|
|
87
91
|
- 6 review dimensions: spec compliance, plan adherence, code quality, security, consistency, test coverage
|
|
88
92
|
- Verdict: PASS | PASS WITH WARNINGS | NEEDS FIXES
|
|
89
|
-
3. Write and execute integration tests:
|
|
93
|
+
3. Run the full test suite — **ONLY if the '## Implementation Log' does not already confirm all tests passing**. If the log states tests passed, trust it and skip the full re-run. When running: `$TEST_CMD 2>&1 | tee /tmp/review-test-out.txt | tail -20`, then grep the file for details — do NOT re-run the suite multiple times. Write and execute integration tests:
|
|
90
94
|
- Interface compliance (request format, response format)
|
|
91
95
|
- Cross-module data flow integrity
|
|
92
96
|
- User story acceptance criteria (from spec.md)
|
|
@@ -326,10 +326,11 @@ if [[ -f "$SESSION_LOG" ]]; then
|
|
|
326
326
|
log_info "Session log: $FINAL_LINES lines, $((FINAL_SIZE / 1024))KB"
|
|
327
327
|
fi
|
|
328
328
|
|
|
329
|
-
SESSION_STATUS_FILE="$SESSION_DIR/session-status.json"
|
|
330
|
-
|
|
331
329
|
# ── Determine session outcome from observable signals ──────────────
|
|
332
330
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
331
|
+
DEFAULT_BRANCH=$(git -C "$PROJECT_ROOT" symbolic-ref refs/remotes/origin/HEAD 2>/dev/null \
|
|
332
|
+
| sed 's@^refs/remotes/origin/@@') \
|
|
333
|
+
|| DEFAULT_BRANCH=$(git -C "$PROJECT_ROOT" rev-parse --abbrev-ref HEAD 2>/dev/null | grep -E '^(main|master)$' || echo "main")
|
|
333
334
|
|
|
334
335
|
if [[ $EXIT_CODE -eq 124 ]]; then
|
|
335
336
|
log_warn "Session timed out after ${SESSION_TIMEOUT}s"
|
|
@@ -339,20 +340,9 @@ elif [[ $EXIT_CODE -ne 0 ]]; then
|
|
|
339
340
|
SESSION_STATUS="crashed"
|
|
340
341
|
else
|
|
341
342
|
# Exit code 0 — check if the session produced commits
|
|
342
|
-
SESSION_START_ISO=$(python3 -c "
|
|
343
|
-
import os, sys
|
|
344
|
-
from datetime import datetime, timezone
|
|
345
|
-
p = sys.argv[1]
|
|
346
|
-
if os.path.isdir(p):
|
|
347
|
-
ts = os.path.getctime(p)
|
|
348
|
-
print(datetime.fromtimestamp(ts, tz=timezone.utc).strftime('%Y-%m-%dT%H:%M:%SZ'))
|
|
349
|
-
else:
|
|
350
|
-
print('')
|
|
351
|
-
" "$SESSION_DIR" 2>/dev/null) || SESSION_START_ISO=""
|
|
352
|
-
|
|
353
343
|
HAS_COMMITS=""
|
|
354
|
-
if
|
|
355
|
-
HAS_COMMITS=$(git -C "$PROJECT_ROOT" log
|
|
344
|
+
if git -C "$PROJECT_ROOT" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
|
345
|
+
HAS_COMMITS=$(git -C "$PROJECT_ROOT" log "${DEFAULT_BRANCH}..HEAD" --oneline 2>/dev/null | head -1)
|
|
356
346
|
fi
|
|
357
347
|
|
|
358
348
|
if [[ -n "$HAS_COMMITS" ]]; then
|
|
@@ -360,8 +350,15 @@ else:
|
|
|
360
350
|
else
|
|
361
351
|
UNCOMMITTED=$(git -C "$PROJECT_ROOT" status --porcelain 2>/dev/null | head -1 || true)
|
|
362
352
|
if [[ -n "$UNCOMMITTED" ]]; then
|
|
363
|
-
log_warn "Session exited cleanly but produced no commits (uncommitted changes found)"
|
|
364
|
-
|
|
353
|
+
log_warn "Session exited cleanly but produced no commits (uncommitted changes found) — auto-committing..."
|
|
354
|
+
git -C "$PROJECT_ROOT" add -A 2>/dev/null || true
|
|
355
|
+
if git -C "$PROJECT_ROOT" commit --no-verify -m "chore($BUG_ID): auto-commit session work" 2>/dev/null; then
|
|
356
|
+
log_info "Auto-commit succeeded"
|
|
357
|
+
SESSION_STATUS="success"
|
|
358
|
+
else
|
|
359
|
+
log_warn "Auto-commit failed — no changes to commit"
|
|
360
|
+
SESSION_STATUS="crashed"
|
|
361
|
+
fi
|
|
365
362
|
else
|
|
366
363
|
log_warn "Session exited cleanly but produced no commits and no changes"
|
|
367
364
|
SESSION_STATUS="crashed"
|
|
@@ -376,14 +373,9 @@ if [[ "$SESSION_STATUS" == "success" ]]; then
|
|
|
376
373
|
if [[ -n "$DIRTY_FILES" ]]; then
|
|
377
374
|
log_info "Auto-committing remaining session artifacts..."
|
|
378
375
|
git -C "$PROJECT_ROOT" add -A 2>/dev/null || true
|
|
379
|
-
git -C "$PROJECT_ROOT" commit -
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
DIRTY_FILES=$(git -C "$PROJECT_ROOT" status --porcelain 2>/dev/null || true)
|
|
383
|
-
if [[ -n "$DIRTY_FILES" ]]; then
|
|
384
|
-
log_error "Git working tree still not clean after auto-commit."
|
|
385
|
-
echo "$DIRTY_FILES" | sed 's/^/ - /'
|
|
386
|
-
SESSION_STATUS="failed"
|
|
376
|
+
git -C "$PROJECT_ROOT" commit --no-verify --amend --no-edit -a 2>/dev/null \
|
|
377
|
+
|| git -C "$PROJECT_ROOT" commit --no-verify -m "chore($BUG_ID): include remaining session artifacts" 2>/dev/null \
|
|
378
|
+
|| true
|
|
387
379
|
fi
|
|
388
380
|
fi
|
|
389
381
|
fi
|
|
@@ -338,10 +338,11 @@ if [[ -f "$SESSION_LOG" ]]; then
|
|
|
338
338
|
log_info "Session log: $FINAL_LINES lines, $((FINAL_SIZE / 1024))KB"
|
|
339
339
|
fi
|
|
340
340
|
|
|
341
|
-
SESSION_STATUS_FILE="$SESSION_DIR/session-status.json"
|
|
342
|
-
|
|
343
341
|
# ── Determine session outcome from observable signals ──────────────
|
|
344
342
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
343
|
+
DEFAULT_BRANCH=$(git -C "$PROJECT_ROOT" symbolic-ref refs/remotes/origin/HEAD 2>/dev/null \
|
|
344
|
+
| sed 's@^refs/remotes/origin/@@') \
|
|
345
|
+
|| DEFAULT_BRANCH=$(git -C "$PROJECT_ROOT" rev-parse --abbrev-ref HEAD 2>/dev/null | grep -E '^(main|master)$' || echo "main")
|
|
345
346
|
|
|
346
347
|
if [[ $EXIT_CODE -eq 124 ]]; then
|
|
347
348
|
log_warn "Session timed out after ${SESSION_TIMEOUT}s"
|
|
@@ -351,20 +352,9 @@ elif [[ $EXIT_CODE -ne 0 ]]; then
|
|
|
351
352
|
SESSION_STATUS="crashed"
|
|
352
353
|
else
|
|
353
354
|
# Exit code 0 — check if the session produced commits
|
|
354
|
-
SESSION_START_ISO=$(python3 -c "
|
|
355
|
-
import os, sys
|
|
356
|
-
from datetime import datetime, timezone
|
|
357
|
-
p = sys.argv[1]
|
|
358
|
-
if os.path.isdir(p):
|
|
359
|
-
ts = os.path.getctime(p)
|
|
360
|
-
print(datetime.fromtimestamp(ts, tz=timezone.utc).strftime('%Y-%m-%dT%H:%M:%SZ'))
|
|
361
|
-
else:
|
|
362
|
-
print('')
|
|
363
|
-
" "$SESSION_DIR" 2>/dev/null) || SESSION_START_ISO=""
|
|
364
|
-
|
|
365
355
|
HAS_COMMITS=""
|
|
366
|
-
if
|
|
367
|
-
HAS_COMMITS=$(git -C "$PROJECT_ROOT" log
|
|
356
|
+
if git -C "$PROJECT_ROOT" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
|
357
|
+
HAS_COMMITS=$(git -C "$PROJECT_ROOT" log "${DEFAULT_BRANCH}..HEAD" --oneline 2>/dev/null | head -1)
|
|
368
358
|
fi
|
|
369
359
|
|
|
370
360
|
if [[ -n "$HAS_COMMITS" ]]; then
|
|
@@ -372,8 +362,15 @@ else:
|
|
|
372
362
|
else
|
|
373
363
|
UNCOMMITTED=$(git -C "$PROJECT_ROOT" status --porcelain 2>/dev/null | head -1 || true)
|
|
374
364
|
if [[ -n "$UNCOMMITTED" ]]; then
|
|
375
|
-
log_warn "Session exited cleanly but produced no commits (uncommitted changes found)"
|
|
376
|
-
|
|
365
|
+
log_warn "Session exited cleanly but produced no commits (uncommitted changes found) — auto-committing..."
|
|
366
|
+
git -C "$PROJECT_ROOT" add -A 2>/dev/null || true
|
|
367
|
+
if git -C "$PROJECT_ROOT" commit --no-verify -m "chore($FEATURE_ID): auto-commit session work" 2>/dev/null; then
|
|
368
|
+
log_info "Auto-commit succeeded"
|
|
369
|
+
SESSION_STATUS="success"
|
|
370
|
+
else
|
|
371
|
+
log_warn "Auto-commit failed — no changes to commit"
|
|
372
|
+
SESSION_STATUS="crashed"
|
|
373
|
+
fi
|
|
377
374
|
else
|
|
378
375
|
log_warn "Session exited cleanly but produced no commits and no changes"
|
|
379
376
|
SESSION_STATUS="crashed"
|
|
@@ -388,14 +385,9 @@ if [[ "$SESSION_STATUS" == "success" ]]; then
|
|
|
388
385
|
if [[ -n "$DIRTY_FILES" ]]; then
|
|
389
386
|
log_info "Auto-committing remaining session artifacts..."
|
|
390
387
|
git -C "$PROJECT_ROOT" add -A 2>/dev/null || true
|
|
391
|
-
git -C "$PROJECT_ROOT" commit -
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
DIRTY_FILES=$(git -C "$PROJECT_ROOT" status --porcelain 2>/dev/null || true)
|
|
395
|
-
if [[ -n "$DIRTY_FILES" ]]; then
|
|
396
|
-
log_error "Git working tree still not clean after auto-commit."
|
|
397
|
-
echo "$DIRTY_FILES" | sed 's/^/ - /'
|
|
398
|
-
SESSION_STATUS="failed"
|
|
388
|
+
git -C "$PROJECT_ROOT" commit --no-verify --amend --no-edit -a 2>/dev/null \
|
|
389
|
+
|| git -C "$PROJECT_ROOT" commit --no-verify -m "chore($FEATURE_ID): include remaining session artifacts" 2>/dev/null \
|
|
390
|
+
|| true
|
|
399
391
|
fi
|
|
400
392
|
fi
|
|
401
393
|
fi
|
|
@@ -168,6 +168,10 @@ spawn_and_wait_session() {
|
|
|
168
168
|
local session_status
|
|
169
169
|
local project_root
|
|
170
170
|
project_root="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
171
|
+
local default_branch
|
|
172
|
+
default_branch=$(git -C "$project_root" symbolic-ref refs/remotes/origin/HEAD 2>/dev/null \
|
|
173
|
+
| sed 's@^refs/remotes/origin/@@') \
|
|
174
|
+
|| default_branch=$(git -C "$project_root" rev-parse --abbrev-ref HEAD 2>/dev/null | grep -E '^(main|master)$' || echo "main")
|
|
171
175
|
|
|
172
176
|
if [[ $exit_code -eq 124 ]]; then
|
|
173
177
|
log_warn "Session timed out after ${SESSION_TIMEOUT}s"
|
|
@@ -177,18 +181,9 @@ spawn_and_wait_session() {
|
|
|
177
181
|
session_status="crashed"
|
|
178
182
|
else
|
|
179
183
|
# Exit code 0 — check if the session actually produced commits
|
|
180
|
-
local session_start_iso=""
|
|
181
|
-
session_start_iso=$(python3 -c "
|
|
182
|
-
import json, sys, os
|
|
183
|
-
p = os.path.join(sys.argv[1], 'current-session.json')
|
|
184
|
-
if os.path.isfile(p):
|
|
185
|
-
with open(p) as f: print(json.load(f).get('started_at', ''))
|
|
186
|
-
else: print('')
|
|
187
|
-
" "$STATE_DIR" 2>/dev/null) || session_start_iso=""
|
|
188
|
-
|
|
189
184
|
local has_commits=""
|
|
190
|
-
if
|
|
191
|
-
has_commits=$(git -C "$project_root" log
|
|
185
|
+
if git -C "$project_root" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
|
186
|
+
has_commits=$(git -C "$project_root" log "${default_branch}..HEAD" --oneline 2>/dev/null | head -1)
|
|
192
187
|
fi
|
|
193
188
|
|
|
194
189
|
if [[ -n "$has_commits" ]]; then
|
|
@@ -197,8 +192,15 @@ else: print('')
|
|
|
197
192
|
local uncommitted=""
|
|
198
193
|
uncommitted=$(git -C "$project_root" status --porcelain 2>/dev/null | head -1 || true)
|
|
199
194
|
if [[ -n "$uncommitted" ]]; then
|
|
200
|
-
log_warn "Session exited cleanly but produced no commits (uncommitted changes found)"
|
|
201
|
-
|
|
195
|
+
log_warn "Session exited cleanly but produced no commits (uncommitted changes found) — auto-committing..."
|
|
196
|
+
git -C "$project_root" add -A 2>/dev/null || true
|
|
197
|
+
if git -C "$project_root" commit --no-verify -m "chore($bug_id): auto-commit session work" 2>/dev/null; then
|
|
198
|
+
log_info "Auto-commit succeeded"
|
|
199
|
+
session_status="success"
|
|
200
|
+
else
|
|
201
|
+
log_warn "Auto-commit failed — no changes to commit"
|
|
202
|
+
session_status="crashed"
|
|
203
|
+
fi
|
|
202
204
|
else
|
|
203
205
|
log_warn "Session exited cleanly but produced no commits and no changes"
|
|
204
206
|
session_status="crashed"
|
|
@@ -214,14 +216,9 @@ else: print('')
|
|
|
214
216
|
if [[ -n "$dirty_files" ]]; then
|
|
215
217
|
log_info "Auto-committing remaining session artifacts..."
|
|
216
218
|
git -C "$project_root" add -A 2>/dev/null || true
|
|
217
|
-
git -C "$project_root" commit -
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
dirty_files=$(git -C "$project_root" status --porcelain 2>/dev/null || true)
|
|
221
|
-
if [[ -n "$dirty_files" ]]; then
|
|
222
|
-
log_error "Git working tree still not clean after auto-commit."
|
|
223
|
-
echo "$dirty_files" | sed 's/^/ - /'
|
|
224
|
-
session_status="failed"
|
|
219
|
+
git -C "$project_root" commit --no-verify --amend --no-edit -a 2>/dev/null \
|
|
220
|
+
|| git -C "$project_root" commit --no-verify -m "chore($bug_id): include remaining session artifacts" 2>/dev/null \
|
|
221
|
+
|| true
|
|
225
222
|
fi
|
|
226
223
|
fi
|
|
227
224
|
fi
|
|
@@ -190,6 +190,10 @@ spawn_and_wait_session() {
|
|
|
190
190
|
local session_status
|
|
191
191
|
local project_root
|
|
192
192
|
project_root="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
193
|
+
local default_branch
|
|
194
|
+
default_branch=$(git -C "$project_root" symbolic-ref refs/remotes/origin/HEAD 2>/dev/null \
|
|
195
|
+
| sed 's@^refs/remotes/origin/@@') \
|
|
196
|
+
|| default_branch=$(git -C "$project_root" rev-parse --abbrev-ref HEAD 2>/dev/null | grep -E '^(main|master)$' || echo "main")
|
|
193
197
|
|
|
194
198
|
if [[ $exit_code -eq 124 ]]; then
|
|
195
199
|
log_warn "Session timed out after ${SESSION_TIMEOUT}s"
|
|
@@ -199,18 +203,9 @@ spawn_and_wait_session() {
|
|
|
199
203
|
session_status="crashed"
|
|
200
204
|
else
|
|
201
205
|
# Exit code 0 — check if the session actually produced commits
|
|
202
|
-
local session_start_iso=""
|
|
203
|
-
session_start_iso=$(python3 -c "
|
|
204
|
-
import json, sys, os
|
|
205
|
-
p = os.path.join(sys.argv[1], 'current-session.json')
|
|
206
|
-
if os.path.isfile(p):
|
|
207
|
-
with open(p) as f: print(json.load(f).get('started_at', ''))
|
|
208
|
-
else: print('')
|
|
209
|
-
" "$STATE_DIR" 2>/dev/null) || session_start_iso=""
|
|
210
|
-
|
|
211
206
|
local has_commits=""
|
|
212
|
-
if
|
|
213
|
-
has_commits=$(git -C "$project_root" log
|
|
207
|
+
if git -C "$project_root" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
|
208
|
+
has_commits=$(git -C "$project_root" log "${default_branch}..HEAD" --oneline 2>/dev/null | head -1)
|
|
214
209
|
fi
|
|
215
210
|
|
|
216
211
|
if [[ -n "$has_commits" ]]; then
|
|
@@ -221,8 +216,15 @@ else: print('')
|
|
|
221
216
|
local uncommitted=""
|
|
222
217
|
uncommitted=$(git -C "$project_root" status --porcelain 2>/dev/null | head -1 || true)
|
|
223
218
|
if [[ -n "$uncommitted" ]]; then
|
|
224
|
-
log_warn "Session exited cleanly but produced no commits (uncommitted changes found)"
|
|
225
|
-
|
|
219
|
+
log_warn "Session exited cleanly but produced no commits (uncommitted changes found) — auto-committing..."
|
|
220
|
+
git -C "$project_root" add -A 2>/dev/null || true
|
|
221
|
+
if git -C "$project_root" commit --no-verify -m "chore($feature_id): auto-commit session work" 2>/dev/null; then
|
|
222
|
+
log_info "Auto-commit succeeded"
|
|
223
|
+
session_status="success"
|
|
224
|
+
else
|
|
225
|
+
log_warn "Auto-commit failed — no changes to commit"
|
|
226
|
+
session_status="crashed"
|
|
227
|
+
fi
|
|
226
228
|
else
|
|
227
229
|
log_warn "Session exited cleanly but produced no commits and no changes"
|
|
228
230
|
session_status="crashed"
|
|
@@ -239,30 +241,9 @@ else: print('')
|
|
|
239
241
|
if [[ -n "$dirty_files" ]]; then
|
|
240
242
|
log_info "Auto-committing remaining session artifacts..."
|
|
241
243
|
git -C "$project_root" add -A 2>/dev/null || true
|
|
242
|
-
git -C "$project_root" commit -
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
# Re-check: if still dirty after auto-commit, flag as commit_missing
|
|
246
|
-
dirty_files=$(git -C "$project_root" status --porcelain 2>/dev/null || true)
|
|
247
|
-
if [[ -n "$dirty_files" ]]; then
|
|
248
|
-
log_warn "Git working tree still not clean after auto-commit."
|
|
249
|
-
echo "$dirty_files" | sed 's/^/ - /'
|
|
250
|
-
session_status="commit_missing"
|
|
251
|
-
else
|
|
252
|
-
# Bugfix commits (fix: / fix(scope):) are exempt from docs check.
|
|
253
|
-
local last_commit_subject=""
|
|
254
|
-
last_commit_subject=$(git -C "$project_root" log -1 --pretty=%s 2>/dev/null || true)
|
|
255
|
-
if [[ "$last_commit_subject" =~ ^fix(\(|:) ]]; then
|
|
256
|
-
log_info "Detected bugfix commit prefix; skipping docs check."
|
|
257
|
-
else
|
|
258
|
-
local docs_changed=""
|
|
259
|
-
docs_changed=$(git -C "$project_root" log --name-only --format="" -1 2>/dev/null \
|
|
260
|
-
| grep -E '\.prizm-docs/' | head -1 || true)
|
|
261
|
-
if [[ -z "$docs_changed" ]]; then
|
|
262
|
-
log_warn "Session committed but no .prizm-docs changes detected."
|
|
263
|
-
session_status="docs_missing"
|
|
264
|
-
fi
|
|
265
|
-
fi
|
|
244
|
+
git -C "$project_root" commit --no-verify --amend --no-edit -a 2>/dev/null \
|
|
245
|
+
|| git -C "$project_root" commit --no-verify -m "chore($feature_id): include remaining session artifacts" 2>/dev/null \
|
|
246
|
+
|| true
|
|
266
247
|
fi
|
|
267
248
|
fi
|
|
268
249
|
fi
|
|
@@ -41,6 +41,7 @@ You are running in headless mode with a FINITE context window. Exceeding it will
|
|
|
41
41
|
4. **One task at a time** — In Phase 3 (implement), complete and test one task before starting the next.
|
|
42
42
|
5. **Minimize tool output** — When running commands, use `| head -20` or `| tail -20` to limit output. Never dump entire test suites or logs.
|
|
43
43
|
6. **Incremental commits when possible** — If a feature has multiple independent tasks, commit after each completed task rather than one big commit at the end.
|
|
44
|
+
7. **Capture test output once** — When running the test suite, always use `$TEST_CMD 2>&1 | tee /tmp/test-out.txt | tail -20`. Then grep `/tmp/test-out.txt` for details. Never re-run the suite just to apply a different filter.
|
|
44
45
|
|
|
45
46
|
---
|
|
46
47
|
|
|
@@ -99,11 +100,22 @@ If plan.md missing, write it directly:
|
|
|
99
100
|
|
|
100
101
|
### Phase 3: Implement + Test
|
|
101
102
|
|
|
103
|
+
**Before starting**: detect the test command and record baseline:
|
|
104
|
+
```bash
|
|
105
|
+
# Try in order, use first that exits 0
|
|
106
|
+
node --test tests/**/*.test.js 2>&1 | tail -3 # Node built-in
|
|
107
|
+
npm test 2>&1 | tail -3 # npm fallback
|
|
108
|
+
```
|
|
109
|
+
Record the working command as `TEST_CMD`. Then record baseline failures (if any):
|
|
110
|
+
```bash
|
|
111
|
+
$TEST_CMD 2>&1 | tee /tmp/test-baseline.txt | tail -20
|
|
112
|
+
```
|
|
113
|
+
|
|
102
114
|
For each task in plan.md Tasks section:
|
|
103
115
|
1. Read the relevant section from `context-snapshot.md` (no need to re-read individual files)
|
|
104
116
|
2. Write/edit the code
|
|
105
|
-
3. Run tests after each task
|
|
106
|
-
|
|
117
|
+
3. Run tests after each task: `$TEST_CMD 2>&1 | tee /tmp/test-out.txt | tail -20` — then grep `/tmp/test-out.txt` for failure details; never re-run just to apply a different filter
|
|
118
|
+
4. Mark task `[x]` in plan.md Tasks section immediately
|
|
107
119
|
|
|
108
120
|
After all tasks complete:
|
|
109
121
|
1. Run the full test suite to ensure nothing is broken
|
|
@@ -41,6 +41,7 @@ You are running in headless mode with a FINITE context window. Exceeding it will
|
|
|
41
41
|
4. **One task at a time** — In Phase 3 (implement), complete and test one task before starting the next.
|
|
42
42
|
5. **Minimize tool output** — When running commands, use `| head -20` or `| tail -20` to limit output. Never dump entire test suites or logs.
|
|
43
43
|
6. **Incremental commits when possible** — If a feature has multiple independent tasks, commit after each completed task rather than one big commit at the end.
|
|
44
|
+
7. **Capture test output once** — When running the test suite, always use `$TEST_CMD 2>&1 | tee /tmp/test-out.txt | tail -20`. Then grep `/tmp/test-out.txt` for details. Never re-run the suite just to apply a different filter.
|
|
44
45
|
|
|
45
46
|
---
|
|
46
47
|
|
|
@@ -125,10 +126,11 @@ Spawn Dev subagent (Agent tool, subagent_type="prizm-dev-team-dev", run_in_backg
|
|
|
125
126
|
Prompt:
|
|
126
127
|
> "Read {{DEV_SUBAGENT_PATH}}. Implement feature {{FEATURE_ID}} (slug: {{FEATURE_SLUG}}) using TDD.
|
|
127
128
|
> **IMPORTANT**: Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` FIRST.
|
|
128
|
-
> 1. Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` — Section 3 has Prizm Context (TRAPS/RULES), Section 4 has File Manifest with paths and interfaces.
|
|
129
|
+
> 1. Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` — Section 3 has Prizm Context (TRAPS/RULES), Section 4 has File Manifest with paths and interfaces.
|
|
130
|
+
> **⚠️ DO NOT re-read source files that are already listed in Section 4 File Manifest.** Only read a source file directly if: (a) NOT in the manifest, (b) needing an implementation detail beyond the interface summary, or (c) needing a constant/enum/field-name value not captured in the interface column.
|
|
129
131
|
> 2. Read `plan.md` (including Tasks section) from `.prizmkit/specs/{{FEATURE_SLUG}}/`.
|
|
130
132
|
> 3. Implement task-by-task. Mark each `[x]` in plan.md Tasks section **immediately** after completion (do NOT batch).
|
|
131
|
-
> 4. Use `TEST_CMD=<TEST_CMD>` to run tests — do NOT explore alternative test commands.
|
|
133
|
+
> 4. Use `TEST_CMD=<TEST_CMD>` to run tests — do NOT explore alternative test commands. **When tests fail: run `$TEST_CMD 2>&1 | tee /tmp/test-out.txt` ONCE, then grep `/tmp/test-out.txt` for failure details. Never re-run the full suite just to apply a different filter.**
|
|
132
134
|
> 5. After ALL tasks done, append '## Implementation Log' to context-snapshot.md with:
|
|
133
135
|
> - Files changed/created (with paths)
|
|
134
136
|
> - Key implementation decisions and rationale
|
|
@@ -159,7 +161,7 @@ Prompt:
|
|
|
159
161
|
> - Section 4: File Manifest (original file structure)
|
|
160
162
|
> - '## Implementation Log': what Dev changed, key decisions, discoveries
|
|
161
163
|
> 2. Run prizmkit-code-review: spec compliance (against spec.md), code quality, correctness. Read ONLY files listed in Implementation Log.
|
|
162
|
-
> 3. Run the full test suite
|
|
164
|
+
> 3. Run the full test suite — **ONLY if the Implementation Log does not already confirm all tests passing**. If the log states tests passed, trust it and skip the re-run. When running: `$TEST_CMD 2>&1 | tee /tmp/review-test-out.txt | tail -20`, then grep the file for details — do NOT re-run the suite multiple times. Write and execute integration tests covering all user stories.
|
|
163
165
|
> 4. Append '## Review Notes' to context-snapshot.md: issues found (with severity), test results, final verdict.
|
|
164
166
|
> Report verdict: PASS, PASS_WITH_WARNINGS, or NEEDS_FIXES."
|
|
165
167
|
|
|
@@ -73,6 +73,7 @@ You are running in headless mode with a FINITE context window. Exceeding it will
|
|
|
73
73
|
4. **One task at a time** — In Phase 4 (implement), complete and test one task before starting the next.
|
|
74
74
|
5. **Minimize tool output** — When running commands, use `| head -20` or `| tail -20` to limit output. Never dump entire test suites or logs.
|
|
75
75
|
6. **Incremental commits when possible** — If a feature has multiple independent tasks, commit after each completed task rather than one big commit at the end.
|
|
76
|
+
7. **Batch independent operations** — Issue multiple independent `Write`/`Read` calls in a single message turn when they have no dependencies. Combine multiple `mkdir -p` into one command. Never run `npm test` twice just to apply a different grep filter — capture output to `/tmp/test-out.txt` once and grep the file.
|
|
76
77
|
|
|
77
78
|
---
|
|
78
79
|
|
|
@@ -118,9 +119,11 @@ Record the working command as `TEST_CMD`. If both fail, record `TEST_CMD="npm te
|
|
|
118
119
|
|
|
119
120
|
**Step 2 — Record pre-existing failure baseline**:
|
|
120
121
|
```bash
|
|
121
|
-
$TEST_CMD 2>&1 | tail -20
|
|
122
|
+
$TEST_CMD 2>&1 | tee /tmp/test-baseline.txt | tail -20
|
|
122
123
|
```
|
|
123
124
|
Save the list of **pre-existing failing tests** (if any) as `BASELINE_FAILURES`. These are known failures that existed before this session — Dev must NOT be blamed for them, but must list them in COMPLETION_SIGNAL.
|
|
125
|
+
|
|
126
|
+
> **⚠️ Test Output Rule**: Always capture test output to a temp file (`tee /tmp/test-out.txt`). Then grep the file instead of re-running the suite. Never run `npm test` multiple times just to apply different grep filters to the output.
|
|
124
127
|
{{END_IF_INIT_DONE}}
|
|
125
128
|
|
|
126
129
|
### Step 1: Initialize
|
|
@@ -242,10 +245,11 @@ Append the following to the Dev agent prompt:
|
|
|
242
245
|
Prompt:
|
|
243
246
|
> "Read {{DEV_SUBAGENT_PATH}}. Implement feature {{FEATURE_ID}} (slug: {{FEATURE_SLUG}}) using TDD.
|
|
244
247
|
> **IMPORTANT**: Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` FIRST.
|
|
245
|
-
> 1. Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` — Section 3 has Prizm Context (TRAPS/RULES), Section 4 has File Manifest with paths and interfaces.
|
|
248
|
+
> 1. Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` — Section 3 has Prizm Context (TRAPS/RULES), Section 4 has File Manifest with paths and interfaces.
|
|
249
|
+
> **⚠️ DO NOT re-read source files that are already listed in Section 4 File Manifest.** The manifest already contains their key interfaces. Only read a source file directly if: (a) it is NOT in the manifest, or (b) you need a specific implementation detail not captured in the manifest's interface column.
|
|
246
250
|
> 2. Read `plan.md` (including Tasks section) from `.prizmkit/specs/{{FEATURE_SLUG}}/`.
|
|
247
251
|
> 3. Implement task-by-task. Mark each `[x]` in plan.md Tasks section **immediately** after completion (do NOT batch).
|
|
248
|
-
> 4. Use `TEST_CMD=<TEST_CMD>` to run tests — do NOT explore alternative test commands.
|
|
252
|
+
> 4. Use `TEST_CMD=<TEST_CMD>` to run tests — do NOT explore alternative test commands. **When tests fail: run `$TEST_CMD 2>&1 | tee /tmp/test-out.txt` ONCE, then grep `/tmp/test-out.txt` for failure details. Never re-run the full suite just to apply a different filter.**
|
|
249
253
|
> 5. After ALL tasks done, append '## Implementation Log' to context-snapshot.md with:
|
|
250
254
|
> - Files changed/created (with paths)
|
|
251
255
|
> - Key implementation decisions and rationale
|
|
@@ -300,7 +304,7 @@ Prompt:
|
|
|
300
304
|
> - Section 4: File Manifest (original file structure)
|
|
301
305
|
> - '## Implementation Log': what Dev changed, key decisions, discoveries
|
|
302
306
|
> 2. Run prizmkit-code-review: spec compliance (against spec.md), code quality, correctness. Read ONLY files listed in Implementation Log.
|
|
303
|
-
> 3. Run the full test suite using `TEST_CMD=<TEST_CMD
|
|
307
|
+
> 3. Run the full test suite using `TEST_CMD=<TEST_CMD>` — **ONLY if the Implementation Log does not already confirm all tests passing**. If Implementation Log states tests passed, trust it and skip the re-run. When running tests: `$TEST_CMD 2>&1 | tee /tmp/review-test-out.txt | tail -20`, then grep `/tmp/review-test-out.txt` for details — do NOT re-run the suite multiple times. Write and execute integration tests covering all user stories from spec.md.
|
|
304
308
|
> 4. Append '## Review Notes' to context-snapshot.md: issues found (with severity), test results, final verdict.
|
|
305
309
|
> Report verdict: PASS, PASS_WITH_WARNINGS, or NEEDS_FIXES."
|
|
306
310
|
|