prizmkit 1.0.137 → 1.0.139
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/dev-pipeline/lib/common.sh +12 -7
- package/bundled/dev-pipeline/run-bugfix.sh +7 -0
- package/bundled/dev-pipeline/run.sh +33 -2
- package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +12 -0
- package/bundled/dev-pipeline/templates/bootstrap-tier1.md +15 -18
- package/bundled/dev-pipeline/templates/bootstrap-tier2.md +9 -15
- package/bundled/dev-pipeline/templates/bootstrap-tier3.md +10 -18
- package/bundled/skills/_metadata.json +1 -1
- package/bundled/skills/prizmkit-implement/SKILL.md +4 -1
- package/bundled/skills/prizmkit-prizm-docs/SKILL.md +2 -2
- package/bundled/skills/prizmkit-retrospective/SKILL.md +5 -3
- package/package.json +1 -1
- package/src/manifest.js +2 -1
- package/src/scaffold.js +5 -4
- package/src/upgrade.js +5 -3
package/bundled/VERSION.json
CHANGED
|
@@ -90,22 +90,27 @@ except: pass
|
|
|
90
90
|
|
|
91
91
|
# prizm_detect_subagents <session_log>
|
|
92
92
|
#
|
|
93
|
-
# Scan session log for subagent spawns and log the result.
|
|
94
|
-
#
|
|
93
|
+
# Scan session log for subagent spawns, count them, and log the result.
|
|
94
|
+
# Sets _SUBAGENT_COUNT to the number of Agent tool calls detected.
|
|
95
95
|
# Requires: USE_STREAM_JSON (from detect_stream_json_support)
|
|
96
|
+
_SUBAGENT_COUNT=0
|
|
96
97
|
prizm_detect_subagents() {
|
|
97
98
|
local session_log="$1"
|
|
99
|
+
_SUBAGENT_COUNT=0
|
|
98
100
|
[[ -f "$session_log" ]] || return 0
|
|
99
101
|
|
|
100
|
-
local
|
|
102
|
+
local count=0
|
|
101
103
|
if [[ "$USE_STREAM_JSON" == "true" ]]; then
|
|
102
|
-
grep -
|
|
104
|
+
count=$(grep -c '"name"[[:space:]]*:[[:space:]]*"Agent"' "$session_log" 2>/dev/null || echo "0")
|
|
103
105
|
else
|
|
104
|
-
grep -
|
|
106
|
+
count=$(grep -cE '(Tool: Agent|"tool":\s*"Agent"|tool_use.*Agent|subagent_type)' "$session_log" 2>/dev/null || echo "0")
|
|
105
107
|
fi
|
|
106
108
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
+
_SUBAGENT_COUNT=$count
|
|
110
|
+
if [[ "$count" -gt 0 ]]; then
|
|
111
|
+
log_info "Subagent calls detected in session: $count"
|
|
112
|
+
else
|
|
113
|
+
log_info "Subagent calls detected in session: 0 (single-agent mode)"
|
|
109
114
|
fi
|
|
110
115
|
}
|
|
111
116
|
|
|
@@ -599,6 +599,7 @@ main() {
|
|
|
599
599
|
fi
|
|
600
600
|
|
|
601
601
|
local session_count=0
|
|
602
|
+
local total_subagent_calls=0
|
|
602
603
|
|
|
603
604
|
while true; do
|
|
604
605
|
# Find next bug to process
|
|
@@ -614,6 +615,7 @@ main() {
|
|
|
614
615
|
log_success "════════════════════════════════════════════════════"
|
|
615
616
|
log_success " All bugs processed! Bug fix pipeline finished."
|
|
616
617
|
log_success " Total sessions: $session_count"
|
|
618
|
+
log_success " Total subagent calls: $total_subagent_calls"
|
|
617
619
|
log_success "════════════════════════════════════════════════════"
|
|
618
620
|
|
|
619
621
|
# Merge dev branch back to original
|
|
@@ -672,6 +674,10 @@ main() {
|
|
|
672
674
|
--state-dir "$STATE_DIR" \
|
|
673
675
|
--output "$bootstrap_prompt" >/dev/null 2>&1
|
|
674
676
|
|
|
677
|
+
# Log agent configuration (bugfix always uses dual-agent: Orchestrator + Dev + Reviewer)
|
|
678
|
+
log_info "Pipeline mode: ${BOLD}standard${NC} (Dual Agent — Orchestrator + Dev + Reviewer)"
|
|
679
|
+
log_info "Agents: 3 (critic: disabled)"
|
|
680
|
+
|
|
675
681
|
# Spawn session
|
|
676
682
|
log_info "Spawning AI CLI session: $session_id"
|
|
677
683
|
_SPAWN_RESULT=""
|
|
@@ -681,6 +687,7 @@ main() {
|
|
|
681
687
|
"$bootstrap_prompt" "$session_dir" "$MAX_RETRIES" "$_ORIGINAL_BRANCH"
|
|
682
688
|
|
|
683
689
|
session_count=$((session_count + 1))
|
|
690
|
+
total_subagent_calls=$((total_subagent_calls + _SUBAGENT_COUNT))
|
|
684
691
|
|
|
685
692
|
log_info "Pausing 5s before next bug..."
|
|
686
693
|
sleep 5
|
|
@@ -647,8 +647,11 @@ sys.exit(1)
|
|
|
647
647
|
log_error "Failed to generate bootstrap prompt for $feature_id"
|
|
648
648
|
return 1
|
|
649
649
|
}
|
|
650
|
-
local feature_model
|
|
650
|
+
local feature_model pipeline_mode agent_count critic_enabled
|
|
651
651
|
feature_model=$(echo "$gen_output" | python3 -c "import json,sys; print(json.load(sys.stdin).get('model',''))" 2>/dev/null || echo "")
|
|
652
|
+
pipeline_mode=$(echo "$gen_output" | python3 -c "import json,sys; print(json.load(sys.stdin).get('pipeline_mode','lite'))" 2>/dev/null || echo "lite")
|
|
653
|
+
agent_count=$(echo "$gen_output" | python3 -c "import json,sys; print(json.load(sys.stdin).get('agent_count',1))" 2>/dev/null || echo "1")
|
|
654
|
+
critic_enabled=$(echo "$gen_output" | python3 -c "import json,sys; print(json.load(sys.stdin).get('critic_enabled','false'))" 2>/dev/null || echo "false")
|
|
652
655
|
|
|
653
656
|
# Dry-Run: Print info and exit
|
|
654
657
|
if [[ "$dry_run" == true ]]; then
|
|
@@ -664,6 +667,8 @@ sys.exit(1)
|
|
|
664
667
|
else
|
|
665
668
|
log_info "Mode: auto-detect (from complexity)"
|
|
666
669
|
fi
|
|
670
|
+
log_info "Pipeline mode: $pipeline_mode"
|
|
671
|
+
log_info "Agents: $agent_count (critic: $([ "$critic_enabled" = "true" ] && echo "enabled" || echo "disabled"))"
|
|
667
672
|
if [[ -n "$feature_model" ]]; then
|
|
668
673
|
log_info "Feature Model: $feature_model"
|
|
669
674
|
elif [[ -n "${MODEL:-}" ]]; then
|
|
@@ -707,6 +712,15 @@ sys.exit(1)
|
|
|
707
712
|
if [[ -n "$mode_override" ]]; then
|
|
708
713
|
log_info "Mode Override: $mode_override"
|
|
709
714
|
fi
|
|
715
|
+
local _run_one_mode_desc
|
|
716
|
+
case "$pipeline_mode" in
|
|
717
|
+
lite) _run_one_mode_desc="Tier 1 — Single Agent" ;;
|
|
718
|
+
standard) _run_one_mode_desc="Tier 2 — Orchestrator + Dev + Reviewer" ;;
|
|
719
|
+
full) _run_one_mode_desc="Tier 3 — Full Team (+ Multi-Critic)" ;;
|
|
720
|
+
*) _run_one_mode_desc="$pipeline_mode" ;;
|
|
721
|
+
esac
|
|
722
|
+
log_info "Pipeline mode: ${BOLD}$pipeline_mode${NC} ($_run_one_mode_desc)"
|
|
723
|
+
log_info "Agents: $agent_count (critic: $([ "$critic_enabled" = "true" ] && echo "enabled" || echo "disabled"))"
|
|
710
724
|
if [[ $SESSION_TIMEOUT -gt 0 ]]; then
|
|
711
725
|
log_info "Session timeout: ${SESSION_TIMEOUT}s"
|
|
712
726
|
else
|
|
@@ -881,6 +895,7 @@ main() {
|
|
|
881
895
|
|
|
882
896
|
# Main processing loop
|
|
883
897
|
local session_count=0
|
|
898
|
+
local total_subagent_calls=0
|
|
884
899
|
|
|
885
900
|
while true; do
|
|
886
901
|
# Check for stuck features
|
|
@@ -923,6 +938,7 @@ for f in data.get('stuck_features', []):
|
|
|
923
938
|
log_success "════════════════════════════════════════════════════"
|
|
924
939
|
log_success " All features completed! Pipeline finished."
|
|
925
940
|
log_success " Total sessions: $session_count"
|
|
941
|
+
log_success " Total subagent calls: $total_subagent_calls"
|
|
926
942
|
log_success "════════════════════════════════════════════════════"
|
|
927
943
|
break
|
|
928
944
|
fi
|
|
@@ -999,8 +1015,22 @@ for f in data.get('stuck_features', []):
|
|
|
999
1015
|
log_error "Failed to generate bootstrap prompt for $feature_id"
|
|
1000
1016
|
continue
|
|
1001
1017
|
}
|
|
1002
|
-
local feature_model
|
|
1018
|
+
local feature_model pipeline_mode agent_count critic_enabled
|
|
1003
1019
|
feature_model=$(echo "$gen_output" | python3 -c "import json,sys; print(json.load(sys.stdin).get('model',''))" 2>/dev/null || echo "")
|
|
1020
|
+
pipeline_mode=$(echo "$gen_output" | python3 -c "import json,sys; print(json.load(sys.stdin).get('pipeline_mode','lite'))" 2>/dev/null || echo "lite")
|
|
1021
|
+
agent_count=$(echo "$gen_output" | python3 -c "import json,sys; print(json.load(sys.stdin).get('agent_count',1))" 2>/dev/null || echo "1")
|
|
1022
|
+
critic_enabled=$(echo "$gen_output" | python3 -c "import json,sys; print(json.load(sys.stdin).get('critic_enabled','false'))" 2>/dev/null || echo "false")
|
|
1023
|
+
|
|
1024
|
+
# Log pipeline mode and agent configuration
|
|
1025
|
+
local _mode_desc
|
|
1026
|
+
case "$pipeline_mode" in
|
|
1027
|
+
lite) _mode_desc="Tier 1 — Single Agent" ;;
|
|
1028
|
+
standard) _mode_desc="Tier 2 — Orchestrator + Dev + Reviewer" ;;
|
|
1029
|
+
full) _mode_desc="Tier 3 — Full Team (+ Multi-Critic)" ;;
|
|
1030
|
+
*) _mode_desc="$pipeline_mode" ;;
|
|
1031
|
+
esac
|
|
1032
|
+
log_info "Pipeline mode: ${BOLD}$pipeline_mode${NC} ($_mode_desc)"
|
|
1033
|
+
log_info "Agents: $agent_count (critic: $([ "$critic_enabled" = "true" ] && echo "enabled" || echo "disabled"))"
|
|
1004
1034
|
|
|
1005
1035
|
# Mark feature as in-progress before spawning session
|
|
1006
1036
|
python3 "$SCRIPTS_DIR/update-feature-status.py" \
|
|
@@ -1042,6 +1072,7 @@ for f in data.get('stuck_features', []):
|
|
|
1042
1072
|
fi
|
|
1043
1073
|
|
|
1044
1074
|
session_count=$((session_count + 1))
|
|
1075
|
+
total_subagent_calls=$((total_subagent_calls + _SUBAGENT_COUNT))
|
|
1045
1076
|
|
|
1046
1077
|
# Brief pause before next iteration
|
|
1047
1078
|
log_info "Pausing 5s before next feature..."
|
|
@@ -723,10 +723,22 @@ def main():
|
|
|
723
723
|
|
|
724
724
|
# Success
|
|
725
725
|
feature_model = feature.get("model", "")
|
|
726
|
+
pipeline_mode = replacements.get("{{PIPELINE_MODE}}", "lite")
|
|
727
|
+
critic_enabled = replacements.get("{{CRITIC_ENABLED}}", "false") == "true"
|
|
728
|
+
# Map mode to agent count for logging
|
|
729
|
+
# lite=1 (single agent), standard/full=3 (orchestrator + dev + reviewer)
|
|
730
|
+
mode_agent_counts = {"lite": 1, "standard": 3, "full": 3}
|
|
731
|
+
agent_count = mode_agent_counts.get(pipeline_mode, 1)
|
|
732
|
+
critic_count_val = int(replacements.get("{{CRITIC_COUNT}}", "1"))
|
|
733
|
+
if critic_enabled:
|
|
734
|
+
agent_count += critic_count_val
|
|
726
735
|
output = {
|
|
727
736
|
"success": True,
|
|
728
737
|
"output_path": os.path.abspath(args.output),
|
|
729
738
|
"model": feature_model,
|
|
739
|
+
"pipeline_mode": pipeline_mode,
|
|
740
|
+
"agent_count": agent_count,
|
|
741
|
+
"critic_enabled": "true" if critic_enabled else "false",
|
|
730
742
|
}
|
|
731
743
|
print(json.dumps(output, indent=2, ensure_ascii=False))
|
|
732
744
|
sys.exit(0)
|
|
@@ -130,7 +130,7 @@ grep -q '^/binary-name$' .gitignore || echo '/binary-name' >> .gitignore
|
|
|
130
130
|
```
|
|
131
131
|
Never commit compiled binaries, build output, or generated artifacts.
|
|
132
132
|
|
|
133
|
-
**
|
|
133
|
+
**3a.** Detect the test command and record baseline:
|
|
134
134
|
```bash
|
|
135
135
|
# Try in order, use first that exits 0
|
|
136
136
|
node --test tests/**/*.test.js 2>&1 | tail -3 # Node built-in
|
|
@@ -141,26 +141,22 @@ Record the working command as `TEST_CMD`. Then record baseline failures (if any)
|
|
|
141
141
|
$TEST_CMD 2>&1 | tee /tmp/test-baseline.txt | tail -20
|
|
142
142
|
```
|
|
143
143
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
144
|
+
**3b.** Run `/prizmkit-implement` — this handles the full implementation cycle:
|
|
145
|
+
- Reads plan.md Tasks section from `.prizmkit/specs/{{FEATURE_SLUG}}/`
|
|
146
|
+
- Reads context from `context-snapshot.md` (Prizm docs, TRAPS, file manifest)
|
|
147
|
+
- Implements task-by-task with TDD, marking each `[x]` immediately
|
|
148
|
+
- Creates/updates L2 `.prizm` docs when creating new modules or significantly modifying existing ones — AI selectively decides which modules warrant L2 based on complexity and importance
|
|
149
|
+
- Runs tests using `TEST_CMD` after each task
|
|
150
|
+
- Writes '## Implementation Log' to `context-snapshot.md`
|
|
149
151
|
|
|
150
|
-
After
|
|
151
|
-
1.
|
|
152
|
-
2.
|
|
153
|
-
3.
|
|
152
|
+
**3c.** After implement completes, verify:
|
|
153
|
+
1. All tasks in plan.md are `[x]`
|
|
154
|
+
2. Run the full test suite to ensure nothing is broken
|
|
155
|
+
3. Verify each acceptance criterion from Section 1 of context-snapshot.md is met — check mentally, do NOT re-read files you already wrote
|
|
156
|
+
4. If any criterion is not met, fix it now (max 2 fix rounds)
|
|
154
157
|
|
|
155
158
|
**CP-2**: All acceptance criteria met, all tests pass.
|
|
156
159
|
|
|
157
|
-
After verification, append to `context-snapshot.md`:
|
|
158
|
-
```
|
|
159
|
-
## Implementation Log
|
|
160
|
-
Files changed/created: [list]
|
|
161
|
-
Key decisions: [list]
|
|
162
|
-
```
|
|
163
|
-
|
|
164
160
|
{{IF_BROWSER_INTERACTION}}
|
|
165
161
|
### Phase 3.5: Browser Verification (playwright-cli)
|
|
166
162
|
|
|
@@ -188,7 +184,8 @@ If any step fails, log the failure and continue. Do NOT retry browser verificati
|
|
|
188
184
|
**4a.** Run `/prizmkit-retrospective` — maintains `.prizm-docs/` (architecture index):
|
|
189
185
|
1. **Structural sync**: Use `git diff --cached --name-status` to locate changed modules, update KEY_FILES/INTERFACES/DEPENDENCIES/file counts in affected `.prizm-docs/` files
|
|
190
186
|
2. **Architecture knowledge** (feature sessions only): Extract TRAPS/RULES/DECISIONS from completed work into `.prizm-docs/`
|
|
191
|
-
3.
|
|
187
|
+
3. **L2 coverage check**: For any module/sub-module with source files created or significantly modified in this session but no L2 `.prizm` doc — evaluate whether L2 is warranted and create if so. The current session has the best context for accurate KEY_FILES, TRAPS, and DECISIONS.
|
|
188
|
+
4. Stage doc changes: `git add .prizm-docs/`
|
|
192
189
|
⚠️ Do NOT commit here. Only stage.
|
|
193
190
|
|
|
194
191
|
**4b.** Stage all feature code explicitly (NEVER use `git add -A` or `git add .`):
|
|
@@ -194,20 +194,13 @@ Wait for Critic to return.
|
|
|
194
194
|
Spawn Dev subagent (Agent tool, subagent_type="prizm-dev-team-dev", run_in_background=false).
|
|
195
195
|
|
|
196
196
|
Prompt:
|
|
197
|
-
> "Read {{DEV_SUBAGENT_PATH}}. Implement feature {{FEATURE_ID}} (slug: {{FEATURE_SLUG}})
|
|
198
|
-
> **IMPORTANT**: Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` FIRST.
|
|
199
|
-
>
|
|
200
|
-
>
|
|
201
|
-
> 2.
|
|
202
|
-
> 3.
|
|
203
|
-
> 4.
|
|
204
|
-
> 5. After ALL tasks done, append '## Implementation Log' to context-snapshot.md with:
|
|
205
|
-
> - Files changed/created (with paths)
|
|
206
|
-
> - Key implementation decisions and rationale
|
|
207
|
-
> - Deviations from plan.md (if any)
|
|
208
|
-
> - Notable discoveries (unexpected behavior, hidden dependencies, new TRAPS)
|
|
209
|
-
> 6. Do NOT execute any git commands (no git add/commit/reset/push).
|
|
210
|
-
> 7. If `<TEST_CMD>` shows failures, check against BASELINE_FAILURES=`<BASELINE_FAILURES>`. Failures present in the baseline are pre-existing — list them explicitly in your COMPLETION_SIGNAL.
|
|
197
|
+
> "Read {{DEV_SUBAGENT_PATH}}. Implement feature {{FEATURE_ID}} (slug: {{FEATURE_SLUG}}).
|
|
198
|
+
> **IMPORTANT**: Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` FIRST — Section 3 has Prizm Context (TRAPS/RULES), Section 4 has File Manifest with paths and interfaces.
|
|
199
|
+
> ⚠️ DO NOT re-read source files already listed in Section 4 File Manifest unless you need implementation detail beyond the interface summary.
|
|
200
|
+
> 1. Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` for full context.
|
|
201
|
+
> 2. Run `/prizmkit-implement` to execute the tasks in plan.md. Use `TEST_CMD=<TEST_CMD>` for testing. Baseline failures: `BASELINE_FAILURES=<BASELINE_FAILURES>`.
|
|
202
|
+
> 3. After implement completes, verify the '## Implementation Log' section was written to context-snapshot.md.
|
|
203
|
+
> 4. Do NOT execute any git commands (no git add/commit/reset/push).
|
|
211
204
|
> Do NOT exit until all tasks are [x] and the '## Implementation Log' section is written in context-snapshot.md."
|
|
212
205
|
|
|
213
206
|
Wait for Dev to return. All tasks must be `[x]`, tests pass.
|
|
@@ -302,7 +295,8 @@ If any step fails, log the failure and continue. Do NOT retry browser verificati
|
|
|
302
295
|
**6a.** Run `/prizmkit-retrospective` — maintains `.prizm-docs/` (architecture index):
|
|
303
296
|
1. **Structural sync**: Use `git diff --cached --name-status` to locate changed modules, update KEY_FILES/INTERFACES/DEPENDENCIES/file counts in affected `.prizm-docs/` files
|
|
304
297
|
2. **Architecture knowledge** (feature sessions only): Extract TRAPS/RULES/DECISIONS from completed work into `.prizm-docs/`
|
|
305
|
-
3.
|
|
298
|
+
3. **L2 coverage check**: For any module/sub-module with source files created or significantly modified in this session but no L2 `.prizm` doc — evaluate whether L2 is warranted and create if so. The current session has the best context for accurate KEY_FILES, TRAPS, and DECISIONS.
|
|
299
|
+
4. Stage doc changes: `git add .prizm-docs/`
|
|
306
300
|
⚠️ Do NOT commit here. Only stage.
|
|
307
301
|
|
|
308
302
|
**6b.** Stage all feature code explicitly (NEVER use `git add -A` or `git add .`):
|
|
@@ -274,20 +274,13 @@ grep -c '^\- \[ \]' .prizmkit/specs/{{FEATURE_SLUG}}/plan.md 2>/dev/null || echo
|
|
|
274
274
|
Spawn Dev agent (Agent tool, subagent_type="prizm-dev-team-dev", run_in_background=false).
|
|
275
275
|
|
|
276
276
|
Prompt:
|
|
277
|
-
> "Read {{DEV_SUBAGENT_PATH}}. Implement feature {{FEATURE_ID}} (slug: {{FEATURE_SLUG}})
|
|
278
|
-
> **IMPORTANT**: Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` FIRST.
|
|
279
|
-
>
|
|
280
|
-
>
|
|
281
|
-
> 2.
|
|
282
|
-
> 3.
|
|
283
|
-
> 4.
|
|
284
|
-
> 5. After ALL tasks done, append '## Implementation Log' to context-snapshot.md with:
|
|
285
|
-
> - Files changed/created (with paths)
|
|
286
|
-
> - Key implementation decisions and rationale
|
|
287
|
-
> - Deviations from plan.md (if any)
|
|
288
|
-
> - Notable discoveries (unexpected behavior, hidden dependencies, new TRAPS)
|
|
289
|
-
> 6. Do NOT execute any git commands (no git add/commit/reset/push).
|
|
290
|
-
> 7. If `<TEST_CMD>` shows failures, check against BASELINE_FAILURES=`<BASELINE_FAILURES>`. Failures present in the baseline are pre-existing — list them explicitly in your COMPLETION_SIGNAL.
|
|
277
|
+
> "Read {{DEV_SUBAGENT_PATH}}. Implement feature {{FEATURE_ID}} (slug: {{FEATURE_SLUG}}).
|
|
278
|
+
> **IMPORTANT**: Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` FIRST — Section 3 has Prizm Context (TRAPS/RULES), Section 4 has File Manifest with paths and interfaces.
|
|
279
|
+
> ⚠️ DO NOT re-read source files already listed in Section 4 File Manifest unless you need implementation detail beyond the interface summary.
|
|
280
|
+
> 1. Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` for full context.
|
|
281
|
+
> 2. Run `/prizmkit-implement` to execute the tasks in plan.md. Use `TEST_CMD=<TEST_CMD>` for testing. Baseline failures: `BASELINE_FAILURES=<BASELINE_FAILURES>`.
|
|
282
|
+
> 3. After implement completes, verify the '## Implementation Log' section was written to context-snapshot.md.
|
|
283
|
+
> 4. Do NOT execute any git commands (no git add/commit/reset/push).
|
|
291
284
|
> Do NOT exit until all tasks are [x] and the '## Implementation Log' section is written in context-snapshot.md."
|
|
292
285
|
|
|
293
286
|
**Gate Check — Implementation Log**:
|
|
@@ -303,10 +296,8 @@ Wait for Dev to return. **If Dev times out before all tasks are `[x]`**:
|
|
|
303
296
|
> "Read {{DEV_SUBAGENT_PATH}}. You are resuming implementation of feature {{FEATURE_ID}} (slug: {{FEATURE_SLUG}}).
|
|
304
297
|
> 1. Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` — Section 4 has File Manifest, 'Implementation Log' (if present) shows what was already done.
|
|
305
298
|
> 2. Run `git diff HEAD` to see actual code changes already made.
|
|
306
|
-
> 3.
|
|
307
|
-
> 4.
|
|
308
|
-
> 5. Append progress to '## Implementation Log' in context-snapshot.md.
|
|
309
|
-
> 6. Do NOT execute any git commands."
|
|
299
|
+
> 3. Run `/prizmkit-implement` to complete the remaining `[ ]` tasks. Use `TEST_CMD=<TEST_CMD>` for testing.
|
|
300
|
+
> 4. Do NOT execute any git commands."
|
|
310
301
|
3. Max 2 recovery retries. After 2 failures, orchestrator implements remaining tasks directly.
|
|
311
302
|
|
|
312
303
|
All tasks `[x]`, tests pass.
|
|
@@ -412,6 +403,7 @@ git log --oneline | grep "{{FEATURE_ID}}" | head -3
|
|
|
412
403
|
**6b.** Run `/prizmkit-retrospective` (**before commit**, maintains `.prizm-docs/` architecture index):
|
|
413
404
|
- **Structural sync**: update KEY_FILES/INTERFACES/DEPENDENCIES/file counts for changed modules
|
|
414
405
|
- **Architecture knowledge** (feature sessions only): extract TRAPS, RULES, DECISIONS from completed work into `.prizm-docs/`
|
|
406
|
+
- **L2 coverage check**: For any module/sub-module with source files created or significantly modified in this session but no L2 `.prizm` doc — evaluate whether L2 is warranted and create if so. The current session has the best context for accurate KEY_FILES, TRAPS, and DECISIONS.
|
|
415
407
|
- Stage doc changes: `git add .prizm-docs/`
|
|
416
408
|
⚠️ Do NOT commit here. Only stage.
|
|
417
409
|
- **For bug-fix sessions**: structural sync only, skip knowledge injection unless a genuinely new pitfall was discovered
|
|
@@ -39,7 +39,10 @@ Execute implementation by following the task breakdown in plan.md. Respects task
|
|
|
39
39
|
3. Check if checkpoint tasks are complete before proceeding to next phase
|
|
40
40
|
4. For each unchecked task in order:
|
|
41
41
|
a. If task has `[P]` marker, it can run in parallel with other `[P]` tasks in the same group
|
|
42
|
-
b. Read L2 doc for target file's module
|
|
42
|
+
b. Read L2 doc for target file's module. TRAPS save you from repeating known mistakes.
|
|
43
|
+
- If L2 exists: check TRAPS and DECISIONS before modifying files.
|
|
44
|
+
- If L2 does not exist and this task creates a new module directory or adds significant source files: create L2 using the L2 GENERATION TEMPLATE (see PRIZM-SPEC). Seed KEY_FILES and DEPENDENCIES from the files being created. TRAPS and DECISIONS can be minimal initially — `/prizmkit-retrospective` will enrich them.
|
|
45
|
+
- Judgment call: not every directory needs L2. Create L2 when the module has meaningful logic, non-obvious coupling, or design decisions worth preserving. Skip for trivial wrapper directories or single-config modules.
|
|
43
46
|
c. Apply TDD where applicable: write a failing test first, then implement until it passes. For UI components or configuration changes where unit tests don't apply, skip the test-first step.
|
|
44
47
|
d. Mark task as `[x]` in `plan.md` Tasks section immediately — not batched at the end. Immediate marking means the plan always reflects true progress, even if the session is interrupted.
|
|
45
48
|
e. After all tasks, append '## Implementation Log' to `context-snapshot.md` (if running in pipeline context): files changed/created, key decisions, notable discoveries.
|
|
@@ -76,7 +76,7 @@ STEPS:
|
|
|
76
76
|
3. Classify each change: A (added) -> new KEY_FILES entries. D (deleted) -> remove entries, update counts. M (modified) -> check dependency changes. R (renamed) -> update all path references.
|
|
77
77
|
4. Update affected docs: L2 first (KEY_FILES, INTERFACES, DATA_FLOW, DEPENDENCIES, TRAPS, CHANGELOG), then L1 (FILES count, KEY_FILES, DEPENDENCIES — L1 does NOT contain INTERFACES/DATA_FLOW/TRAPS/DECISIONS), then L0 (MODULE_INDEX counts, CROSS_CUTTING) only if structural change. No UPDATED timestamps — git tracks modification times.
|
|
78
78
|
5. Skip updates if: only internal implementation changed (no interface/dependency change), only comments/whitespace/formatting, only .prizm files changed. DO NOT skip test file changes or bug fixes — they may reveal TRAPS worth capturing in L2.
|
|
79
|
-
6. If new directory qualifies as a module (per MODULE_DISCOVERY_CRITERIA) and matches no existing module: create L1 immediately, add to MODULE_INDEX
|
|
79
|
+
6. If new directory qualifies as a module (per MODULE_DISCOVERY_CRITERIA) and matches no existing module: create L1 immediately, add to MODULE_INDEX. If the current diff includes Added or Modified source files in this module → also create L2 immediately using the L2 GENERATION TEMPLATE. Otherwise defer L2.
|
|
80
80
|
7. Append entries to changelog.prizm using format: `- YYYY-MM-DD | <module-path> | <verb>: <description>`
|
|
81
81
|
8. Enforce size limits: L0 > 4KB -> consolidate. L1 > 4KB -> trim KEY_FILES descriptions, ensure RULES <= 3 entries. L2 > 5KB -> split or archive.
|
|
82
82
|
9. Stage updated .prizm files via `git add .prizm-docs/`
|
|
@@ -162,7 +162,7 @@ When working in a project with .prizm-docs/:
|
|
|
162
162
|
|
|
163
163
|
- ON SESSION START: Always read .prizm-docs/root.prizm (L0). This is the project map.
|
|
164
164
|
- ON TASK: Read L1 docs for relevant modules referenced in MODULE_INDEX.
|
|
165
|
-
- ON FILE EDIT: Read L2 doc before modifying files. Check TRAPS and DECISIONS sections.
|
|
165
|
+
- ON FILE EDIT: Read L2 doc before modifying files. Check TRAPS and DECISIONS sections. If L2 does not exist and you are creating/modifying significant source files in this module → generate L2 using the L2 GENERATION TEMPLATE before proceeding.
|
|
166
166
|
- ON DEEP READ: If you need deep understanding of a module without modifying it, generate L2 if it doesn't exist.
|
|
167
167
|
- NEVER load all .prizm docs at once. Progressive loading saves tokens.
|
|
168
168
|
- BUDGET: Typical task should consume 3000-5000 tokens of Prizm docs total.
|
|
@@ -59,14 +59,16 @@ git diff --name-status
|
|
|
59
59
|
|
|
60
60
|
**1d.** Update affected docs (bottom-up: L2 → L1 → L0):
|
|
61
61
|
|
|
62
|
-
- **L2
|
|
62
|
+
- **L2**: If L2 exists → update KEY_FILES, INTERFACES, DATA_FLOW, DEPENDENCIES, CHANGELOG, TRAPS, DECISIONS. If L2 does NOT exist AND the module has Added or Modified source files in the current diff with meaningful logic (not trivial config) → create L2 using the L2 GENERATION TEMPLATE, then populate from source.
|
|
63
63
|
- **L1**: Update FILES count, KEY_FILES (if major files added/removed), DEPENDENCIES (if module-level deps changed). **L1 does NOT contain INTERFACES, DATA_FLOW, TRAPS, or DECISIONS** — those belong in L2 only.
|
|
64
64
|
- **L0 root.prizm**: Update MODULE_INDEX file counts only if counts changed. Update CROSS_CUTTING if cross-module concerns changed. Update only if structural change (module added/removed).
|
|
65
65
|
|
|
66
66
|
**1d-migrate.** Legacy TRAPS format migration (opportunistic):
|
|
67
67
|
While updating an affected L1/L2 doc, if you encounter TRAPS entries **without** a severity prefix (e.g., `- foo | FIX: bar` instead of `- [LOW] foo | FIX: bar`), prepend `[LOW]` as a conservative default. This clears legacy format debt incrementally — only in files already being touched, never as a bulk operation.
|
|
68
68
|
|
|
69
|
-
**1e.** If new directory qualifies as a module (per MODULE_DISCOVERY_CRITERIA in PRIZM-SPEC Section 9.1 Step 2) and matches no existing module:
|
|
69
|
+
**1e.** If new directory qualifies as a module (per MODULE_DISCOVERY_CRITERIA in PRIZM-SPEC Section 9.1 Step 2) and matches no existing module:
|
|
70
|
+
1. Create L1 doc immediately, add to MODULE_INDEX.
|
|
71
|
+
2. If the current diff includes Added or Modified source files with meaningful logic in this module → create L2 immediately using the L2 GENERATION TEMPLATE. Otherwise defer L2 to the next session that touches this module.
|
|
70
72
|
|
|
71
73
|
**1f.** Enforce size limits:
|
|
72
74
|
- L0 > 4KB → consolidate MODULE_INDEX
|
|
@@ -143,7 +145,7 @@ When writing TRAPS:
|
|
|
143
145
|
**QUALITY GATE**: Every item must answer: "If a new AI session reads only `.prizm-docs/` and this entry, does it gain actionable understanding?" If not, discard. Do not record trivially observable code patterns — the AI can read the code directly.
|
|
144
146
|
|
|
145
147
|
**2c.** Inject into the correct `.prizm-docs/` file:
|
|
146
|
-
- Module-level TRAPS/RULES/DECISIONS → the affected **L2** `.prizm` file
|
|
148
|
+
- Module-level TRAPS/RULES/DECISIONS → the affected **L2** `.prizm` file. If the target L2 does not exist, create it first using the L2 GENERATION TEMPLATE before injecting knowledge. (TRAPS/DECISIONS/RULES belong in L2, not L1.)
|
|
147
149
|
- Project-level RULES/PATTERNS → `root.prizm`
|
|
148
150
|
- Cross-module concerns spanning 2+ modules → `root.prizm` CROSS_CUTTING section
|
|
149
151
|
|
package/package.json
CHANGED
package/src/manifest.js
CHANGED
|
@@ -99,7 +99,7 @@ export function buildManifest({
|
|
|
99
99
|
* Diff two manifests and return added/removed items.
|
|
100
100
|
* @param {Object} oldManifest - previous manifest
|
|
101
101
|
* @param {Object} newManifest - new manifest to compare against
|
|
102
|
-
* @returns {Object} { skills: {added, removed}, agents: {added, removed}, rules: {added, removed} }
|
|
102
|
+
* @returns {Object} { skills: {added, removed}, agents: {added, removed}, rules: {added, removed}, pipeline: {added, removed}, extras: {added, removed} }
|
|
103
103
|
*/
|
|
104
104
|
export function diffManifest(oldManifest, newManifest) {
|
|
105
105
|
function diffArrays(oldArr, newArr) {
|
|
@@ -119,5 +119,6 @@ export function diffManifest(oldManifest, newManifest) {
|
|
|
119
119
|
Array.isArray(oldManifest?.files?.pipeline) ? oldManifest.files.pipeline : [],
|
|
120
120
|
Array.isArray(newManifest?.files?.pipeline) ? newManifest.files.pipeline : [],
|
|
121
121
|
),
|
|
122
|
+
extras: diffArrays(oldManifest?.files?.extras, newManifest?.files?.extras),
|
|
122
123
|
};
|
|
123
124
|
}
|
package/src/scaffold.js
CHANGED
|
@@ -692,7 +692,8 @@ export async function installGitignore(projectRoot, options, dryRun) {
|
|
|
692
692
|
|
|
693
693
|
if (missing.length > 0) {
|
|
694
694
|
const separator = existing.endsWith('\n') ? '' : '\n';
|
|
695
|
-
|
|
695
|
+
const header = existingLines.has('# PrizmKit') ? '' : '# PrizmKit\n';
|
|
696
|
+
await fs.appendFile(targetPath, separator + '\n' + header + missing.join('\n') + '\n');
|
|
696
697
|
console.log(chalk.green(` ✓ .gitignore (added ${missing.length} entries)`));
|
|
697
698
|
} else {
|
|
698
699
|
console.log(chalk.green(' ✓ .gitignore (up-to-date)'));
|
|
@@ -894,15 +895,15 @@ export async function scaffold(config) {
|
|
|
894
895
|
}
|
|
895
896
|
}
|
|
896
897
|
|
|
897
|
-
//
|
|
898
|
+
// 12. Git pre-commit hook
|
|
898
899
|
console.log(chalk.blue(' Git Hook:'));
|
|
899
900
|
await installGitHook(projectRoot, dryRun);
|
|
900
901
|
|
|
901
|
-
//
|
|
902
|
+
// 13. PrizmKit scripts (always installed)
|
|
902
903
|
console.log(chalk.blue(' PrizmKit 脚本:'));
|
|
903
904
|
await installPrizmkitScripts(projectRoot, dryRun);
|
|
904
905
|
|
|
905
|
-
//
|
|
906
|
+
// 14. Write installation manifest
|
|
906
907
|
if (!dryRun) {
|
|
907
908
|
const agentsDir = getAgentsDir();
|
|
908
909
|
const agentFileNames = (await fs.readdir(agentsDir)).filter(f => f.endsWith('.md'));
|
package/src/upgrade.js
CHANGED
|
@@ -272,7 +272,7 @@ export async function runUpgrade(directory, options = {}) {
|
|
|
272
272
|
newManifest.installedAt = oldManifest.installedAt;
|
|
273
273
|
}
|
|
274
274
|
|
|
275
|
-
const diff = oldManifest ? diffManifest(oldManifest, newManifest) : { skills: { added: [], removed: [] }, agents: { added: [], removed: [] }, rules: { added: [], removed: [] }, pipeline: { added: [], removed: [] } };
|
|
275
|
+
const diff = oldManifest ? diffManifest(oldManifest, newManifest) : { skills: { added: [], removed: [] }, agents: { added: [], removed: [] }, rules: { added: [], removed: [] }, pipeline: { added: [], removed: [] }, extras: { added: [], removed: [] } };
|
|
276
276
|
|
|
277
277
|
// 5. Display upgrade summary
|
|
278
278
|
const oldVersion = oldManifest?.version || 'unknown';
|
|
@@ -282,8 +282,8 @@ export async function runUpgrade(directory, options = {}) {
|
|
|
282
282
|
console.log(` Suite: ${suite}`);
|
|
283
283
|
console.log('');
|
|
284
284
|
|
|
285
|
-
const totalAdded = diff.skills.added.length + diff.agents.added.length + diff.rules.added.length + diff.pipeline.added.length;
|
|
286
|
-
const totalRemoved = diff.skills.removed.length + diff.agents.removed.length + diff.rules.removed.length + diff.pipeline.removed.length;
|
|
285
|
+
const totalAdded = diff.skills.added.length + diff.agents.added.length + diff.rules.added.length + diff.pipeline.added.length + diff.extras.added.length;
|
|
286
|
+
const totalRemoved = diff.skills.removed.length + diff.agents.removed.length + diff.rules.removed.length + diff.pipeline.removed.length + diff.extras.removed.length;
|
|
287
287
|
const totalUpdated = newSkillList.length + newAgentFiles.length + newRuleFiles.length;
|
|
288
288
|
|
|
289
289
|
if (diff.skills.added.length) console.log(chalk.green(` + Skills added: ${diff.skills.added.join(', ')}`));
|
|
@@ -294,6 +294,8 @@ export async function runUpgrade(directory, options = {}) {
|
|
|
294
294
|
if (diff.rules.removed.length) console.log(chalk.red(` - Rules removed: ${diff.rules.removed.join(', ')}`));
|
|
295
295
|
if (diff.pipeline.added.length) console.log(chalk.green(` + Pipeline files added: ${diff.pipeline.added.length} file(s)`));
|
|
296
296
|
if (diff.pipeline.removed.length) console.log(chalk.red(` - Pipeline files removed: ${diff.pipeline.removed.length} file(s)`));
|
|
297
|
+
if (diff.extras.added.length) console.log(chalk.green(` + Extras added: ${diff.extras.added.join(', ')}`));
|
|
298
|
+
if (diff.extras.removed.length) console.log(chalk.red(` - Extras removed: ${diff.extras.removed.join(', ')}`));
|
|
297
299
|
|
|
298
300
|
if (totalAdded === 0 && totalRemoved === 0 && oldVersion === pkg.version) {
|
|
299
301
|
console.log(chalk.gray(' No changes detected. Re-installing all files to ensure consistency.'));
|