prizmkit 1.1.120 → 1.1.121
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/prizmkit_runtime/runner_classification.py +23 -25
- package/bundled/dev-pipeline/prizmkit_runtime/runner_models.py +8 -2
- package/bundled/dev-pipeline/prizmkit_runtime/runner_prompts.py +10 -1
- package/bundled/dev-pipeline/prizmkit_runtime/runners.py +43 -29
- package/bundled/dev-pipeline/scripts/continuation.py +51 -6
- package/bundled/dev-pipeline/scripts/update-bug-status.py +57 -14
- package/bundled/dev-pipeline/scripts/update-feature-status.py +54 -5
- package/bundled/dev-pipeline/scripts/update-refactor-status.py +57 -14
- package/bundled/dev-pipeline/templates/bootstrap-tier3.md +2 -2
- package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +2 -1
- package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +2 -2
- package/bundled/dev-pipeline/templates/sections/bugfix-phase-review.md +3 -3
- package/bundled/dev-pipeline/templates/sections/phase-review-agent.md +3 -3
- package/bundled/dev-pipeline/templates/sections/phase-review-full.md +4 -4
- package/bundled/dev-pipeline/templates/sections/refactor-phase-review.md +3 -3
- package/bundled/dev-pipeline/tests/test_auto_skip.py +5 -5
- package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +10 -3
- package/bundled/dev-pipeline/tests/test_generate_bugfix_prompt.py +9 -2
- package/bundled/dev-pipeline/tests/test_generate_refactor_prompt.py +9 -1
- package/bundled/dev-pipeline/tests/test_python_runner_parity.py +222 -18
- package/bundled/dev-pipeline/tests/test_unified_cli.py +14 -10
- package/bundled/skills/_metadata.json +4 -4
- package/bundled/skills/prizmkit-code-review/SKILL.md +49 -48
- package/bundled/skills/prizmkit-code-review/references/review-report-template.md +13 -8
- package/bundled/skills/prizmkit-code-review/references/reviewer-agent-prompt.md +46 -32
- package/bundled/skills/prizmkit-code-review/references/reviewer-workspace-protocol.md +90 -0
- package/bundled/skills/prizmkit-test/SKILL.md +159 -155
- package/bundled/skills/prizmkit-test/assets/authoritative-records.schema.json +420 -0
- package/bundled/skills/prizmkit-test/assets/behavior-risk-matrix.schema.json +116 -0
- package/bundled/skills/prizmkit-test/assets/evidence-manifest.schema.json +112 -0
- package/bundled/skills/prizmkit-test/assets/evidence-package-template.json +97 -0
- package/bundled/skills/prizmkit-test/references/boundary-coverage-protocol.md +76 -192
- package/bundled/skills/prizmkit-test/references/contract-mock-protocol.md +65 -0
- package/bundled/skills/prizmkit-test/references/evidence-protocol.md +194 -0
- package/bundled/skills/prizmkit-test/references/evidence-request-protocol.md +78 -0
- package/bundled/skills/prizmkit-test/references/examples.md +65 -108
- package/bundled/skills/prizmkit-test/references/service-boundary-test-catalog.md +10 -7
- package/bundled/skills/prizmkit-test/references/test-generation-steps.md +90 -82
- package/bundled/skills/prizmkit-test/references/test-report-template.md +77 -98
- package/bundled/skills/prizmkit-test/references/trusted-evidence-execution.md +97 -0
- package/bundled/skills/prizmkit-test/scripts/build_test_evidence.py +723 -0
- package/bundled/skills/prizmkit-test/scripts/validate_test_evidence.py +1426 -0
- package/package.json +1 -1
- package/bundled/skills/prizmkit-test/scripts/validate_boundary_report.py +0 -347
|
@@ -381,6 +381,33 @@ def _set_continuation_common(status_data, args, session_id):
|
|
|
381
381
|
status_data["last_session_id"] = session_id
|
|
382
382
|
|
|
383
383
|
|
|
384
|
+
def _set_ai_error_continuation_metadata(status_data, args, session_id, reason):
|
|
385
|
+
"""Preserve durable task/session state for any retryable launched AI error."""
|
|
386
|
+
if args.active_dev_branch:
|
|
387
|
+
status_data["active_dev_branch"] = args.active_dev_branch
|
|
388
|
+
if args.base_branch:
|
|
389
|
+
status_data["base_branch"] = args.base_branch
|
|
390
|
+
status_data["continuation_pending"] = True
|
|
391
|
+
status_data["continuation_reason"] = reason
|
|
392
|
+
status_data["continuation_count"] = status_data.get("continuation_count", 0) + 1
|
|
393
|
+
status_data["previous_session_id"] = session_id
|
|
394
|
+
status_data["last_fatal_error_code"] = args.last_fatal_error_code or reason
|
|
395
|
+
if args.continuation_summary_path:
|
|
396
|
+
status_data["continuation_summary_path"] = args.continuation_summary_path
|
|
397
|
+
if args.no_progress_count is not None:
|
|
398
|
+
status_data["no_progress_count"] = max(0, args.no_progress_count)
|
|
399
|
+
fingerprint = _load_progress_fingerprint(args.progress_fingerprint)
|
|
400
|
+
if fingerprint is not None:
|
|
401
|
+
status_data["last_progress_fingerprint"] = fingerprint
|
|
402
|
+
status_data["resume_from_phase"] = None
|
|
403
|
+
if session_id:
|
|
404
|
+
sessions = status_data.get("sessions", [])
|
|
405
|
+
if session_id not in sessions:
|
|
406
|
+
sessions.append(session_id)
|
|
407
|
+
status_data["sessions"] = sessions
|
|
408
|
+
status_data["last_session_id"] = session_id
|
|
409
|
+
|
|
410
|
+
|
|
384
411
|
def set_context_overflow_continuation_metadata(status_data, args, session_id):
|
|
385
412
|
"""Record continuation metadata for a context-overflow outcome in status.json."""
|
|
386
413
|
status_data["context_overflow_count"] = status_data.get("context_overflow_count", 0) + 1
|
|
@@ -848,6 +875,18 @@ def action_update(args, feature_list_path, state_dir):
|
|
|
848
875
|
|
|
849
876
|
# Track what status we write to feature-list.json
|
|
850
877
|
new_status = current_list_status
|
|
878
|
+
if args.active_dev_branch:
|
|
879
|
+
fs["active_dev_branch"] = args.active_dev_branch
|
|
880
|
+
if args.base_branch:
|
|
881
|
+
fs["base_branch"] = args.base_branch
|
|
882
|
+
if args.last_fatal_error_code:
|
|
883
|
+
fs["last_fatal_error_code"] = args.last_fatal_error_code
|
|
884
|
+
if args.continuation_summary_path:
|
|
885
|
+
fs["continuation_summary_path"] = args.continuation_summary_path
|
|
886
|
+
fingerprint = _load_progress_fingerprint(args.progress_fingerprint)
|
|
887
|
+
if fingerprint is not None:
|
|
888
|
+
fs["last_progress_fingerprint"] = fingerprint
|
|
889
|
+
|
|
851
890
|
|
|
852
891
|
if session_status == "success":
|
|
853
892
|
fs["infra_error_count"] = 0
|
|
@@ -923,10 +962,14 @@ def action_update(args, feature_list_path, state_dir):
|
|
|
923
962
|
|
|
924
963
|
if infra_error_count >= max_infra_retries:
|
|
925
964
|
new_status = "failed"
|
|
965
|
+
fs["continuation_pending"] = False
|
|
966
|
+
fs["continuation_reason"] = session_status
|
|
967
|
+
fs["needs_attention"] = True
|
|
926
968
|
if session_id:
|
|
927
969
|
fs["last_failed_session_id"] = session_id
|
|
928
970
|
else:
|
|
929
|
-
new_status = "
|
|
971
|
+
new_status = "in_progress"
|
|
972
|
+
_set_ai_error_continuation_metadata(fs, args, session_id, session_status)
|
|
930
973
|
|
|
931
974
|
err = update_feature_in_list(feature_list_path, feature_id, new_status)
|
|
932
975
|
if err:
|
|
@@ -955,8 +998,12 @@ def action_update(args, feature_list_path, state_dir):
|
|
|
955
998
|
|
|
956
999
|
if fs["retry_count"] >= max_retries:
|
|
957
1000
|
new_status = "failed"
|
|
1001
|
+
fs["continuation_pending"] = False
|
|
1002
|
+
fs["continuation_reason"] = session_status
|
|
1003
|
+
fs["needs_attention"] = True
|
|
958
1004
|
else:
|
|
959
|
-
new_status = "
|
|
1005
|
+
new_status = "in_progress"
|
|
1006
|
+
_set_ai_error_continuation_metadata(fs, args, session_id, session_status)
|
|
960
1007
|
|
|
961
1008
|
fs["resume_from_phase"] = None
|
|
962
1009
|
if session_id:
|
|
@@ -969,7 +1016,7 @@ def action_update(args, feature_list_path, state_dir):
|
|
|
969
1016
|
error_out("Failed to update .prizmkit/plans/feature-list.json: {}".format(err))
|
|
970
1017
|
return
|
|
971
1018
|
|
|
972
|
-
if
|
|
1019
|
+
if session_id:
|
|
973
1020
|
sessions = fs.get("sessions", [])
|
|
974
1021
|
if session_id not in sessions:
|
|
975
1022
|
sessions.append(session_id)
|
|
@@ -1013,8 +1060,9 @@ def action_update(args, feature_list_path, state_dir):
|
|
|
1013
1060
|
summary["degraded_reason"] = session_status
|
|
1014
1061
|
summary["restart_policy"] = "finalization_retry"
|
|
1015
1062
|
elif session_status == "infra_error":
|
|
1016
|
-
summary["restart_policy"] = "
|
|
1063
|
+
summary["restart_policy"] = "in_process_ai_error_continuation" if new_status == "in_progress" else "needs_attention"
|
|
1017
1064
|
summary["infra_error_count"] = fs.get("infra_error_count", 0)
|
|
1065
|
+
summary.update(continuation_metadata_summary(fs))
|
|
1018
1066
|
summary["artifacts_preserved"] = True
|
|
1019
1067
|
elif session_status == "context_overflow":
|
|
1020
1068
|
summary["restart_policy"] = "context_overflow_continuation"
|
|
@@ -1025,7 +1073,8 @@ def action_update(args, feature_list_path, state_dir):
|
|
|
1025
1073
|
summary.update(continuation_metadata_summary(fs))
|
|
1026
1074
|
summary["artifacts_preserved"] = True
|
|
1027
1075
|
elif session_status != "success":
|
|
1028
|
-
summary["restart_policy"] = "
|
|
1076
|
+
summary["restart_policy"] = "in_process_ai_error_continuation" if new_status == "in_progress" else "needs_attention"
|
|
1077
|
+
summary.update(continuation_metadata_summary(fs))
|
|
1029
1078
|
summary["artifacts_preserved"] = True
|
|
1030
1079
|
|
|
1031
1080
|
print(json.dumps(summary, indent=2, ensure_ascii=False))
|
|
@@ -275,6 +275,33 @@ def _set_continuation_common(status_data, args, session_id):
|
|
|
275
275
|
status_data["last_session_id"] = session_id
|
|
276
276
|
|
|
277
277
|
|
|
278
|
+
def _set_ai_error_continuation_metadata(status_data, args, session_id, reason):
|
|
279
|
+
"""Preserve durable task/session state for any retryable launched AI error."""
|
|
280
|
+
if args.active_dev_branch:
|
|
281
|
+
status_data["active_dev_branch"] = args.active_dev_branch
|
|
282
|
+
if args.base_branch:
|
|
283
|
+
status_data["base_branch"] = args.base_branch
|
|
284
|
+
status_data["continuation_pending"] = True
|
|
285
|
+
status_data["continuation_reason"] = reason
|
|
286
|
+
status_data["continuation_count"] = status_data.get("continuation_count", 0) + 1
|
|
287
|
+
status_data["previous_session_id"] = session_id
|
|
288
|
+
status_data["last_fatal_error_code"] = args.last_fatal_error_code or reason
|
|
289
|
+
if args.continuation_summary_path:
|
|
290
|
+
status_data["continuation_summary_path"] = args.continuation_summary_path
|
|
291
|
+
if args.no_progress_count is not None:
|
|
292
|
+
status_data["no_progress_count"] = max(0, args.no_progress_count)
|
|
293
|
+
fingerprint = _load_progress_fingerprint(args.progress_fingerprint)
|
|
294
|
+
if fingerprint is not None:
|
|
295
|
+
status_data["last_progress_fingerprint"] = fingerprint
|
|
296
|
+
status_data["resume_from_phase"] = None
|
|
297
|
+
if session_id:
|
|
298
|
+
sessions = status_data.get("sessions", [])
|
|
299
|
+
if session_id not in sessions:
|
|
300
|
+
sessions.append(session_id)
|
|
301
|
+
status_data["sessions"] = sessions
|
|
302
|
+
status_data["last_session_id"] = session_id
|
|
303
|
+
|
|
304
|
+
|
|
278
305
|
def set_context_overflow_continuation_metadata(status_data, args, session_id):
|
|
279
306
|
"""Record continuation metadata for a context-overflow outcome in status.json."""
|
|
280
307
|
status_data["context_overflow_count"] = status_data.get("context_overflow_count", 0) + 1
|
|
@@ -460,6 +487,18 @@ def action_update(args, refactor_list_path, state_dir):
|
|
|
460
487
|
|
|
461
488
|
# Track what status we write to refactor-list.json
|
|
462
489
|
new_status = current_list_status
|
|
490
|
+
if args.active_dev_branch:
|
|
491
|
+
rs["active_dev_branch"] = args.active_dev_branch
|
|
492
|
+
if args.base_branch:
|
|
493
|
+
rs["base_branch"] = args.base_branch
|
|
494
|
+
if args.last_fatal_error_code:
|
|
495
|
+
rs["last_fatal_error_code"] = args.last_fatal_error_code
|
|
496
|
+
if args.continuation_summary_path:
|
|
497
|
+
rs["continuation_summary_path"] = args.continuation_summary_path
|
|
498
|
+
fingerprint = _load_progress_fingerprint(args.progress_fingerprint)
|
|
499
|
+
if fingerprint is not None:
|
|
500
|
+
rs["last_progress_fingerprint"] = fingerprint
|
|
501
|
+
|
|
463
502
|
|
|
464
503
|
if session_status == "success":
|
|
465
504
|
rs["infra_error_count"] = 0
|
|
@@ -503,10 +542,14 @@ def action_update(args, refactor_list_path, state_dir):
|
|
|
503
542
|
|
|
504
543
|
if infra_error_count >= max_infra_retries:
|
|
505
544
|
new_status = "failed"
|
|
545
|
+
rs["continuation_pending"] = False
|
|
546
|
+
rs["continuation_reason"] = session_status
|
|
547
|
+
rs["needs_attention"] = True
|
|
506
548
|
if session_id:
|
|
507
549
|
rs["last_failed_session_id"] = session_id
|
|
508
550
|
else:
|
|
509
|
-
new_status = "
|
|
551
|
+
new_status = "in_progress"
|
|
552
|
+
_set_ai_error_continuation_metadata(rs, args, session_id, session_status)
|
|
510
553
|
|
|
511
554
|
err = update_refactor_in_list(refactor_list_path, refactor_id, new_status)
|
|
512
555
|
if err:
|
|
@@ -532,27 +575,25 @@ def action_update(args, refactor_list_path, state_dir):
|
|
|
532
575
|
else:
|
|
533
576
|
rs["retry_count"] = rs.get("retry_count", 0) + 1
|
|
534
577
|
|
|
535
|
-
cleaned = cleanup_refactor_artifacts(
|
|
536
|
-
state_dir=state_dir,
|
|
537
|
-
refactor_id=refactor_id,
|
|
538
|
-
project_root=args.project_root,
|
|
539
|
-
)
|
|
540
|
-
|
|
541
578
|
if rs["retry_count"] >= max_retries:
|
|
542
579
|
new_status = "failed"
|
|
580
|
+
rs["continuation_pending"] = False
|
|
581
|
+
rs["continuation_reason"] = session_status
|
|
582
|
+
rs["needs_attention"] = True
|
|
543
583
|
else:
|
|
544
|
-
new_status = "
|
|
584
|
+
new_status = "in_progress"
|
|
585
|
+
_set_ai_error_continuation_metadata(rs, args, session_id, session_status)
|
|
545
586
|
|
|
546
587
|
rs["resume_from_phase"] = None
|
|
547
|
-
|
|
548
|
-
|
|
588
|
+
if session_id:
|
|
589
|
+
rs["last_failed_session_id"] = session_id
|
|
549
590
|
|
|
550
591
|
err = update_refactor_in_list(refactor_list_path, refactor_id, new_status)
|
|
551
592
|
if err:
|
|
552
593
|
error_out("Failed to update .prizmkit/plans/refactor-list.json: {}".format(err))
|
|
553
594
|
return
|
|
554
595
|
|
|
555
|
-
if
|
|
596
|
+
if session_id:
|
|
556
597
|
sessions = rs.get("sessions", [])
|
|
557
598
|
if session_id not in sessions:
|
|
558
599
|
sessions.append(session_id)
|
|
@@ -594,8 +635,9 @@ def action_update(args, refactor_list_path, state_dir):
|
|
|
594
635
|
summary["degraded_reason"] = session_status
|
|
595
636
|
summary["restart_policy"] = "finalization_retry"
|
|
596
637
|
elif session_status == "infra_error":
|
|
597
|
-
summary["restart_policy"] = "
|
|
638
|
+
summary["restart_policy"] = "in_process_ai_error_continuation" if new_status == "in_progress" else "needs_attention"
|
|
598
639
|
summary["infra_error_count"] = rs.get("infra_error_count", 0)
|
|
640
|
+
summary.update(continuation_metadata_summary(rs))
|
|
599
641
|
summary["artifacts_preserved"] = True
|
|
600
642
|
elif session_status == "context_overflow":
|
|
601
643
|
summary["restart_policy"] = "context_overflow_continuation"
|
|
@@ -606,8 +648,9 @@ def action_update(args, refactor_list_path, state_dir):
|
|
|
606
648
|
summary.update(continuation_metadata_summary(rs))
|
|
607
649
|
summary["artifacts_preserved"] = True
|
|
608
650
|
elif session_status != "success":
|
|
609
|
-
summary["restart_policy"] = "
|
|
610
|
-
summary
|
|
651
|
+
summary["restart_policy"] = "in_process_ai_error_continuation" if new_status == "in_progress" else "needs_attention"
|
|
652
|
+
summary.update(continuation_metadata_summary(rs))
|
|
653
|
+
summary["artifacts_preserved"] = True
|
|
611
654
|
|
|
612
655
|
print(json.dumps(summary, indent=2, ensure_ascii=False))
|
|
613
656
|
|
|
@@ -240,7 +240,7 @@ For each Verification Gate from the Task Contract, write one evidence line to Im
|
|
|
240
240
|
|
|
241
241
|
Review the completed implementation before the scoped feature test gate runs. Use `artifact_dir=.prizmkit/specs/{{FEATURE_SLUG}}/` so the code-review skill can read spec, plan, context snapshot, implementation log, and current diff artifacts. Do not require or read a prior `/prizmkit-test` report here; test generation and test-fix looping happen in the next phase.
|
|
242
242
|
|
|
243
|
-
Run `/prizmkit-code-review` with `artifact_dir=.prizmkit/specs/{{FEATURE_SLUG}}/`. The
|
|
243
|
+
Run `/prizmkit-code-review` with `artifact_dir=.prizmkit/specs/{{FEATURE_SLUG}}/`. The skill chooses a platform-supported independent Reviewer strategy and verifies that the Reviewer's snapshot is equivalent to the current workspace under its skill-owned workspace protocol. Do not prescribe Agent launch parameters from this bootstrap prompt.
|
|
244
244
|
|
|
245
245
|
The skill runs an internal review-fix loop (Reviewer Agent → filter → orchestrator fix, max 3 rounds) and writes `review-report.md` to the artifact directory.
|
|
246
246
|
|
|
@@ -253,7 +253,7 @@ If GATE:MISSING:
|
|
|
253
253
|
- Do not re-run `/prizmkit-code-review` in an unbounded report-repair loop.
|
|
254
254
|
- Perform one bounded status check; retry at most once: inspect the skill output, `review-report.md` path, and any Reviewer agent spawn messages.
|
|
255
255
|
- If the missing report is caused by Reviewer agent spawn or review skill error, retry `/prizmkit-code-review` at most once only if it appears transient.
|
|
256
|
-
- If the report is still missing after that single check/retry, write `failure-log.md` with the spawn/skill error and last observable state, then
|
|
256
|
+
- If the report is still missing after that single check/retry, write `failure-log.md` with the spawn/skill error and last observable state, then stop with a clear recovery failure. Do not synthesize a passing report through Main-Agent self-review.
|
|
257
257
|
|
|
258
258
|
Read `review-report.md` and check the Verdict:
|
|
259
259
|
- `PASS` → proceed to next phase
|
|
@@ -180,6 +180,7 @@ After implement completes, verify:
|
|
|
180
180
|
If `FAST_PATH=true` (≤ 2 tasks, obvious root cause), skip this phase entirely and mark checkpoint step `prizmkit-code-review` as `skipped` before continuing.
|
|
181
181
|
|
|
182
182
|
Run `/prizmkit-code-review` with `artifact_dir=.prizmkit/bugfix/{{BUG_ID}}/`:
|
|
183
|
+
- The skill chooses a platform-supported independent Reviewer strategy and verifies a workspace-equivalent snapshot under its skill-owned protocol
|
|
183
184
|
- The skill runs an internal review-fix loop (Reviewer → filter → orchestrator fix, max 3 rounds) and writes `review-report.md`
|
|
184
185
|
- `review-report.md` must contain `## Verdict`
|
|
185
186
|
|
|
@@ -191,7 +192,7 @@ After `/prizmkit-code-review` returns, verify the review report:
|
|
|
191
192
|
If GATE:MISSING:
|
|
192
193
|
- Do not re-run `/prizmkit-code-review` in an unbounded report-repair loop.
|
|
193
194
|
- Perform one bounded status check; retry `/prizmkit-code-review` at most once only if the missing report appears caused by a transient team/config/lock error.
|
|
194
|
-
- If the report is still missing after that single check/retry, write `failure-log.md` with the spawn/skill error and last observable state, then
|
|
195
|
+
- If the report is still missing after that single check/retry, write `failure-log.md` with the spawn/skill error and last observable state, then stop with a clear recovery failure. Do not replace the independent Reviewer with Main-Agent self-review.
|
|
195
196
|
|
|
196
197
|
Read `review-report.md` and check the Verdict:
|
|
197
198
|
- `PASS` → proceed
|
|
@@ -139,7 +139,7 @@ Apply the browser behavior preservation protocol where UI behavior can be affect
|
|
|
139
139
|
|
|
140
140
|
### Phase 4: Review — Code Review & Behavior Verification
|
|
141
141
|
|
|
142
|
-
Run `/prizmkit-code-review` with `artifact_dir=.prizmkit/refactor/{{REFACTOR_ID}}/` directly from the main orchestrator.
|
|
142
|
+
Run `/prizmkit-code-review` with `artifact_dir=.prizmkit/refactor/{{REFACTOR_ID}}/` directly from the main orchestrator. The skill loads its skill-owned `references/reviewer-agent-prompt.md` and `references/reviewer-workspace-protocol.md`, chooses a platform-supported independent Reviewer strategy, and verifies a workspace-equivalent snapshot.
|
|
143
143
|
|
|
144
144
|
Review requirements:
|
|
145
145
|
- verify refactor quality against spec.md and plan.md;
|
|
@@ -147,7 +147,7 @@ Review requirements:
|
|
|
147
147
|
- run or confirm relevant tests;
|
|
148
148
|
- write `.prizmkit/refactor/{{REFACTOR_ID}}/review-report.md` with `## Verdict`.
|
|
149
149
|
|
|
150
|
-
If the report is missing after one bounded status check, write `failure-log.md` and
|
|
150
|
+
If the report is missing after one bounded status check, write `failure-log.md` and stop with a clear recovery failure. Do not replace the independent Reviewer with Main-Agent self-review.
|
|
151
151
|
|
|
152
152
|
**Checkpoint update**: set step `prizmkit-code-review` to `completed` in `{{CHECKPOINT_PATH}}`.
|
|
153
153
|
|
|
@@ -12,9 +12,9 @@ If `FAST_PATH=true`, skip this phase intentionally:
|
|
|
12
12
|
|
|
13
13
|
Then continue to the next checkpoint step.
|
|
14
14
|
|
|
15
|
-
Otherwise, run `/prizmkit-code-review` with `artifact_dir=.prizmkit/bugfix/{{BUG_ID}}/`. The
|
|
15
|
+
Otherwise, run `/prizmkit-code-review` with `artifact_dir=.prizmkit/bugfix/{{BUG_ID}}/`. The skill loads its skill-owned Reviewer prompt and workspace protocol, chooses a platform-supported subagent strategy, and verifies that the Reviewer's snapshot is equivalent to the current workspace before review.
|
|
16
16
|
|
|
17
|
-
The skill runs its internal Reviewer Agent → filter → orchestrator fix loop and writes `review-report.md`. Do not
|
|
17
|
+
The skill runs its internal Reviewer Agent → filter → orchestrator fix loop and writes `review-report.md`. Do not prescribe Agent launch parameters from this pipeline template; the review skill owns strategy selection and workspace-equivalence verification.
|
|
18
18
|
|
|
19
19
|
**Gate Check — Review Report**:
|
|
20
20
|
|
|
@@ -24,6 +24,6 @@ The skill runs its internal Reviewer Agent → filter → orchestrator fix loop
|
|
|
24
24
|
|
|
25
25
|
- `PASS` → proceed.
|
|
26
26
|
- `NEEDS_FIXES` → the skill exhausted its internal rounds; log remaining findings and proceed only when they do not block acceptance criteria.
|
|
27
|
-
- Missing report → one bounded retry
|
|
27
|
+
- Missing report → one bounded retry, then write `failure-log.md` and stop if the independent review protocol remains blocked; do not replace it with Main-Agent self-review.
|
|
28
28
|
|
|
29
29
|
**Checkpoint update**: Set step `prizmkit-code-review` to `completed` when review is complete, or `skipped` for FAST_PATH.
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Review the completed implementation before the scoped feature test gate runs. Use `artifact_dir=.prizmkit/specs/{{FEATURE_SLUG}}/` so the code-review skill can read spec, plan, context snapshot, implementation log, and current diff artifacts. Do not require or read a prior `/prizmkit-test` report here; test generation and test-fix looping happen in the next phase.
|
|
4
4
|
|
|
5
|
-
Run `/prizmkit-code-review` with `artifact_dir=.prizmkit/specs/{{FEATURE_SLUG}}/`. The
|
|
5
|
+
Run `/prizmkit-code-review` with `artifact_dir=.prizmkit/specs/{{FEATURE_SLUG}}/`. The skill loads its skill-owned Reviewer prompt and workspace protocol, chooses a platform-supported subagent strategy, and verifies that the Reviewer's snapshot is equivalent to the current workspace before review.
|
|
6
6
|
|
|
7
|
-
The skill runs an internal review-fix loop (Reviewer Agent → filter → orchestrator fix, max 3 rounds) and writes `review-report.md` to the artifact directory. Do not
|
|
7
|
+
The skill runs an internal review-fix loop (Reviewer Agent → filter → orchestrator fix, max 3 rounds) and writes `review-report.md` to the artifact directory. Do not prescribe Agent launch parameters from this pipeline template; the review skill owns strategy selection and workspace-equivalence verification.
|
|
8
8
|
|
|
9
9
|
**Gate Check — Review Report**:
|
|
10
10
|
After `/prizmkit-code-review` returns, verify the review report:
|
|
@@ -15,7 +15,7 @@ If GATE:MISSING:
|
|
|
15
15
|
- Do not re-run `/prizmkit-code-review` in an unbounded report-repair loop.
|
|
16
16
|
- Perform one bounded status check; retry at most once: inspect the skill output, `review-report.md` path, and any Reviewer agent spawn messages.
|
|
17
17
|
- If the missing report is caused by team/config/lock errors from the Reviewer agent spawn or review skill error, retry `/prizmkit-code-review` at most once only if it appears transient.
|
|
18
|
-
- If the report is still missing after that single check/retry, write `failure-log.md` with the spawn/skill error and last observable state, then
|
|
18
|
+
- If the report is still missing after that single check/retry, write `failure-log.md` with the spawn/skill error and last observable state, then stop with a clear recovery failure. Do not synthesize a passing report through Main-Agent self-review.
|
|
19
19
|
|
|
20
20
|
Read `review-report.md` and check the Verdict:
|
|
21
21
|
- `PASS` → proceed to next phase
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
Review the completed implementation before the scoped feature test gate runs. Use `artifact_dir=.prizmkit/specs/{{FEATURE_SLUG}}/` so the code-review skill can read spec, plan, context snapshot, implementation log, and current diff artifacts. Do not require or read a prior `/prizmkit-test` report here; test generation and test-fix looping happen in the next phase.
|
|
4
4
|
|
|
5
|
-
Run `/prizmkit-code-review` with `artifact_dir=.prizmkit/specs/{{FEATURE_SLUG}}/`. The
|
|
5
|
+
Run `/prizmkit-code-review` with `artifact_dir=.prizmkit/specs/{{FEATURE_SLUG}}/`. The skill loads its skill-owned Reviewer prompt and workspace protocol, chooses a platform-supported subagent strategy, and verifies that the Reviewer's snapshot is equivalent to the current workspace before review.
|
|
6
6
|
|
|
7
|
-
If the
|
|
7
|
+
If the independent Reviewer cannot start or verify the snapshot because of a transient platform error, retry at most once. If the second attempt fails, do not keep spawning variants or enter report-polling loops; write `failure-log.md` with the observable error and let the skill report the unresolved verification blocker. Do not replace the independent Reviewer with Main-Agent self-review.
|
|
8
8
|
|
|
9
|
-
The skill runs an internal review-fix loop (Reviewer Agent → filter → orchestrator fix, max 3 rounds) and writes `review-report.md` to the artifact directory. Do not
|
|
9
|
+
The skill runs an internal review-fix loop (Reviewer Agent → filter → orchestrator fix, max 3 rounds) and writes `review-report.md` to the artifact directory. Do not prescribe Agent launch parameters from this pipeline template; the review skill owns strategy selection and workspace-equivalence verification.
|
|
10
10
|
|
|
11
11
|
**Gate Check — Review Report**:
|
|
12
12
|
After `/prizmkit-code-review` returns, verify the review report:
|
|
@@ -17,7 +17,7 @@ If GATE:MISSING:
|
|
|
17
17
|
- Do not re-run `/prizmkit-code-review` in an unbounded report-repair loop.
|
|
18
18
|
- Perform one bounded status check; retry at most once: inspect the skill output, `review-report.md` path, and any Reviewer agent spawn messages.
|
|
19
19
|
- If the missing report is caused by team/config/lock errors from the Reviewer agent spawn or review skill error, retry `/prizmkit-code-review` at most once only if it appears transient.
|
|
20
|
-
- If the report is still missing after that single check/retry, write `failure-log.md` with the spawn/skill error and last observable state, then
|
|
20
|
+
- If the report is still missing after that single check/retry, write `failure-log.md` with the spawn/skill error and last observable state, then stop with a clear recovery failure. Do not synthesize a passing report through Main-Agent self-review.
|
|
21
21
|
|
|
22
22
|
Read `review-report.md` and check the Verdict:
|
|
23
23
|
- `PASS` → proceed to next phase
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
### Phase 3: Review — Code Review & Behavior Verification
|
|
2
2
|
|
|
3
|
-
Run `/prizmkit-code-review` directly with `artifact_dir=.prizmkit/refactor/{{REFACTOR_ID}}/`. The
|
|
3
|
+
Run `/prizmkit-code-review` directly with `artifact_dir=.prizmkit/refactor/{{REFACTOR_ID}}/`. The skill loads its skill-owned `references/reviewer-agent-prompt.md` and `references/reviewer-workspace-protocol.md`, chooses a platform-supported subagent strategy, and verifies that the Reviewer's snapshot is equivalent to the current workspace before review.
|
|
4
4
|
|
|
5
|
-
Do not spawn a top-level Reviewer subagent. The code-review skill owns its internal Reviewer Agent → filter → orchestrator fix loop. Do not
|
|
5
|
+
Do not spawn a top-level Reviewer subagent. The code-review skill owns its internal Reviewer Agent → filter → orchestrator fix loop. Do not prescribe Agent launch parameters from this pipeline template; the review skill owns strategy selection and workspace-equivalence verification.
|
|
6
6
|
|
|
7
7
|
**Gate Check — Review Report**:
|
|
8
8
|
|
|
@@ -12,7 +12,7 @@ Do not spawn a top-level Reviewer subagent. The code-review skill owns its inter
|
|
|
12
12
|
|
|
13
13
|
- `PASS` → proceed.
|
|
14
14
|
- `NEEDS_FIXES` → the skill exhausted its internal rounds; log remaining findings and proceed only when they do not block behavior preservation.
|
|
15
|
-
- Missing report → one bounded retry
|
|
15
|
+
- Missing report → one bounded retry, then write `failure-log.md` and stop if the independent review protocol remains blocked; do not replace it with Main-Agent self-review.
|
|
16
16
|
|
|
17
17
|
Verify the review explicitly checks behavior preservation, public API compatibility, imports, tests, and rollback assumptions.
|
|
18
18
|
|
|
@@ -1195,7 +1195,7 @@ def _run_update(fl_path, state_dir, feature_id, session_status, session_id="sess
|
|
|
1195
1195
|
|
|
1196
1196
|
|
|
1197
1197
|
class TestInfraErrorUpdate:
|
|
1198
|
-
def
|
|
1198
|
+
def test_infra_error_below_budget_keeps_in_progress_without_consuming_retry(self, tmp_path):
|
|
1199
1199
|
features = [_make_feature("F-001", "Root", status="in_progress")]
|
|
1200
1200
|
fl_path = _write_fl(tmp_path, features)
|
|
1201
1201
|
state_dir = _init_state(tmp_path, ["F-001"])
|
|
@@ -1214,12 +1214,12 @@ class TestInfraErrorUpdate:
|
|
|
1214
1214
|
max_infra_retries=3,
|
|
1215
1215
|
)
|
|
1216
1216
|
|
|
1217
|
-
assert result["new_status"] == "
|
|
1217
|
+
assert result["new_status"] == "in_progress"
|
|
1218
1218
|
assert result["retry_count"] == 2
|
|
1219
1219
|
assert result["infra_error_count"] == 1
|
|
1220
1220
|
assert result["max_infra_retries"] == 3
|
|
1221
|
-
assert result["restart_policy"] == "
|
|
1222
|
-
assert _read_statuses(fl_path)["F-001"] == "
|
|
1221
|
+
assert result["restart_policy"] == "in_process_ai_error_continuation"
|
|
1222
|
+
assert _read_statuses(fl_path)["F-001"] == "in_progress"
|
|
1223
1223
|
|
|
1224
1224
|
fs = load_feature_status(state_dir, "F-001")
|
|
1225
1225
|
assert fs["retry_count"] == 2
|
|
@@ -1250,7 +1250,7 @@ class TestInfraErrorUpdate:
|
|
|
1250
1250
|
assert result["new_status"] == "failed"
|
|
1251
1251
|
assert result["retry_count"] == 1
|
|
1252
1252
|
assert result["infra_error_count"] == 3
|
|
1253
|
-
assert result["restart_policy"] == "
|
|
1253
|
+
assert result["restart_policy"] == "needs_attention"
|
|
1254
1254
|
assert _read_statuses(fl_path)["F-001"] == "failed"
|
|
1255
1255
|
|
|
1256
1256
|
fs = load_feature_status(state_dir, "F-001")
|
|
@@ -921,7 +921,14 @@ class TestContinuationHandoff:
|
|
|
921
921
|
args = Namespace(
|
|
922
922
|
output=str(tmp_path / ".prizmkit/state/features/F-123/sessions/F-123-new/bootstrap-prompt.md"),
|
|
923
923
|
state_dir=str(tmp_path / ".prizmkit/state/features"),
|
|
924
|
-
continuation_mode="
|
|
924
|
+
continuation_mode="ai_error",
|
|
925
|
+
failure_classification="ai_runtime_or_provider_error",
|
|
926
|
+
code_retry_count="1",
|
|
927
|
+
infra_error_count="2",
|
|
928
|
+
max_code_retries="3",
|
|
929
|
+
max_infra_retries="3",
|
|
930
|
+
no_progress_count="0",
|
|
931
|
+
progress_fingerprint=json.dumps({"git_diff_fingerprint": "diff", "head_commit": "abc", "checkpoint_cursor": "S03:pending"}),
|
|
925
932
|
previous_session_id="F-123-old",
|
|
926
933
|
continuation_count="2",
|
|
927
934
|
context_overflow_count="2",
|
|
@@ -942,11 +949,11 @@ class TestContinuationHandoff:
|
|
|
942
949
|
|
|
943
950
|
assert rendered.startswith("NORMAL BOOTSTRAP")
|
|
944
951
|
assert "## Continuation Addendum" in rendered
|
|
945
|
-
assert "This is an automatic continuation after
|
|
952
|
+
assert "This is an automatic continuation after the previous launched AI session ended with `ai_runtime_or_provider_error`." in rendered
|
|
946
953
|
assert "This is a fresh headless AI CLI session for the same task." in rendered
|
|
947
954
|
assert "Continue on the current branch/worktree." in rendered
|
|
948
955
|
assert "Do not reset, clean, switch branches, or discard work." in rendered
|
|
949
|
-
assert "
|
|
956
|
+
assert "Inspect `git status` and `git diff` before editing." in rendered
|
|
950
957
|
assert "Treat completed/skipped checkpoint steps as already done." in rendered
|
|
951
958
|
assert "Do not read the previous full `session.log` unless explicitly necessary." in rendered
|
|
952
959
|
assert "prefer synthesized artifacts and summaries over logs" in rendered
|
|
@@ -265,7 +265,14 @@ class TestBugfixContinuationHandoff:
|
|
|
265
265
|
args = Namespace(
|
|
266
266
|
output=str(tmp_path / ".prizmkit/state/bugfix/B-007/sessions/B-007-new/bootstrap-prompt.md"),
|
|
267
267
|
state_dir=str(tmp_path / ".prizmkit/state/bugfix"),
|
|
268
|
-
continuation_mode="
|
|
268
|
+
continuation_mode="ai_error",
|
|
269
|
+
failure_classification="ai_runtime_or_provider_error",
|
|
270
|
+
code_retry_count="1",
|
|
271
|
+
infra_error_count="2",
|
|
272
|
+
max_code_retries="3",
|
|
273
|
+
max_infra_retries="3",
|
|
274
|
+
no_progress_count="0",
|
|
275
|
+
progress_fingerprint=json.dumps({"git_diff_fingerprint": "diff", "head_commit": "abc", "checkpoint_cursor": "S03:pending"}),
|
|
269
276
|
previous_session_id="B-007-old",
|
|
270
277
|
continuation_count="1",
|
|
271
278
|
context_overflow_count="1",
|
|
@@ -279,7 +286,7 @@ class TestBugfixContinuationHandoff:
|
|
|
279
286
|
)
|
|
280
287
|
|
|
281
288
|
assert prompt.startswith("BUGFIX PROMPT")
|
|
282
|
-
assert "This is an automatic continuation after
|
|
289
|
+
assert "This is an automatic continuation after the previous launched AI session ended with `ai_runtime_or_provider_error`." in prompt
|
|
283
290
|
assert "Do not attempt `/compact` as the recovery mechanism." not in prompt
|
|
284
291
|
assert ("Log " + "monitor") not in prompt
|
|
285
292
|
assert ("log-" + "monitor") not in prompt
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"""Tests for generate-refactor-prompt.py continuation behavior."""
|
|
2
2
|
|
|
3
|
+
import json
|
|
3
4
|
from argparse import Namespace
|
|
4
5
|
from pathlib import Path
|
|
5
6
|
import os
|
|
@@ -20,7 +21,14 @@ class TestRefactorContinuationHandoff:
|
|
|
20
21
|
args = Namespace(
|
|
21
22
|
output=str(tmp_path / ".prizmkit/state/refactor/R-007/sessions/R-007-new/bootstrap-prompt.md"),
|
|
22
23
|
state_dir=str(tmp_path / ".prizmkit/state/refactor"),
|
|
23
|
-
continuation_mode="
|
|
24
|
+
continuation_mode="ai_error",
|
|
25
|
+
failure_classification="ai_runtime_or_provider_error",
|
|
26
|
+
code_retry_count="1",
|
|
27
|
+
infra_error_count="2",
|
|
28
|
+
max_code_retries="3",
|
|
29
|
+
max_infra_retries="3",
|
|
30
|
+
no_progress_count="0",
|
|
31
|
+
progress_fingerprint=json.dumps({"git_diff_fingerprint": "diff", "head_commit": "abc", "checkpoint_cursor": "S03:pending"}),
|
|
24
32
|
previous_session_id="R-007-old",
|
|
25
33
|
continuation_count="1",
|
|
26
34
|
context_overflow_count="1",
|