prizmkit 1.0.88 → 1.0.90
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/lib/branch.sh +4 -6
- package/bundled/dev-pipeline/retry-bug.sh +19 -13
- package/bundled/dev-pipeline/retry-feature.sh +16 -13
- package/bundled/dev-pipeline/run-bugfix.sh +21 -12
- package/bundled/dev-pipeline/run.sh +18 -28
- package/bundled/dev-pipeline/scripts/detect-stuck.py +25 -3
- package/bundled/dev-pipeline/scripts/init-bugfix-pipeline.py +3 -1
- package/bundled/dev-pipeline/scripts/init-pipeline.py +3 -1
- 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)
|
|
@@ -98,13 +98,11 @@ branch_merge() {
|
|
|
98
98
|
return 1
|
|
99
99
|
fi
|
|
100
100
|
|
|
101
|
-
# Step 2: Merge dev branch
|
|
101
|
+
# Step 2: Merge dev branch (fast-forward only — avoids interactive merge commit editor)
|
|
102
102
|
log_info "Merging $dev_branch into $original_branch..."
|
|
103
|
-
if ! git -C "$project_root" merge "$dev_branch" 2>&1; then
|
|
104
|
-
log_error "Merge failed — resolve
|
|
105
|
-
log_error " git checkout $original_branch && git
|
|
106
|
-
# Return to dev branch so state is not lost
|
|
107
|
-
git -C "$project_root" merge --abort 2>/dev/null || true
|
|
103
|
+
if ! git -C "$project_root" merge --ff-only "$dev_branch" 2>&1; then
|
|
104
|
+
log_error "Merge failed (non-fast-forward) — resolve manually:"
|
|
105
|
+
log_error " git checkout $original_branch && git rebase $dev_branch"
|
|
108
106
|
git -C "$project_root" checkout "$dev_branch" 2>/dev/null || true
|
|
109
107
|
return 1
|
|
110
108
|
fi
|
|
@@ -175,6 +175,9 @@ python3 "$SCRIPTS_DIR/update-bug-status.py" \
|
|
|
175
175
|
log_warn "Failed to clean bug artifacts (continuing with fresh session only)"
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
+
# Auto-detect available models (must run before any git commit operations)
|
|
179
|
+
bash "$SCRIPT_DIR/scripts/detect-models.sh" --quiet 2>/dev/null || true
|
|
180
|
+
|
|
178
181
|
# ============================================================
|
|
179
182
|
# Generate bootstrap prompt
|
|
180
183
|
# ============================================================
|
|
@@ -326,10 +329,11 @@ if [[ -f "$SESSION_LOG" ]]; then
|
|
|
326
329
|
log_info "Session log: $FINAL_LINES lines, $((FINAL_SIZE / 1024))KB"
|
|
327
330
|
fi
|
|
328
331
|
|
|
329
|
-
SESSION_STATUS_FILE="$SESSION_DIR/session-status.json"
|
|
330
|
-
|
|
331
332
|
# ── Determine session outcome from observable signals ──────────────
|
|
332
333
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
334
|
+
DEFAULT_BRANCH=$(git -C "$PROJECT_ROOT" symbolic-ref refs/remotes/origin/HEAD 2>/dev/null \
|
|
335
|
+
| sed 's@^refs/remotes/origin/@@') \
|
|
336
|
+
|| DEFAULT_BRANCH=$(git -C "$PROJECT_ROOT" rev-parse --abbrev-ref HEAD 2>/dev/null | grep -E '^(main|master)$' || echo "main")
|
|
333
337
|
|
|
334
338
|
if [[ $EXIT_CODE -eq 124 ]]; then
|
|
335
339
|
log_warn "Session timed out after ${SESSION_TIMEOUT}s"
|
|
@@ -341,7 +345,7 @@ else
|
|
|
341
345
|
# Exit code 0 — check if the session produced commits
|
|
342
346
|
HAS_COMMITS=""
|
|
343
347
|
if git -C "$PROJECT_ROOT" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
|
344
|
-
HAS_COMMITS=$(git -C "$PROJECT_ROOT" log
|
|
348
|
+
HAS_COMMITS=$(git -C "$PROJECT_ROOT" log "${DEFAULT_BRANCH}..HEAD" --oneline 2>/dev/null | head -1)
|
|
345
349
|
fi
|
|
346
350
|
|
|
347
351
|
if [[ -n "$HAS_COMMITS" ]]; then
|
|
@@ -349,8 +353,15 @@ else
|
|
|
349
353
|
else
|
|
350
354
|
UNCOMMITTED=$(git -C "$PROJECT_ROOT" status --porcelain 2>/dev/null | head -1 || true)
|
|
351
355
|
if [[ -n "$UNCOMMITTED" ]]; then
|
|
352
|
-
log_warn "Session exited cleanly but produced no commits (uncommitted changes found)"
|
|
353
|
-
|
|
356
|
+
log_warn "Session exited cleanly but produced no commits (uncommitted changes found) — auto-committing..."
|
|
357
|
+
git -C "$PROJECT_ROOT" add -A 2>/dev/null || true
|
|
358
|
+
if git -C "$PROJECT_ROOT" commit --no-verify -m "chore($BUG_ID): auto-commit session work" 2>/dev/null; then
|
|
359
|
+
log_info "Auto-commit succeeded"
|
|
360
|
+
SESSION_STATUS="success"
|
|
361
|
+
else
|
|
362
|
+
log_warn "Auto-commit failed — no changes to commit"
|
|
363
|
+
SESSION_STATUS="crashed"
|
|
364
|
+
fi
|
|
354
365
|
else
|
|
355
366
|
log_warn "Session exited cleanly but produced no commits and no changes"
|
|
356
367
|
SESSION_STATUS="crashed"
|
|
@@ -365,14 +376,9 @@ if [[ "$SESSION_STATUS" == "success" ]]; then
|
|
|
365
376
|
if [[ -n "$DIRTY_FILES" ]]; then
|
|
366
377
|
log_info "Auto-committing remaining session artifacts..."
|
|
367
378
|
git -C "$PROJECT_ROOT" add -A 2>/dev/null || true
|
|
368
|
-
git -C "$PROJECT_ROOT" commit --no-verify -
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
DIRTY_FILES=$(git -C "$PROJECT_ROOT" status --porcelain 2>/dev/null || true)
|
|
372
|
-
if [[ -n "$DIRTY_FILES" ]]; then
|
|
373
|
-
log_error "Git working tree still not clean after auto-commit."
|
|
374
|
-
echo "$DIRTY_FILES" | sed 's/^/ - /'
|
|
375
|
-
SESSION_STATUS="failed"
|
|
379
|
+
git -C "$PROJECT_ROOT" commit --no-verify --amend --no-edit -a 2>/dev/null \
|
|
380
|
+
|| git -C "$PROJECT_ROOT" commit --no-verify -m "chore($BUG_ID): include remaining session artifacts" 2>/dev/null \
|
|
381
|
+
|| true
|
|
376
382
|
fi
|
|
377
383
|
fi
|
|
378
384
|
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"
|
|
@@ -353,7 +354,7 @@ else
|
|
|
353
354
|
# Exit code 0 — check if the session produced commits
|
|
354
355
|
HAS_COMMITS=""
|
|
355
356
|
if git -C "$PROJECT_ROOT" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
|
356
|
-
HAS_COMMITS=$(git -C "$PROJECT_ROOT" log
|
|
357
|
+
HAS_COMMITS=$(git -C "$PROJECT_ROOT" log "${DEFAULT_BRANCH}..HEAD" --oneline 2>/dev/null | head -1)
|
|
357
358
|
fi
|
|
358
359
|
|
|
359
360
|
if [[ -n "$HAS_COMMITS" ]]; then
|
|
@@ -361,8 +362,15 @@ else
|
|
|
361
362
|
else
|
|
362
363
|
UNCOMMITTED=$(git -C "$PROJECT_ROOT" status --porcelain 2>/dev/null | head -1 || true)
|
|
363
364
|
if [[ -n "$UNCOMMITTED" ]]; then
|
|
364
|
-
log_warn "Session exited cleanly but produced no commits (uncommitted changes found)"
|
|
365
|
-
|
|
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
|
|
366
374
|
else
|
|
367
375
|
log_warn "Session exited cleanly but produced no commits and no changes"
|
|
368
376
|
SESSION_STATUS="crashed"
|
|
@@ -377,14 +385,9 @@ if [[ "$SESSION_STATUS" == "success" ]]; then
|
|
|
377
385
|
if [[ -n "$DIRTY_FILES" ]]; then
|
|
378
386
|
log_info "Auto-committing remaining session artifacts..."
|
|
379
387
|
git -C "$PROJECT_ROOT" add -A 2>/dev/null || true
|
|
380
|
-
git -C "$PROJECT_ROOT" commit --no-verify -
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
DIRTY_FILES=$(git -C "$PROJECT_ROOT" status --porcelain 2>/dev/null || true)
|
|
384
|
-
if [[ -n "$DIRTY_FILES" ]]; then
|
|
385
|
-
log_error "Git working tree still not clean after auto-commit."
|
|
386
|
-
echo "$DIRTY_FILES" | sed 's/^/ - /'
|
|
387
|
-
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
|
|
388
391
|
fi
|
|
389
392
|
fi
|
|
390
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"
|
|
@@ -179,7 +183,7 @@ spawn_and_wait_session() {
|
|
|
179
183
|
# Exit code 0 — check if the session actually produced commits
|
|
180
184
|
local has_commits=""
|
|
181
185
|
if git -C "$project_root" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
|
182
|
-
has_commits=$(git -C "$project_root" log
|
|
186
|
+
has_commits=$(git -C "$project_root" log "${default_branch}..HEAD" --oneline 2>/dev/null | head -1)
|
|
183
187
|
fi
|
|
184
188
|
|
|
185
189
|
if [[ -n "$has_commits" ]]; then
|
|
@@ -188,8 +192,15 @@ spawn_and_wait_session() {
|
|
|
188
192
|
local uncommitted=""
|
|
189
193
|
uncommitted=$(git -C "$project_root" status --porcelain 2>/dev/null | head -1 || true)
|
|
190
194
|
if [[ -n "$uncommitted" ]]; then
|
|
191
|
-
log_warn "Session exited cleanly but produced no commits (uncommitted changes found)"
|
|
192
|
-
|
|
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
|
|
193
204
|
else
|
|
194
205
|
log_warn "Session exited cleanly but produced no commits and no changes"
|
|
195
206
|
session_status="crashed"
|
|
@@ -205,14 +216,9 @@ spawn_and_wait_session() {
|
|
|
205
216
|
if [[ -n "$dirty_files" ]]; then
|
|
206
217
|
log_info "Auto-committing remaining session artifacts..."
|
|
207
218
|
git -C "$project_root" add -A 2>/dev/null || true
|
|
208
|
-
git -C "$project_root" commit --no-verify -
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
dirty_files=$(git -C "$project_root" status --porcelain 2>/dev/null || true)
|
|
212
|
-
if [[ -n "$dirty_files" ]]; then
|
|
213
|
-
log_error "Git working tree still not clean after auto-commit."
|
|
214
|
-
echo "$dirty_files" | sed 's/^/ - /'
|
|
215
|
-
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
|
|
216
222
|
fi
|
|
217
223
|
fi
|
|
218
224
|
fi
|
|
@@ -527,6 +533,9 @@ main() {
|
|
|
527
533
|
log_info "Resuming existing bugfix pipeline..."
|
|
528
534
|
fi
|
|
529
535
|
|
|
536
|
+
# Auto-detect available models (must run before any git commit operations)
|
|
537
|
+
bash "$SCRIPT_DIR/scripts/detect-models.sh" --quiet 2>/dev/null || true
|
|
538
|
+
|
|
530
539
|
# Print header
|
|
531
540
|
echo ""
|
|
532
541
|
echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
|
|
@@ -588,7 +597,7 @@ main() {
|
|
|
588
597
|
_DEV_BRANCH_NAME=""
|
|
589
598
|
else
|
|
590
599
|
log_warn "Auto-merge failed — dev branch preserved: $_DEV_BRANCH_NAME"
|
|
591
|
-
log_warn "Merge manually: git checkout $_ORIGINAL_BRANCH && git
|
|
600
|
+
log_warn "Merge manually: git checkout $_ORIGINAL_BRANCH && git rebase $_DEV_BRANCH_NAME"
|
|
592
601
|
fi
|
|
593
602
|
fi
|
|
594
603
|
break
|
|
@@ -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"
|
|
@@ -201,7 +205,7 @@ spawn_and_wait_session() {
|
|
|
201
205
|
# Exit code 0 — check if the session actually produced commits
|
|
202
206
|
local has_commits=""
|
|
203
207
|
if git -C "$project_root" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
|
204
|
-
has_commits=$(git -C "$project_root" log
|
|
208
|
+
has_commits=$(git -C "$project_root" log "${default_branch}..HEAD" --oneline 2>/dev/null | head -1)
|
|
205
209
|
fi
|
|
206
210
|
|
|
207
211
|
if [[ -n "$has_commits" ]]; then
|
|
@@ -212,8 +216,15 @@ spawn_and_wait_session() {
|
|
|
212
216
|
local uncommitted=""
|
|
213
217
|
uncommitted=$(git -C "$project_root" status --porcelain 2>/dev/null | head -1 || true)
|
|
214
218
|
if [[ -n "$uncommitted" ]]; then
|
|
215
|
-
log_warn "Session exited cleanly but produced no commits (uncommitted changes found)"
|
|
216
|
-
|
|
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
|
|
217
228
|
else
|
|
218
229
|
log_warn "Session exited cleanly but produced no commits and no changes"
|
|
219
230
|
session_status="crashed"
|
|
@@ -230,30 +241,9 @@ spawn_and_wait_session() {
|
|
|
230
241
|
if [[ -n "$dirty_files" ]]; then
|
|
231
242
|
log_info "Auto-committing remaining session artifacts..."
|
|
232
243
|
git -C "$project_root" add -A 2>/dev/null || true
|
|
233
|
-
git -C "$project_root" commit --no-verify -
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
# Re-check: if still dirty after auto-commit, flag as commit_missing
|
|
237
|
-
dirty_files=$(git -C "$project_root" status --porcelain 2>/dev/null || true)
|
|
238
|
-
if [[ -n "$dirty_files" ]]; then
|
|
239
|
-
log_warn "Git working tree still not clean after auto-commit."
|
|
240
|
-
echo "$dirty_files" | sed 's/^/ - /'
|
|
241
|
-
session_status="commit_missing"
|
|
242
|
-
else
|
|
243
|
-
# Bugfix commits (fix: / fix(scope):) are exempt from docs check.
|
|
244
|
-
local last_commit_subject=""
|
|
245
|
-
last_commit_subject=$(git -C "$project_root" log -1 --pretty=%s 2>/dev/null || true)
|
|
246
|
-
if [[ "$last_commit_subject" =~ ^fix(\(|:) ]]; then
|
|
247
|
-
log_info "Detected bugfix commit prefix; skipping docs check."
|
|
248
|
-
else
|
|
249
|
-
local docs_changed=""
|
|
250
|
-
docs_changed=$(git -C "$project_root" log --name-only --format="" -1 2>/dev/null \
|
|
251
|
-
| grep -E '\.prizm-docs/' | head -1 || true)
|
|
252
|
-
if [[ -z "$docs_changed" ]]; then
|
|
253
|
-
log_warn "Session committed but no .prizm-docs changes detected."
|
|
254
|
-
session_status="docs_missing"
|
|
255
|
-
fi
|
|
256
|
-
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
|
|
257
247
|
fi
|
|
258
248
|
fi
|
|
259
249
|
fi
|
|
@@ -969,7 +959,7 @@ for f in data.get('stuck_features', []):
|
|
|
969
959
|
_DEV_BRANCH_NAME=""
|
|
970
960
|
else
|
|
971
961
|
log_warn "Auto-merge failed — dev branch preserved: $_DEV_BRANCH_NAME"
|
|
972
|
-
log_warn "Merge manually: git checkout $_ORIGINAL_BRANCH && git
|
|
962
|
+
log_warn "Merge manually: git checkout $_ORIGINAL_BRANCH && git rebase $_DEV_BRANCH_NAME"
|
|
973
963
|
fi
|
|
974
964
|
fi
|
|
975
965
|
break
|
|
@@ -13,6 +13,7 @@ features are found, 0 otherwise.
|
|
|
13
13
|
Usage:
|
|
14
14
|
python3 detect-stuck.py --state-dir <path> [--feature-id <id>]
|
|
15
15
|
[--max-retries <n>] [--stale-threshold <seconds>]
|
|
16
|
+
[--feature-list <path>]
|
|
16
17
|
"""
|
|
17
18
|
|
|
18
19
|
import argparse
|
|
@@ -53,6 +54,11 @@ def parse_args():
|
|
|
53
54
|
default=600,
|
|
54
55
|
help="Heartbeat staleness threshold in seconds (default: 600)",
|
|
55
56
|
)
|
|
57
|
+
parser.add_argument(
|
|
58
|
+
"--feature-list",
|
|
59
|
+
default=None,
|
|
60
|
+
help="Path to feature-list.json (overrides pipeline.json reference)",
|
|
61
|
+
)
|
|
56
62
|
return parser.parse_args()
|
|
57
63
|
|
|
58
64
|
|
|
@@ -289,14 +295,26 @@ def check_dependency_deadlock(feature_id, feature_list_data, state_dir):
|
|
|
289
295
|
|
|
290
296
|
|
|
291
297
|
def find_feature_list(state_dir):
|
|
292
|
-
"""Attempt to locate and load feature-list.json via pipeline.json reference.
|
|
298
|
+
"""Attempt to locate and load feature-list.json via pipeline.json reference.
|
|
299
|
+
|
|
300
|
+
Resolves feature_list_path relative to state_dir when it is a relative path,
|
|
301
|
+
so that pipeline.json is portable across machines and directory structures.
|
|
302
|
+
"""
|
|
293
303
|
pipeline_path = os.path.join(state_dir, "pipeline.json")
|
|
294
304
|
pipeline = load_json(pipeline_path)
|
|
295
305
|
if pipeline is None:
|
|
296
306
|
return None
|
|
297
307
|
|
|
298
308
|
fl_path = pipeline.get("feature_list_path")
|
|
299
|
-
if
|
|
309
|
+
if not fl_path:
|
|
310
|
+
return None
|
|
311
|
+
|
|
312
|
+
# Resolve relative paths relative to state_dir (not process cwd)
|
|
313
|
+
if not os.path.isabs(fl_path):
|
|
314
|
+
fl_path = os.path.join(state_dir, fl_path)
|
|
315
|
+
|
|
316
|
+
fl_path = os.path.normpath(fl_path)
|
|
317
|
+
if os.path.isfile(fl_path):
|
|
300
318
|
return load_json(fl_path)
|
|
301
319
|
|
|
302
320
|
return None
|
|
@@ -354,7 +372,11 @@ def main():
|
|
|
354
372
|
feature_ids = discover_feature_ids(state_dir)
|
|
355
373
|
|
|
356
374
|
# Load feature list for dependency checks
|
|
357
|
-
|
|
375
|
+
# Prefer CLI-provided path; fall back to pipeline.json reference
|
|
376
|
+
if args.feature_list:
|
|
377
|
+
feature_list_data = load_json(os.path.abspath(args.feature_list))
|
|
378
|
+
else:
|
|
379
|
+
feature_list_data = find_feature_list(state_dir)
|
|
358
380
|
|
|
359
381
|
stuck_features = []
|
|
360
382
|
for fid in feature_ids:
|
|
@@ -190,6 +190,8 @@ def create_state_directory(state_dir, bug_list_path, bugs):
|
|
|
190
190
|
"""Create the state directory structure with pipeline.json and per-bug status files."""
|
|
191
191
|
abs_state_dir = os.path.abspath(state_dir)
|
|
192
192
|
abs_bug_list_path = os.path.abspath(bug_list_path)
|
|
193
|
+
# Store as relative path from state_dir so pipeline.json is portable across machines
|
|
194
|
+
rel_bug_list_path = os.path.relpath(abs_bug_list_path, abs_state_dir)
|
|
193
195
|
bugs_dir = os.path.join(abs_state_dir, "bugs")
|
|
194
196
|
|
|
195
197
|
now = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
@@ -204,7 +206,7 @@ def create_state_directory(state_dir, bug_list_path, bugs):
|
|
|
204
206
|
"run_id": run_id,
|
|
205
207
|
"pipeline_type": "bugfix",
|
|
206
208
|
"status": "initialized",
|
|
207
|
-
"bug_list_path":
|
|
209
|
+
"bug_list_path": rel_bug_list_path,
|
|
208
210
|
"created_at": now,
|
|
209
211
|
"total_bugs": len(bugs),
|
|
210
212
|
"completed_bugs": 0,
|
|
@@ -226,6 +226,8 @@ def create_state_directory(state_dir, feature_list_path, features):
|
|
|
226
226
|
"""Create the state directory structure with pipeline.json and per-feature status files."""
|
|
227
227
|
abs_state_dir = os.path.abspath(state_dir)
|
|
228
228
|
abs_feature_list_path = os.path.abspath(feature_list_path)
|
|
229
|
+
# Store as relative path from state_dir so pipeline.json is portable across machines
|
|
230
|
+
rel_feature_list_path = os.path.relpath(abs_feature_list_path, abs_state_dir)
|
|
229
231
|
features_dir = os.path.join(abs_state_dir, "features")
|
|
230
232
|
|
|
231
233
|
now = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
@@ -245,7 +247,7 @@ def create_state_directory(state_dir, feature_list_path, features):
|
|
|
245
247
|
pipeline_state = {
|
|
246
248
|
"run_id": run_id,
|
|
247
249
|
"status": "initialized",
|
|
248
|
-
"feature_list_path":
|
|
250
|
+
"feature_list_path": rel_feature_list_path,
|
|
249
251
|
"created_at": now,
|
|
250
252
|
"total_features": len(features),
|
|
251
253
|
"completed_features": completed_count,
|
|
@@ -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
|
|