prizmkit 1.1.72 → 1.1.74
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 +11 -1
- package/bundled/dev-pipeline/lib/heartbeat.sh +71 -42
- package/bundled/dev-pipeline/scripts/parse-stream-progress.py +38 -0
- package/bundled/dev-pipeline/templates/agent-prompts/dev-implement.md +21 -0
- package/bundled/dev-pipeline/templates/bootstrap-tier2.md +1 -1
- package/bundled/dev-pipeline/templates/bootstrap-tier3.md +5 -9
- package/bundled/dev-pipeline/templates/sections/feature-context.md +3 -18
- package/bundled/dev-pipeline/templates/sections/phase-context-snapshot-agent-suffix.md +1 -1
- package/bundled/dev-pipeline/templates/sections/phase-context-snapshot-base.md +6 -12
- package/bundled/dev-pipeline/templates/sections/phase-context-snapshot-lite-suffix.md +10 -3
- package/bundled/dev-pipeline/templates/sections/phase-implement-agent.md +1 -0
- package/bundled/dev-pipeline/templates/sections/phase-specify-plan-full.md +4 -8
- package/bundled/dev-pipeline-windows/lib/pipeline.ps1 +26 -2
- package/bundled/dev-pipeline-windows/scripts/parse-stream-progress.py +38 -0
- package/bundled/dev-pipeline-windows/templates/agent-prompts/dev-implement.md +21 -0
- package/bundled/dev-pipeline-windows/templates/agent-prompts/reviewer-review.md +1 -1
- package/bundled/dev-pipeline-windows/templates/bootstrap-prompt.md +27 -0
- package/bundled/dev-pipeline-windows/templates/bootstrap-tier1.md +543 -14
- package/bundled/dev-pipeline-windows/templates/bootstrap-tier2.md +664 -14
- package/bundled/dev-pipeline-windows/templates/bootstrap-tier3.md +741 -14
- package/bundled/dev-pipeline-windows/templates/bugfix-bootstrap-prompt.md +2 -2
- package/bundled/dev-pipeline-windows/templates/feature-list-schema.json +1 -1
- package/bundled/dev-pipeline-windows/templates/refactor-bootstrap-prompt.md +1 -1
- package/bundled/dev-pipeline-windows/templates/refactor-list-schema.json +1 -1
- package/bundled/dev-pipeline-windows/templates/sections/context-budget-rules.md +3 -3
- package/bundled/dev-pipeline-windows/templates/sections/failure-capture.md +1 -1
- package/bundled/dev-pipeline-windows/templates/sections/feature-context.md +3 -18
- package/bundled/dev-pipeline-windows/templates/sections/phase-browser-verification-auto.md +239 -40
- package/bundled/dev-pipeline-windows/templates/sections/phase-browser-verification-opencli.md +75 -26
- package/bundled/dev-pipeline-windows/templates/sections/phase-browser-verification.md +142 -36
- package/bundled/dev-pipeline-windows/templates/sections/phase-commit-full.md +2 -2
- package/bundled/dev-pipeline-windows/templates/sections/phase-commit.md +1 -1
- package/bundled/dev-pipeline-windows/templates/sections/phase-context-snapshot-agent-suffix.md +1 -1
- package/bundled/dev-pipeline-windows/templates/sections/phase-context-snapshot-base.md +7 -17
- package/bundled/dev-pipeline-windows/templates/sections/phase-context-snapshot-lite-suffix.md +10 -3
- package/bundled/dev-pipeline-windows/templates/sections/phase-critic-plan-full.md +1 -1
- package/bundled/dev-pipeline-windows/templates/sections/phase-critic-plan.md +1 -1
- package/bundled/dev-pipeline-windows/templates/sections/phase-implement-agent.md +3 -1
- package/bundled/dev-pipeline-windows/templates/sections/phase-implement-full.md +7 -3
- package/bundled/dev-pipeline-windows/templates/sections/phase-implement-lite.md +1 -3
- package/bundled/dev-pipeline-windows/templates/sections/phase-plan-agent.md +1 -1
- package/bundled/dev-pipeline-windows/templates/sections/phase-plan-lite.md +1 -1
- package/bundled/dev-pipeline-windows/templates/sections/phase-review-agent.md +1 -1
- package/bundled/dev-pipeline-windows/templates/sections/phase-review-full.md +2 -2
- package/bundled/dev-pipeline-windows/templates/sections/phase-specify-plan-full.md +13 -17
- package/bundled/dev-pipeline-windows/templates/sections/phase0-test-baseline.md +2 -4
- package/bundled/dev-pipeline-windows/templates/sections/subagent-timeout-recovery.md +1 -1
- package/bundled/skills/_metadata.json +1 -1
- package/package.json +1 -1
package/bundled/VERSION.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: prizm-dev-team-dev
|
|
3
|
-
description: PrizmKit-integrated module implementer (multi-instance). Follows /prizmkit-implement workflow with TDD, marks tasks [x] in plan.md Tasks section
|
|
3
|
+
description: PrizmKit-integrated module implementer (multi-instance). Follows /prizmkit-implement workflow with TDD, marks tasks [x] in plan.md Tasks section. Works directly in the repository; uses git worktree only if explicitly instructed. Use when implementing specific feature modules.
|
|
4
4
|
tools: Read, Write, Edit, Bash, Glob, Grep, TaskCreate, TaskGet, TaskUpdate, TaskList, SendMessage
|
|
5
5
|
disallowedTools: Agent
|
|
6
6
|
model: inherit
|
|
@@ -86,6 +86,16 @@ DEV-17: DO NOT re-read source files already listed in context-snapshot.md Sectio
|
|
|
86
86
|
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.
|
|
87
87
|
DEV-19: Before writing any `.prizmkit/prizm-docs/` file, check if it exists. If it exists: only update durable fields (KEY_FILES, INTERFACES, DEPENDENCIES, file counts, RULES, TRAPS, DECISIONS) — never overwrite the full file. Never add CHANGELOG, UPDATED/date fields, or workflow metadata. Only create new L2 docs for sub-modules you are actively creating in this session.
|
|
88
88
|
DEV-20: Internal tracking IDs are not product copy. Before writing UI text or UI-copy assertions, translate references like `F-003 guard` into product-language behavior such as `the high-risk guard`. Add regression coverage when a feature touches user-visible text.
|
|
89
|
+
DEV-21: Before any Read with offset + limit, compute offset + limit. If the last tool_result for this file shows it has N lines, offset MUST be < N. Never request an offset >= known file length.
|
|
90
|
+
DEV-22: When Edit fails with 'String to replace not found':
|
|
91
|
+
1. STOP editing immediately — do NOT retry the same Edit.
|
|
92
|
+
2. Run `grep -n` to locate the exact line of the target text.
|
|
93
|
+
3. Read with offset = max(grep_line - 20, 0), limit = 50.
|
|
94
|
+
4. Copy the exact text from the Read result into the Edit old_string.
|
|
95
|
+
5. Never guess or extrapolate an offset — grep first, then read, then edit.
|
|
96
|
+
DEV-23: If 3 consecutive Read calls to the same file return 'shorter than provided offset' or 'Wasted call', STOP all work on that file. Send ESCALATION with the file path, current line count, and the offsets you attempted. The orchestrator will provide the correct content.
|
|
97
|
+
DEV-24: Before editing a large file (>1000 lines), verify you know its current line count from the most recent tool_result. Old line counts from earlier turns may be stale if you have since edited the file.
|
|
98
|
+
DEV-25: After every 3 successful Edit operations on a file, run the relevant test command for that file once to validate your changes compile and behave correctly. Do not defer all testing to the end.
|
|
89
99
|
```
|
|
90
100
|
|
|
91
101
|
### Workflow
|
|
@@ -90,48 +90,6 @@ PY
|
|
|
90
90
|
fi
|
|
91
91
|
prev_child_activity_signature="$child_activity_signature"
|
|
92
92
|
|
|
93
|
-
# Track progress staleness. Parent sessions can sit in a wait/polling
|
|
94
|
-
# tool while child transcripts keep growing, so child activity counts.
|
|
95
|
-
if [[ $growth -eq 0 && $child_growth -eq 0 ]]; then
|
|
96
|
-
stale_seconds=$((stale_seconds + heartbeat_interval))
|
|
97
|
-
else
|
|
98
|
-
stale_seconds=0
|
|
99
|
-
fi
|
|
100
|
-
|
|
101
|
-
local size_display
|
|
102
|
-
if [[ $cur_size -gt 1048576 ]]; then
|
|
103
|
-
size_display="$((cur_size / 1048576))MB"
|
|
104
|
-
elif [[ $cur_size -gt 1024 ]]; then
|
|
105
|
-
size_display="$((cur_size / 1024))KB"
|
|
106
|
-
else
|
|
107
|
-
size_display="${cur_size}B"
|
|
108
|
-
fi
|
|
109
|
-
local child_display=""
|
|
110
|
-
if [[ ${child_total_bytes:-0} -gt 0 ]]; then
|
|
111
|
-
local child_size_display
|
|
112
|
-
if [[ $child_total_bytes -gt 1048576 ]]; then
|
|
113
|
-
child_size_display="$((child_total_bytes / 1048576))MB"
|
|
114
|
-
elif [[ $child_total_bytes -gt 1024 ]]; then
|
|
115
|
-
child_size_display="$((child_total_bytes / 1024))KB"
|
|
116
|
-
else
|
|
117
|
-
child_size_display="${child_total_bytes}B"
|
|
118
|
-
fi
|
|
119
|
-
child_display=" | child: ${child_size_display}"
|
|
120
|
-
if [[ ${child_session_count:-0} -gt 1 ]]; then
|
|
121
|
-
child_display="${child_display}/${child_session_count}"
|
|
122
|
-
fi
|
|
123
|
-
fi
|
|
124
|
-
|
|
125
|
-
local mins=$((elapsed / 60))
|
|
126
|
-
local secs=$((elapsed % 60))
|
|
127
|
-
|
|
128
|
-
local status_icon
|
|
129
|
-
if [[ $growth -gt 0 || $child_growth -gt 0 ]]; then
|
|
130
|
-
status_icon="${GREEN}▶${NC}"
|
|
131
|
-
else
|
|
132
|
-
status_icon="${YELLOW}⏸${NC}"
|
|
133
|
-
fi
|
|
134
|
-
|
|
135
93
|
local effective_stale_kill_threshold="$stale_kill_threshold"
|
|
136
94
|
if [[ $stale_kill_threshold -gt 0 && -f "$progress_json" ]]; then
|
|
137
95
|
local codex_wait_threshold
|
|
@@ -173,6 +131,77 @@ PY
|
|
|
173
131
|
fi
|
|
174
132
|
fi
|
|
175
133
|
|
|
134
|
+
# Check for error-loop: agent is actively producing output but results are
|
|
135
|
+
# all read-offset errors or wasted calls. This is a stuck agent that appears
|
|
136
|
+
# "active" by log growth but is accomplishing nothing.
|
|
137
|
+
local error_loop_detected=false
|
|
138
|
+
if [[ $effective_stale_kill_threshold -gt 0 && $growth -gt 0 && -f "$progress_json" ]]; then
|
|
139
|
+
local error_loop_flag
|
|
140
|
+
error_loop_flag=$(python3 - "$progress_json" <<'PY' 2>/dev/null || true
|
|
141
|
+
import json, sys
|
|
142
|
+
try:
|
|
143
|
+
with open(sys.argv[1], encoding="utf-8") as fh:
|
|
144
|
+
progress = json.load(fh)
|
|
145
|
+
except Exception:
|
|
146
|
+
raise SystemExit(0)
|
|
147
|
+
errors = progress.get("errors", [])
|
|
148
|
+
if isinstance(errors, list) and len(errors) >= 5:
|
|
149
|
+
recent = errors[-5:]
|
|
150
|
+
if all(isinstance(e, dict) and e.get("type") in ("read_offset_overflow", "wasted_call") for e in recent):
|
|
151
|
+
print("error_loop")
|
|
152
|
+
PY
|
|
153
|
+
)
|
|
154
|
+
if [[ "$error_loop_flag" == "error_loop" ]]; then
|
|
155
|
+
error_loop_detected=true
|
|
156
|
+
fi
|
|
157
|
+
fi
|
|
158
|
+
|
|
159
|
+
# Track progress staleness. Parent sessions can sit in a wait/polling
|
|
160
|
+
# tool while child transcripts keep growing, so child activity counts.
|
|
161
|
+
# Error loops bypass normal growth-as-progress because the log is only
|
|
162
|
+
# growing with repeated failed reads or wasted calls.
|
|
163
|
+
if [[ "$error_loop_detected" == "true" ]]; then
|
|
164
|
+
stale_seconds=$effective_stale_kill_threshold
|
|
165
|
+
elif [[ $growth -eq 0 && $child_growth -eq 0 ]]; then
|
|
166
|
+
stale_seconds=$((stale_seconds + heartbeat_interval))
|
|
167
|
+
else
|
|
168
|
+
stale_seconds=0
|
|
169
|
+
fi
|
|
170
|
+
|
|
171
|
+
local size_display
|
|
172
|
+
if [[ $cur_size -gt 1048576 ]]; then
|
|
173
|
+
size_display="$((cur_size / 1048576))MB"
|
|
174
|
+
elif [[ $cur_size -gt 1024 ]]; then
|
|
175
|
+
size_display="$((cur_size / 1024))KB"
|
|
176
|
+
else
|
|
177
|
+
size_display="${cur_size}B"
|
|
178
|
+
fi
|
|
179
|
+
local child_display=""
|
|
180
|
+
if [[ ${child_total_bytes:-0} -gt 0 ]]; then
|
|
181
|
+
local child_size_display
|
|
182
|
+
if [[ $child_total_bytes -gt 1048576 ]]; then
|
|
183
|
+
child_size_display="$((child_total_bytes / 1048576))MB"
|
|
184
|
+
elif [[ $child_total_bytes -gt 1024 ]]; then
|
|
185
|
+
child_size_display="$((child_total_bytes / 1024))KB"
|
|
186
|
+
else
|
|
187
|
+
child_size_display="${child_total_bytes}B"
|
|
188
|
+
fi
|
|
189
|
+
child_display=" | child: ${child_size_display}"
|
|
190
|
+
if [[ ${child_session_count:-0} -gt 1 ]]; then
|
|
191
|
+
child_display="${child_display}/${child_session_count}"
|
|
192
|
+
fi
|
|
193
|
+
fi
|
|
194
|
+
|
|
195
|
+
local mins=$((elapsed / 60))
|
|
196
|
+
local secs=$((elapsed % 60))
|
|
197
|
+
|
|
198
|
+
local status_icon
|
|
199
|
+
if [[ $growth -gt 0 || $child_growth -gt 0 ]]; then
|
|
200
|
+
status_icon="${GREEN}▶${NC}"
|
|
201
|
+
else
|
|
202
|
+
status_icon="${YELLOW}⏸${NC}"
|
|
203
|
+
fi
|
|
204
|
+
|
|
176
205
|
# Fatal provider/runtime errors are terminal; do not wait for the
|
|
177
206
|
# stale window when progress.json already proves the model cannot
|
|
178
207
|
# continue (for example context_too_large).
|
|
@@ -264,6 +264,44 @@ class ProgressTracker:
|
|
|
264
264
|
self.event_format = self.event_format or "stream-json"
|
|
265
265
|
self.is_active = True
|
|
266
266
|
|
|
267
|
+
# Check for error patterns in tool_result content (supports both formats):
|
|
268
|
+
# A) Top-level tool_result events: event["content"] is the result text
|
|
269
|
+
# B) Nested user events: event["message"]["content"][] has type=="tool_result" items
|
|
270
|
+
content_candidates = []
|
|
271
|
+
|
|
272
|
+
# Format A: top-level tool_result
|
|
273
|
+
if event_type == "tool_result":
|
|
274
|
+
content_candidates.append(str(event.get("content", "")))
|
|
275
|
+
|
|
276
|
+
# Format B: nested inside user event
|
|
277
|
+
if event_type == "user":
|
|
278
|
+
message = event.get("message", {})
|
|
279
|
+
content_list = message.get("content", [])
|
|
280
|
+
if isinstance(content_list, list):
|
|
281
|
+
for item in content_list:
|
|
282
|
+
if isinstance(item, dict) and item.get("type") == "tool_result":
|
|
283
|
+
content_candidates.append(str(item.get("content", "")))
|
|
284
|
+
|
|
285
|
+
for result_text in content_candidates:
|
|
286
|
+
if "shorter than the provided offset" in result_text:
|
|
287
|
+
self.errors.append({
|
|
288
|
+
"type": "read_offset_overflow",
|
|
289
|
+
"tool": self.current_tool,
|
|
290
|
+
"at": datetime.now(timezone.utc).isoformat(),
|
|
291
|
+
})
|
|
292
|
+
break # one error per event is enough
|
|
293
|
+
elif "Wasted call" in result_text:
|
|
294
|
+
self.errors.append({
|
|
295
|
+
"type": "wasted_call",
|
|
296
|
+
"tool": self.current_tool,
|
|
297
|
+
"at": datetime.now(timezone.utc).isoformat(),
|
|
298
|
+
})
|
|
299
|
+
break
|
|
300
|
+
|
|
301
|
+
# Keep only last 20 errors to prevent unbounded growth in progress.json
|
|
302
|
+
if len(self.errors) > 20:
|
|
303
|
+
self.errors = self.errors[-20:]
|
|
304
|
+
|
|
267
305
|
elif event_type == "system":
|
|
268
306
|
# System events (hooks, init, task notifications, etc.) — track but don't count as messages.
|
|
269
307
|
self.event_format = self.event_format or "stream-json"
|
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
"Read {{DEV_SUBAGENT_PATH}}. Implement feature {{FEATURE_ID}} (slug: {{FEATURE_SLUG}}).
|
|
2
2
|
|
|
3
|
+
## Task Summary Card
|
|
4
|
+
|
|
5
|
+
**Objective**: Implement {{FEATURE_TITLE}}.
|
|
6
|
+
|
|
7
|
+
**Primary files** (see context-snapshot.md Section 4 for full manifest):
|
|
8
|
+
- Review plan.md Tasks section for the complete task-to-file mapping.
|
|
9
|
+
- Each task's `— file:` suffix identifies the target file.
|
|
10
|
+
|
|
11
|
+
**Test command**: `{{TEST_CMD}}`
|
|
12
|
+
|
|
13
|
+
**Known baseline failures**: `{{BASELINE_FAILURES}}`
|
|
14
|
+
|
|
15
|
+
**DO NOT**:
|
|
16
|
+
- Re-read source files already listed in context-snapshot.md Section 4 File Manifest
|
|
17
|
+
- Create new files unless a plan.md task explicitly requires it
|
|
18
|
+
- Run git commands
|
|
19
|
+
- Use mock success data or fake rows in UI/tests
|
|
20
|
+
|
|
3
21
|
## Required Inputs
|
|
4
22
|
|
|
5
23
|
1. Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` first.
|
|
@@ -35,6 +53,9 @@ Before returning, append `## Implementation Log` to `context-snapshot.md` with:
|
|
|
35
53
|
- Carry forward the Dev-isolated subset: skip scaffold/generated files listed in `context-snapshot.md`; verify dependency versions before install/build commands that resolve dependencies; after build/compile commands, ensure outputs are ignored and never commit generated artifacts.
|
|
36
54
|
- If tests fail, follow this Test Failure Recovery subset: classify failures as baseline, new regression, brittle test, or environment/tooling; fix new regressions and brittle tests while progress is being made; document baseline failures; write `failure-log.md` for blockers.
|
|
37
55
|
- Do not run git commands; staging and commit are handled by the orchestrator.
|
|
56
|
+
- **Edit safety**: If an Edit fails with 'String to replace not found', grep for the target text before retrying. Never guess file offsets — verify them with a Read or grep first.
|
|
57
|
+
- **Read safety**: If 3 consecutive Reads to the same file return 'shorter than offset' or 'Wasted call', STOP and report BLOCKED.
|
|
58
|
+
- **Test early**: Run `{{TEST_CMD}}` after every 3 successful Edit operations. Capture output to /tmp/test-out.txt and grep for failures.
|
|
38
59
|
|
|
39
60
|
Do not return success unless:
|
|
40
61
|
1. implementation tasks are complete;
|
|
@@ -131,7 +131,7 @@ If MISSING — build it now:
|
|
|
131
131
|
```bash
|
|
132
132
|
find . -maxdepth 2 -type d -not -path '*/node_modules/*' -not -path '*/.git/*' -not -path '*/dist/*' -not -path '*/build/*' -not -path '*/__pycache__/*' -not -path '*/vendor/*' | sed -e 's;[^/]*/;|____;g;s;____|; |;g'
|
|
133
133
|
```
|
|
134
|
-
- **Section 3 —
|
|
134
|
+
- **Section 3 — Key TRAPS & RULES**: relevant TRAPS/RULES from prizm-docs (not full copies)
|
|
135
135
|
- **Section 4 — File Manifest**: For each file relevant to this feature, list: file path, why it's needed (modify/reference/test), key interface signatures (function names + params + return types). Do NOT include full file content — agents read files on-demand. Format:
|
|
136
136
|
### Files to Modify
|
|
137
137
|
| File | Why Needed | Key Interfaces |
|
|
@@ -148,12 +148,9 @@ If `EXISTING_CODE` is non-empty: your spec/plan/tasks must reflect this existing
|
|
|
148
148
|
Identify the top-level source directories from the results.
|
|
149
149
|
3. Scan the detected source directories for files related to this feature; read each one
|
|
150
150
|
4. Write `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md`:
|
|
151
|
-
- **Section 1 — Feature Brief**: feature description + acceptance criteria (copy from above)
|
|
152
|
-
- **Section 2 —
|
|
153
|
-
|
|
154
|
-
find . -maxdepth 2 -type d -not -path '*/node_modules/*' -not -path '*/.git/*' -not -path '*/dist/*' -not -path '*/build/*' -not -path '*/__pycache__/*' -not -path '*/vendor/*' | sed -e 's;[^/]*/;|____;g;s;____|; |;g'
|
|
155
|
-
```
|
|
156
|
-
- **Section 3 — Prizm Context**: full content of root.prizm and relevant L1/L2 docs
|
|
151
|
+
- **Section 1 — Feature Brief**: feature description (2-3 lines) + acceptance criteria (copy from above)
|
|
152
|
+
- **Section 2 — Verification Gates**: copy the gate checklist from the Task Contract above
|
|
153
|
+
- **Section 3 — Key TRAPS & RULES**: extract only relevant TRAPS/RULES from prizm-docs that apply to files in this scope. Do NOT copy full L0/L1/L2 content.
|
|
157
154
|
- **Section 4 — File Manifest**: For each file relevant to this feature, list: file path, why it's needed (modify/reference/test), key interface signatures (function names + params + return types). Do NOT include full file content — agents read files on-demand. Format:
|
|
158
155
|
### Files to Modify
|
|
159
156
|
| File | Why Needed | Key Interfaces |
|
|
@@ -167,7 +164,6 @@ If `EXISTING_CODE` is non-empty: your spec/plan/tasks must reflect this existing
|
|
|
167
164
|
|
|
168
165
|
### Known TRAPS (from .prizmkit/prizm-docs/)
|
|
169
166
|
- <trap entries extracted from L1/L2 docs>
|
|
170
|
-
- **Section 5 — Existing Tests**: full content of related test files as code blocks
|
|
171
167
|
4. Confirm: `ls .prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md`
|
|
172
168
|
|
|
173
169
|
**After Step A**: Use context-snapshot.md Section 4 File Manifest to guide targeted file reads. Do NOT scan directories or read unrelated files.
|
|
@@ -200,7 +196,7 @@ Spawn failure cap: for team/config/lock errors, retry at most once for this Revi
|
|
|
200
196
|
|
|
201
197
|
Prompt:
|
|
202
198
|
> "Read {{REVIEWER_SUBAGENT_PATH}}. For feature {{FEATURE_ID}} (slug: {{FEATURE_SLUG}}):
|
|
203
|
-
> 1. Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` FIRST — Section 3 has
|
|
199
|
+
> 1. Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` FIRST — Section 3 has TRAPS/RULES, Section 4 has file manifest.
|
|
204
200
|
> 2. Cross-check `spec.md` and `plan.md` (including Tasks section) for consistency.
|
|
205
201
|
> 3. Before flagging CRITICAL or HIGH issues, read the relevant source files listed in the File Manifest to verify.
|
|
206
202
|
> Report: CRITICAL, HIGH, MEDIUM issues found (or 'No issues found')."
|
|
@@ -230,7 +226,7 @@ Spawn failure cap: for team/config/lock errors, retry at most once for this Crit
|
|
|
230
226
|
Prompt:
|
|
231
227
|
> "Read {{CRITIC_SUBAGENT_PATH}}. For feature {{FEATURE_ID}} (slug: {{FEATURE_SLUG}}):
|
|
232
228
|
> **MODE: Plan Challenge**
|
|
233
|
-
> 1. Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` FIRST — Section 3 has
|
|
229
|
+
> 1. Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` FIRST — Section 3 has TRAPS/RULES, Section 4 has file manifest.
|
|
234
230
|
> 2. Read `.prizmkit/prizm-docs/root.prizm` and relevant L1/L2 docs for affected modules.
|
|
235
231
|
> 3. Read existing source files in the modules this plan touches.
|
|
236
232
|
> 4. Challenge plan.md against the project's existing architecture, patterns, and style.
|
|
@@ -4,33 +4,18 @@
|
|
|
4
4
|
Use this material according to the following priority:
|
|
5
5
|
|
|
6
6
|
1. **Task Contract** — defines current scope and Verification Gates.
|
|
7
|
-
2. **
|
|
8
|
-
3. **
|
|
9
|
-
4. **Project Brief** — product background and architecture alignment.
|
|
10
|
-
5. **App Global Context** — stack, runtime, and testing conventions.
|
|
11
|
-
6. **Project Conventions** — repository-specific rules.
|
|
12
|
-
|
|
13
|
-
### User Raw Context
|
|
14
|
-
|
|
15
|
-
{{USER_CONTEXT}}
|
|
7
|
+
2. **Completed Dependencies** — existing interfaces; do not re-implement.
|
|
8
|
+
3. **App Global Context** — stack, runtime, testing conventions.
|
|
16
9
|
|
|
17
10
|
### Completed Dependencies
|
|
18
11
|
|
|
19
|
-
> Use this section to understand available interfaces and avoid duplicating completed work.
|
|
20
|
-
|
|
21
12
|
{{COMPLETED_DEPENDENCIES}}
|
|
22
13
|
|
|
23
|
-
### Project Brief
|
|
24
|
-
|
|
25
|
-
> Use this section for alignment only. Do not treat unrelated backlog items as current feature scope.
|
|
26
|
-
|
|
27
|
-
{{PROJECT_BRIEF}}
|
|
28
|
-
|
|
29
14
|
### App Global Context
|
|
30
15
|
|
|
31
16
|
{{GLOBAL_CONTEXT}}
|
|
32
17
|
|
|
33
18
|
### Project Conventions
|
|
34
19
|
|
|
35
|
-
> Read {{PLATFORM_CONVENTIONS}} for project-level coding standards
|
|
20
|
+
> Read {{PLATFORM_CONVENTIONS}} for project-level coding standards and architecture decisions.
|
|
36
21
|
</feature-context>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
- **Section 3 —
|
|
1
|
+
- **Section 3 — Key TRAPS & RULES**: extract only relevant TRAPS/RULES from prizm-docs. Do NOT copy full L0/L1/L2 content — the orchestrator already loaded them.
|
|
2
2
|
- **Section 4 — File Manifest**: For each file relevant to this feature, list: file path, why it's needed (modify/reference/test), key interface signatures (function names + params + return types). Do NOT include full file content — agents read files on-demand. Format:
|
|
3
3
|
### Files to Modify
|
|
4
4
|
| File | Why Needed | Key Interfaces |
|
|
@@ -6,15 +6,9 @@ ls .prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md 2>/dev/null && echo "EXI
|
|
|
6
6
|
|
|
7
7
|
If MISSING — build it now:
|
|
8
8
|
1. Read `.prizmkit/prizm-docs/root.prizm` and relevant L1/L2 prizm docs
|
|
9
|
-
2.
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
4. Write `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md`:
|
|
16
|
-
- **Section 1 — Task Contract**: Objective, scope rule, non-scope rule, and Verification Gates from the Task Contract above
|
|
17
|
-
- **Section 2 — Project Structure**: run the following to get a visual directory tree, then paste output:
|
|
18
|
-
```bash
|
|
19
|
-
find . -maxdepth 2 -type d -not -path '*/node_modules/*' -not -path '*/.git/*' -not -path '*/dist/*' -not -path '*/build/*' -not -path '*/__pycache__/*' -not -path '*/vendor/*' | sed -e 's;[^/]*/;|____;g;s;____|; |;g'
|
|
20
|
-
```
|
|
9
|
+
2. Read source files listed in the feature's scope (use prizm-docs KEY_FILES for guidance)
|
|
10
|
+
3. Write `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md`:
|
|
11
|
+
- **Section 1 — Feature Brief**: 2-3 line feature description from Task Contract
|
|
12
|
+
- **Section 2 — Verification Gates**: gate checklist from Task Contract
|
|
13
|
+
- **Section 3 — Key TRAPS & RULES**: extract only relevant TRAPS/RULES from prizm-docs that apply to files in this scope. Do NOT copy full L0/L1/L2 content.
|
|
14
|
+
- **Section 4 — File Manifest**: file path, why needed, key interfaces. Format: Files to Modify | Files for Reference tables.
|
|
@@ -1,6 +1,13 @@
|
|
|
1
|
-
- **Section 3 —
|
|
2
|
-
- **Section 4 —
|
|
3
|
-
|
|
1
|
+
- **Section 3 — Key TRAPS & RULES**: extract only relevant TRAPS/RULES from prizm-docs that apply to files in this scope. Do NOT copy full L0/L1/L2 content.
|
|
2
|
+
- **Section 4 — File Manifest**: For each relevant file, list path, why needed, key interface signatures. Use table format:
|
|
3
|
+
|
|
4
|
+
### Files to Modify
|
|
5
|
+
| File | Why Needed | Key Interfaces |
|
|
6
|
+
|------|-----------|----------------|
|
|
7
|
+
|
|
8
|
+
### Files for Reference
|
|
9
|
+
| File | Why Needed | Key Interfaces |
|
|
10
|
+
|------|-----------|----------------|
|
|
4
11
|
|
|
5
12
|
|
|
6
13
|
**Checkpoint update**: Run the update script to set step `context-snapshot` to `"completed"`:
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|-----------|-------|
|
|
8
8
|
| subagent_type | prizm-dev-team-dev |
|
|
9
9
|
| run_in_background | false |
|
|
10
|
+
| isolation | Leave empty — Dev works directly in the repo, no worktree |
|
|
10
11
|
|
|
11
12
|
**Agent spawn failure policy**:
|
|
12
13
|
- If spawning Dev fails with team/config/lock errors, retry at most once.
|
|
@@ -19,13 +19,10 @@ ls .prizmkit/specs/{{FEATURE_SLUG}}/ 2>/dev/null
|
|
|
19
19
|
Identify the top-level source directories from the results.
|
|
20
20
|
3. Scan the detected source directories for files related to this feature; read each one
|
|
21
21
|
4. Write `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md`:
|
|
22
|
-
- **Section 1 —
|
|
23
|
-
- **Section 2 —
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
```
|
|
27
|
-
- **Section 3 — Prizm Context**: full content of root.prizm and relevant L1/L2 docs
|
|
28
|
-
- **Section 4 — File Manifest**: For each file relevant to this feature, list: file path, why it's needed (modify/reference/test), key interface signatures (function names + params + return types). Do NOT include full file content — agents read files on-demand. Format:
|
|
22
|
+
- **Section 1 — Feature Brief**: feature description (copy from Task Contract above, 2-3 lines only)
|
|
23
|
+
- **Section 2 — Verification Gates**: copy the gate checklist from the Task Contract above
|
|
24
|
+
- **Section 3 — Key TRAPS & RULES**: extract TRAPS and RULES entries from loaded prizm-docs that apply to files in this feature's scope. Do NOT copy full L0/L1/L2 content — only the specific TRAPS/RULES lines relevant to the files listed in Section 4.
|
|
25
|
+
- **Section 4 — File Manifest**: For each file relevant to this feature, list path, why needed (modify/reference/test), key interface signatures. Do NOT include full file content. Format:
|
|
29
26
|
### Files to Modify
|
|
30
27
|
| File | Why Needed | Key Interfaces |
|
|
31
28
|
|------|-----------|----------------|
|
|
@@ -38,7 +35,6 @@ ls .prizmkit/specs/{{FEATURE_SLUG}}/ 2>/dev/null
|
|
|
38
35
|
|
|
39
36
|
### Known TRAPS (from .prizmkit/prizm-docs/)
|
|
40
37
|
- <trap entries extracted from L1/L2 docs>
|
|
41
|
-
- **Section 5 — Existing Tests**: full content of related test files as code blocks
|
|
42
38
|
5. Confirm: `ls .prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md`
|
|
43
39
|
|
|
44
40
|
**After Step A**: Use context-snapshot.md Section 4 File Manifest to guide targeted file reads. Do NOT scan directories or read unrelated files.
|
|
@@ -811,7 +811,32 @@ function Invoke-PrizmPipeline {
|
|
|
811
811
|
$childAdvanced = ($childSignature -and $childSignature -ne $previousChildActivitySignature)
|
|
812
812
|
$previousChildActivitySignature = $childSignature
|
|
813
813
|
|
|
814
|
-
|
|
814
|
+
$effectiveStaleKillThreshold = Get-PrizmEffectiveStaleKillThreshold -ProgressFile $progressJson -BaseThreshold $staleKillThreshold
|
|
815
|
+
|
|
816
|
+
# Check for error-loop: agent is actively producing output but results are
|
|
817
|
+
# all read-offset errors or wasted calls.
|
|
818
|
+
$errorLoopDetected = $false
|
|
819
|
+
if ($effectiveStaleKillThreshold -gt 0 -and $growth -gt 0 -and (Test-Path $progressJson)) {
|
|
820
|
+
try {
|
|
821
|
+
$progress = Get-Content $progressJson -Raw | ConvertFrom-Json
|
|
822
|
+
$errors = $progress.errors
|
|
823
|
+
if ($errors -is [array] -and $errors.Count -ge 5) {
|
|
824
|
+
$recent = $errors[-5..-1]
|
|
825
|
+
$allBad = ($recent | Where-Object {
|
|
826
|
+
$_.type -in @("read_offset_overflow", "wasted_call")
|
|
827
|
+
}).Count -eq 5
|
|
828
|
+
if ($allBad) {
|
|
829
|
+
$errorLoopDetected = $true
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
} catch {
|
|
833
|
+
# Ignore JSON parse errors — progress file may be incomplete or malformed
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
if ($errorLoopDetected) {
|
|
838
|
+
$staleSeconds = $effectiveStaleKillThreshold
|
|
839
|
+
} elseif ($growth -gt 0 -or $childAdvanced) {
|
|
815
840
|
$staleSeconds = 0
|
|
816
841
|
} else {
|
|
817
842
|
$staleSeconds += $waitSeconds
|
|
@@ -823,7 +848,6 @@ function Invoke-PrizmPipeline {
|
|
|
823
848
|
break
|
|
824
849
|
}
|
|
825
850
|
|
|
826
|
-
$effectiveStaleKillThreshold = Get-PrizmEffectiveStaleKillThreshold -ProgressFile $progressJson -BaseThreshold $staleKillThreshold
|
|
827
851
|
$fatalErrorCode = Get-PrizmProgressFatalErrorCode -ProgressFile $progressJson
|
|
828
852
|
if ($fatalErrorCode) {
|
|
829
853
|
$wasStaleKilled = $true
|
|
@@ -264,6 +264,44 @@ class ProgressTracker:
|
|
|
264
264
|
self.event_format = self.event_format or "stream-json"
|
|
265
265
|
self.is_active = True
|
|
266
266
|
|
|
267
|
+
# Check for error patterns in tool_result content (supports both formats):
|
|
268
|
+
# A) Top-level tool_result events: event["content"] is the result text
|
|
269
|
+
# B) Nested user events: event["message"]["content"][] has type=="tool_result" items
|
|
270
|
+
content_candidates = []
|
|
271
|
+
|
|
272
|
+
# Format A: top-level tool_result
|
|
273
|
+
if event_type == "tool_result":
|
|
274
|
+
content_candidates.append(str(event.get("content", "")))
|
|
275
|
+
|
|
276
|
+
# Format B: nested inside user event
|
|
277
|
+
if event_type == "user":
|
|
278
|
+
message = event.get("message", {})
|
|
279
|
+
content_list = message.get("content", [])
|
|
280
|
+
if isinstance(content_list, list):
|
|
281
|
+
for item in content_list:
|
|
282
|
+
if isinstance(item, dict) and item.get("type") == "tool_result":
|
|
283
|
+
content_candidates.append(str(item.get("content", "")))
|
|
284
|
+
|
|
285
|
+
for result_text in content_candidates:
|
|
286
|
+
if "shorter than the provided offset" in result_text:
|
|
287
|
+
self.errors.append({
|
|
288
|
+
"type": "read_offset_overflow",
|
|
289
|
+
"tool": self.current_tool,
|
|
290
|
+
"at": datetime.now(timezone.utc).isoformat(),
|
|
291
|
+
})
|
|
292
|
+
break # one error per event is enough
|
|
293
|
+
elif "Wasted call" in result_text:
|
|
294
|
+
self.errors.append({
|
|
295
|
+
"type": "wasted_call",
|
|
296
|
+
"tool": self.current_tool,
|
|
297
|
+
"at": datetime.now(timezone.utc).isoformat(),
|
|
298
|
+
})
|
|
299
|
+
break
|
|
300
|
+
|
|
301
|
+
# Keep only last 20 errors to prevent unbounded growth in progress.json
|
|
302
|
+
if len(self.errors) > 20:
|
|
303
|
+
self.errors = self.errors[-20:]
|
|
304
|
+
|
|
267
305
|
elif event_type == "system":
|
|
268
306
|
# System events (hooks, init, task notifications, etc.) — track but don't count as messages.
|
|
269
307
|
self.event_format = self.event_format or "stream-json"
|
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
"Read {{DEV_SUBAGENT_PATH}}. Implement feature {{FEATURE_ID}} (slug: {{FEATURE_SLUG}}).
|
|
2
2
|
|
|
3
|
+
## Task Summary Card
|
|
4
|
+
|
|
5
|
+
**Objective**: Implement {{FEATURE_TITLE}}.
|
|
6
|
+
|
|
7
|
+
**Primary files** (see context-snapshot.md Section 4 for full manifest):
|
|
8
|
+
- Review plan.md Tasks section for the complete task-to-file mapping.
|
|
9
|
+
- Each task's `— file:` suffix identifies the target file.
|
|
10
|
+
|
|
11
|
+
**Test command**: `{{TEST_CMD}}`
|
|
12
|
+
|
|
13
|
+
**Known baseline failures**: `{{BASELINE_FAILURES}}`
|
|
14
|
+
|
|
15
|
+
**DO NOT**:
|
|
16
|
+
- Re-read source files already listed in context-snapshot.md Section 4 File Manifest
|
|
17
|
+
- Create new files unless a plan.md task explicitly requires it
|
|
18
|
+
- Run git commands
|
|
19
|
+
- Use mock success data or fake rows in UI/tests
|
|
20
|
+
|
|
3
21
|
## Required Inputs
|
|
4
22
|
|
|
5
23
|
1. Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` first.
|
|
@@ -35,6 +53,9 @@ Before returning, append `## Implementation Log` to `context-snapshot.md` with:
|
|
|
35
53
|
- Carry forward the Dev-isolated subset: skip scaffold/generated files listed in `context-snapshot.md`; verify dependency versions before install/build commands that resolve dependencies; after build/compile commands, ensure outputs are ignored and never commit generated artifacts.
|
|
36
54
|
- If tests fail, follow this Test Failure Recovery subset: classify failures as baseline, new regression, brittle test, or environment/tooling; fix new regressions and brittle tests while progress is being made; document baseline failures; write `failure-log.md` for blockers.
|
|
37
55
|
- Do not run git commands; staging and commit are handled by the orchestrator.
|
|
56
|
+
- **Edit safety**: If an Edit fails with 'String to replace not found', use Select-String or a targeted Read to find the target text before retrying. Never guess file offsets — verify them first.
|
|
57
|
+
- **Read safety**: If 3 consecutive Reads to the same file return 'shorter than offset' or 'Wasted call', STOP and report BLOCKED.
|
|
58
|
+
- **Test early**: Run `{{TEST_CMD}}` after every 3 successful Edit operations. Capture output with `Tee-Object (Join-Path $env:TEMP "test-out.txt")` and use Select-String for failures.
|
|
38
59
|
|
|
39
60
|
Do not return success unless:
|
|
40
61
|
1. implementation tasks are complete;
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
1. Read `.prizmkit/specs/{{FEATURE_SLUG}}/spec.md` (if it exists) for goals and Verification Gates; if spec.md does not exist, read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` Section 1 Task Contract instead
|
|
3
3
|
2. Read `.prizmkit/specs/{{FEATURE_SLUG}}/plan.md` for architecture decisions and completed tasks
|
|
4
4
|
3. Run /prizmkit-code-review with artifact_dir=.prizmkit/specs/{{FEATURE_SLUG}}/. The skill will run its internal review-fix loop (Reviewer → filter → Dev fix, max 3 rounds) and write review-report.md.
|
|
5
|
-
4. Run the full test suite using `{{TEST_CMD}}`. When running tests:
|
|
5
|
+
4. Run the full test suite using `{{TEST_CMD}}`. When running tests: `& { {{TEST_CMD}} } 2>&1 | Tee-Object (Join-Path $env:TEMP "review-test-out.txt") | Select-Object -Last 20`, then Select-String `(Join-Path $env:TEMP "review-test-out.txt")` for details — do NOT re-run the suite multiple times.
|
|
6
6
|
5. review-report.md will be written to .prizmkit/specs/{{FEATURE_SLUG}}/ by prizmkit-code-review.
|
|
7
7
|
Report: verdict (PASS/NEEDS_FIXES), number of rounds, findings fixed/rejected."
|
|
@@ -17,6 +17,12 @@
|
|
|
17
17
|
|
|
18
18
|
{{ACCEPTANCE_CRITERIA}}
|
|
19
19
|
|
|
20
|
+
## Your Mission
|
|
21
|
+
|
|
22
|
+
You are the **session orchestrator**. Implement Feature {{FEATURE_ID}}: "{{FEATURE_TITLE}}".
|
|
23
|
+
|
|
24
|
+
**CRITICAL**: You MUST NOT exit until ALL work is complete and committed.
|
|
25
|
+
|
|
20
26
|
## Instructions
|
|
21
27
|
|
|
22
28
|
You are running in **headless non-interactive mode** — no human is available for input.
|
|
@@ -44,3 +50,24 @@ Infer what needs to be done from the feature context above and follow the standa
|
|
|
44
50
|
- Do NOT push to remote — the user will push manually.
|
|
45
51
|
- Write all artifacts to `.prizmkit/specs/{{FEATURE_SLUG}}/`.
|
|
46
52
|
- If a step fails after 3 attempts, write a status report and stop.
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
## Failure Capture Protocol
|
|
56
|
+
|
|
57
|
+
If you encounter an unrecoverable error, context overflow, or are about to exit without completing all steps:
|
|
58
|
+
|
|
59
|
+
1. Write `.prizmkit/specs/{{FEATURE_SLUG}}/failure-log.md` BEFORE exiting:
|
|
60
|
+
```
|
|
61
|
+
FAILURE_TYPE: timeout | test_failure | review_rejected | context_overflow | unknown
|
|
62
|
+
PHASE: <failed phase>
|
|
63
|
+
ROOT_CAUSE: <1-2 sentence explanation>
|
|
64
|
+
ATTEMPTED: <approaches already tried>
|
|
65
|
+
SUGGESTION: <what the next session should try differently>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
2. This file is intentionally lightweight — write it BEFORE context runs out.
|
|
69
|
+
|
|
70
|
+
After a successful session (all steps complete + commit done), delete it:
|
|
71
|
+
```powershell
|
|
72
|
+
Remove-Item -Force -ErrorAction SilentlyContinue .prizmkit/specs/{{FEATURE_SLUG}}/failure-log.md
|
|
73
|
+
```
|