prizmkit 1.1.140 → 1.1.142

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.
Files changed (83) hide show
  1. package/bundled/VERSION.json +3 -3
  2. package/bundled/dev-pipeline/README.md +1 -1
  3. package/bundled/dev-pipeline/prizmkit_runtime/checkpoint_state.py +165 -125
  4. package/bundled/dev-pipeline/prizmkit_runtime/runner_classification.py +13 -1
  5. package/bundled/dev-pipeline/prizmkit_runtime/runner_models.py +0 -6
  6. package/bundled/dev-pipeline/prizmkit_runtime/runners.py +5 -3
  7. package/bundled/dev-pipeline/prizmkit_runtime/test_result.py +160 -0
  8. package/bundled/dev-pipeline/scripts/check-session-status.py +11 -1
  9. package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +23 -806
  10. package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +6 -8
  11. package/bundled/dev-pipeline/scripts/generate-recovery-prompt.py +1 -1
  12. package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +6 -8
  13. package/bundled/dev-pipeline/scripts/prompt_framework.py +68 -56
  14. package/bundled/dev-pipeline/scripts/update-bug-status.py +21 -2
  15. package/bundled/dev-pipeline/scripts/update-checkpoint.py +52 -131
  16. package/bundled/dev-pipeline/scripts/update-feature-status.py +21 -2
  17. package/bundled/dev-pipeline/scripts/update-refactor-status.py +21 -2
  18. package/bundled/dev-pipeline/templates/bootstrap-prompt.md +3 -3
  19. package/bundled/dev-pipeline/templates/bootstrap-tier3.md +8 -19
  20. package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +6 -6
  21. package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +5 -5
  22. package/bundled/dev-pipeline/templates/sections/bugfix-phase-commit-report.md +1 -1
  23. package/bundled/dev-pipeline/templates/sections/bugfix-phase-diagnose-plan.md +1 -1
  24. package/bundled/dev-pipeline/templates/sections/bugfix-phase-manual-verification.md +1 -1
  25. package/bundled/dev-pipeline/templates/sections/bugfix-phase-review.md +1 -1
  26. package/bundled/dev-pipeline/templates/sections/bugfix-phase-test.md +13 -10
  27. package/bundled/dev-pipeline/templates/sections/bugfix-reminders.md +1 -1
  28. package/bundled/dev-pipeline/templates/sections/checkpoint-system.md +18 -9
  29. package/bundled/dev-pipeline/templates/sections/headless-commit-authorization.md +1 -1
  30. package/bundled/dev-pipeline/templates/sections/phase-commit-full.md +1 -1
  31. package/bundled/dev-pipeline/templates/sections/phase-commit.md +1 -1
  32. package/bundled/dev-pipeline/templates/sections/phase-context-snapshot-agent-suffix.md +2 -2
  33. package/bundled/dev-pipeline/templates/sections/phase-context-snapshot-base.md +1 -1
  34. package/bundled/dev-pipeline/templates/sections/phase-context-snapshot-lite-suffix.md +1 -1
  35. package/bundled/dev-pipeline/templates/sections/phase-implement-lite.md +1 -1
  36. package/bundled/dev-pipeline/templates/sections/phase-prizmkit-test.md +14 -26
  37. package/bundled/dev-pipeline/templates/sections/phase-review-full.md +2 -2
  38. package/bundled/dev-pipeline/templates/sections/phase-specify-plan-full.md +3 -3
  39. package/bundled/dev-pipeline/templates/sections/refactor-phase-review.md +1 -1
  40. package/bundled/dev-pipeline/templates/sections/refactor-phase-test.md +13 -10
  41. package/bundled/dev-pipeline/templates/sections/refactor-reminders.md +1 -1
  42. package/bundled/dev-pipeline/templates/session-status-schema.json +1 -1
  43. package/bundled/dev-pipeline/tests/test_checkpoint_state.py +494 -413
  44. package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +144 -684
  45. package/bundled/dev-pipeline/tests/test_generate_bugfix_prompt.py +20 -41
  46. package/bundled/dev-pipeline/tests/test_generate_refactor_prompt.py +24 -24
  47. package/bundled/dev-pipeline/tests/test_python_runner_parity.py +176 -36
  48. package/bundled/skills/_metadata.json +6 -6
  49. package/bundled/skills/prizmkit/SKILL.md +13 -18
  50. package/bundled/skills/prizmkit/references/workflow-state-protocol.md +73 -80
  51. package/bundled/skills/prizmkit-code-review/SKILL.md +7 -7
  52. package/bundled/skills/prizmkit-code-review/references/workflow-state-protocol.md +73 -80
  53. package/bundled/skills/prizmkit-committer/SKILL.md +8 -7
  54. package/bundled/skills/prizmkit-committer/references/workflow-state-protocol.md +73 -80
  55. package/bundled/skills/prizmkit-implement/SKILL.md +3 -2
  56. package/bundled/skills/prizmkit-implement/references/workflow-state-protocol.md +73 -80
  57. package/bundled/skills/prizmkit-plan/SKILL.md +2 -1
  58. package/bundled/skills/prizmkit-plan/references/workflow-state-protocol.md +73 -80
  59. package/bundled/skills/prizmkit-retrospective/SKILL.md +8 -6
  60. package/bundled/skills/prizmkit-retrospective/references/workflow-state-protocol.md +73 -80
  61. package/bundled/skills/prizmkit-test/SKILL.md +217 -189
  62. package/bundled/skills/prizmkit-test/references/external-contract-mock-guidance.md +119 -0
  63. package/bundled/skills/prizmkit-test/references/independent-test-review.md +269 -0
  64. package/bundled/skills/prizmkit-test/references/test-coverage-model.md +193 -0
  65. package/bundled/skills/prizmkit-test/references/test-report-template.md +164 -79
  66. package/bundled/skills/prizmkit-workflow/SKILL.md +28 -36
  67. package/bundled/skills/prizmkit-workflow/references/workflow-state-protocol.md +73 -80
  68. package/package.json +1 -1
  69. package/bundled/skills/prizmkit-test/assets/authoritative-records.schema.json +0 -477
  70. package/bundled/skills/prizmkit-test/assets/behavior-risk-matrix.schema.json +0 -116
  71. package/bundled/skills/prizmkit-test/assets/evidence-manifest.schema.json +0 -111
  72. package/bundled/skills/prizmkit-test/assets/evidence-package-template.json +0 -66
  73. package/bundled/skills/prizmkit-test/references/boundary-coverage-protocol.md +0 -104
  74. package/bundled/skills/prizmkit-test/references/contract-mock-protocol.md +0 -65
  75. package/bundled/skills/prizmkit-test/references/evidence-protocol.md +0 -208
  76. package/bundled/skills/prizmkit-test/references/evidence-request-protocol.md +0 -80
  77. package/bundled/skills/prizmkit-test/references/examples.md +0 -100
  78. package/bundled/skills/prizmkit-test/references/service-boundary-test-catalog.md +0 -228
  79. package/bundled/skills/prizmkit-test/references/test-generation-steps.md +0 -118
  80. package/bundled/skills/prizmkit-test/references/trusted-evidence-execution.md +0 -107
  81. package/bundled/skills/prizmkit-test/references/workflow-state-protocol.md +0 -181
  82. package/bundled/skills/prizmkit-test/scripts/build_test_evidence.py +0 -1930
  83. package/bundled/skills/prizmkit-test/scripts/validate_test_evidence.py +0 -1847
@@ -472,7 +472,7 @@ class TestBugfixCheckpointGeneration:
472
472
  existing["bugfix_state"] = bugfix_checkpoint_metadata(
473
473
  ".prizmkit/bugfix/B-001",
474
474
  stage="test",
475
- status="TEST_BLOCKED",
475
+ status="failed",
476
476
  stage_result="TEST_BLOCKED",
477
477
  repair_round=2,
478
478
  next_stage="prizmkit-test",
@@ -481,6 +481,7 @@ class TestBugfixCheckpointGeneration:
481
481
 
482
482
  merged = merge_bugfix_checkpoint_state(existing, fresh, str(tmp_path))
483
483
 
484
+ assert merged["bugfix_state"]["status"] == "failed"
484
485
  assert merged["bugfix_state"]["stage_result"] == "TEST_BLOCKED"
485
486
  assert merged["bugfix_state"]["resume_from"] == "prizmkit-test"
486
487
 
@@ -500,66 +501,44 @@ class TestBugfixCheckpointGeneration:
500
501
  test_step = checkpoint["steps"][4]
501
502
  assert test_step["depends_on"] == "S04"
502
503
  assert test_step["required_artifacts"] == [
503
- ".prizmkit/test/evidence/*/manifest.json",
504
- ".prizmkit/test/evidence/*/verdict.json",
505
- ".prizmkit/test/evidence/*/validation.json",
504
+ ".prizmkit/bugfix/B-001/test-report.md",
505
+ ".prizmkit/bugfix/B-001/test-result.json",
506
506
  ]
507
507
  assert checkpoint["steps"][5]["depends_on"] == "S05"
508
508
 
509
- def test_bugfix_repair_routing_preserves_review_and_test_boundaries(self):
509
+ def test_bugfix_result_routing_stops_test_non_pass(self):
510
510
  review = route_bugfix_repair("REVIEW_NEEDS_FIXES", repair_round=0)
511
- test_infra = route_bugfix_repair(
512
- "TEST_FAIL", "test-infrastructure", repair_round=1,
513
- )
514
- production = route_bugfix_repair("TEST_FAIL", "public-interface", repair_round=2)
511
+ needs_fixes = route_bugfix_repair("TEST_NEEDS_FIXES", repair_round=1)
512
+ blocked = route_bugfix_repair("TEST_BLOCKED", repair_round=1)
515
513
 
516
514
  assert review["route"] == [
517
515
  "prizmkit-implement", "prizmkit-code-review", "prizmkit-test",
518
516
  ]
519
- assert test_infra["route"] == ["prizmkit-implement", "prizmkit-test"]
520
- assert production["route"] == [
521
- "prizmkit-implement", "prizmkit-code-review", "prizmkit-test",
522
- ]
523
- assert production["repair_round"] == 3
524
-
525
- def test_bugfix_repair_routing_blocks_unsafe_blocked_and_exhausted_results(self):
526
- unknown = route_bugfix_repair("TEST_FAIL", "unknown", repair_round=1)
527
- blocked = route_bugfix_repair("TEST_BLOCKED", "production", repair_round=1)
528
- exhausted = route_bugfix_repair("TEST_FAIL", "production", repair_round=3)
529
-
530
- assert unknown["blocked"] is True
531
- assert unknown["route"] == []
517
+ assert review["repair_round"] == 1
518
+ assert needs_fixes["blocked"] is True
519
+ assert needs_fixes["route"] == []
520
+ assert needs_fixes["blocked_reason"] == "test_needs_fixes"
532
521
  assert blocked["blocked"] is True
533
522
  assert blocked["resumable"] is False
534
523
  assert blocked["next_stage"] is None
535
524
  assert blocked["terminal_status"] == "WORKFLOW_BLOCKED"
536
525
  assert blocked["blocked_reason"] == "test_blocked"
537
- assert blocked["route"] == []
538
- assert "cannot safely edit production" in blocked["reason"]
539
- assert exhausted["blocked"] is True
540
- assert exhausted["repair_round"] == 3
541
526
 
542
- def test_bugfix_checkpoint_metadata_preserves_artifact_and_evidence_handoff(self):
527
+ def test_bugfix_checkpoint_metadata_has_no_evidence_handoff(self):
543
528
  metadata = bugfix_checkpoint_metadata(
544
529
  ".prizmkit/bugfix/B-001",
545
- evidence={
546
- "manifest_path": ".prizmkit/test/evidence/id/manifest.json",
547
- "verdict_path": ".prizmkit/test/evidence/id/verdict.json",
548
- "validation_path": ".prizmkit/test/evidence/id/validation.json",
549
- },
550
530
  stage="test",
551
- status="TEST_FAIL",
552
- stage_result="TEST_FAIL",
553
- repair_scope="test-infrastructure",
554
- repair_round=2,
531
+ status="failed",
532
+ stage_result="TEST_NEEDS_FIXES",
533
+ repair_round=0,
534
+ next_stage=None,
535
+ resume_from=None,
555
536
  )
556
537
 
557
538
  assert metadata["artifact_dir"] == ".prizmkit/bugfix/B-001"
558
- assert metadata["authoritative_evidence_paths"]["validation"].endswith(
559
- "/validation.json"
560
- )
561
- assert metadata["repair_round"] == 2
562
- assert metadata["resume_from"] == "prizmkit-implement"
539
+ assert metadata["status"] == "failed"
540
+ assert metadata["stage_result"] == "TEST_NEEDS_FIXES"
541
+ assert "authoritative_evidence_paths" not in metadata
563
542
 
564
543
  def test_manual_bugfix_uses_automatic_verification_and_keeps_commit_gate(self):
565
544
  sections = assemble_bugfix_sections(
@@ -59,12 +59,12 @@ class TestRefactorCheckpointMerge:
59
59
  existing["refactor_state"] = refactor_checkpoint_metadata(
60
60
  ".prizmkit/refactor/R-008",
61
61
  stage="test",
62
- status="TEST_FAIL",
63
- stage_result="TEST_FAIL",
62
+ status="failed",
63
+ stage_result="TEST_NEEDS_FIXES",
64
64
  repair_scope="public-interface",
65
65
  repair_round=2,
66
- next_stage="prizmkit-implement",
67
- resume_from="prizmkit-implement",
66
+ next_stage=None,
67
+ resume_from=None,
68
68
  )
69
69
  existing["steps"][0]["status"] = "skipped"
70
70
 
@@ -72,6 +72,7 @@ class TestRefactorCheckpointMerge:
72
72
 
73
73
  assert merged["steps"][0]["status"] == "skipped"
74
74
  assert merged["steps"][1]["status"] == "pending"
75
+ assert merged["refactor_state"]["status"] == "failed"
75
76
  assert merged["refactor_state"]["repair_scope"] == "public-interface"
76
77
  assert merged["refactor_state"]["repair_round"] == 2
77
78
 
@@ -215,7 +216,7 @@ def test_template_source_is_clean_for_headless_prompt_contract():
215
216
  assert "/prizmkit-test scope=this-change artifact_dir=.prizmkit/refactor/{{REFACTOR_ID}}/" in content
216
217
  assert "local_commit_authorized=true" in content
217
218
  assert "push_authorized" not in content
218
- assert "Behavior-preservation checks remain supporting evidence" in content
219
+ assert "Behavior-preservation context remains supporting input" in content
219
220
 
220
221
 
221
222
  # ---------------------------------------------------------------------------
@@ -349,44 +350,43 @@ class TestRefactorCheckpointGeneration:
349
350
  "completion-summary",
350
351
  ]
351
352
  assert checkpoint["steps"][4]["depends_on"] == "S04"
353
+ assert checkpoint["steps"][4]["required_artifacts"] == [
354
+ ".prizmkit/refactor/R-001/test-report.md",
355
+ ".prizmkit/refactor/R-001/test-result.json",
356
+ ]
352
357
  assert checkpoint["steps"][5]["depends_on"] == "S05"
353
358
 
354
- def test_refactor_repair_routing_preserves_behavior_review_and_test(self):
355
- test_infra = route_refactor_repair(
356
- "TEST_FAIL", "test-infrastructure", repair_round=1,
357
- )
358
- production = route_refactor_repair("TEST_FAIL", "public-interface", repair_round=1)
359
- blocked = route_refactor_repair("TEST_BLOCKED", "production", repair_round=1)
359
+ def test_refactor_result_routing_stops_test_non_pass(self):
360
+ review = route_refactor_repair("REVIEW_NEEDS_FIXES", repair_round=0)
361
+ needs_fixes = route_refactor_repair("TEST_NEEDS_FIXES", repair_round=1)
362
+ blocked = route_refactor_repair("TEST_BLOCKED", repair_round=1)
360
363
 
361
- assert test_infra["route"] == ["prizmkit-implement", "prizmkit-test"]
362
- assert production["route"] == [
364
+ assert review["route"] == [
363
365
  "prizmkit-implement", "prizmkit-code-review", "prizmkit-test",
364
366
  ]
365
- unknown = route_refactor_repair("TEST_FAIL", "contract", repair_round=1)
366
- exhausted = route_refactor_repair("TEST_FAIL", "production", repair_round=3)
367
- assert unknown["blocked"] is True
368
- assert unknown["route"] == []
369
- assert exhausted["blocked"] is True
370
- assert exhausted["repair_round"] == 3
367
+ assert needs_fixes["blocked"] is True
368
+ assert needs_fixes["route"] == []
369
+ assert needs_fixes["blocked_reason"] == "test_needs_fixes"
371
370
  assert blocked["blocked"] is True
372
371
  assert blocked["route"] == []
373
372
  assert blocked["next_stage"] is None
374
373
  assert blocked["terminal_status"] == "WORKFLOW_BLOCKED"
375
374
  assert blocked["blocked_reason"] == "test_blocked"
376
375
 
377
- def test_refactor_checkpoint_metadata_preserves_artifact_and_evidence_handoff(self):
376
+ def test_refactor_checkpoint_metadata_has_no_evidence_handoff(self):
378
377
  metadata = refactor_checkpoint_metadata(
379
378
  ".prizmkit/refactor/R-001",
380
- evidence={"manifest_path": "manifest.json"},
381
379
  stage="test",
382
- status="TEST_PASS",
380
+ status="completed",
383
381
  stage_result="TEST_PASS",
384
382
  next_stage="prizmkit-retrospective",
385
383
  resume_from="prizmkit-retrospective",
386
384
  )
387
385
 
388
386
  assert metadata["artifact_dir"] == ".prizmkit/refactor/R-001"
389
- assert metadata["authoritative_evidence_paths"]["manifest"] == "manifest.json"
387
+ assert metadata["status"] == "completed"
388
+ assert metadata["stage_result"] == "TEST_PASS"
389
+ assert "authoritative_evidence_paths" not in metadata
390
390
  assert metadata["next_stage"] == "prizmkit-retrospective"
391
391
  assert metadata["resume_from"] == "prizmkit-retrospective"
392
392
 
@@ -397,7 +397,7 @@ class TestRefactorCheckpointGeneration:
397
397
  "/prizmkit-test scope=this-change artifact_dir=.prizmkit/refactor/R-001/"
398
398
  ) < prompt.index("### Headless Commit Authorization")
399
399
  assert "prizmkit-workflow" not in prompt
400
- assert "Behavior-preservation checks collected during planning and implementation remain supporting evidence" in prompt
400
+ assert "Existing behavior-preservation context is input to testing" in prompt
401
401
  assert '"local_commit_authorized": true' in prompt
402
402
  assert "push_authorized" not in prompt
403
403
  assert "Remote publication is controlled by the runtime" in prompt
@@ -92,12 +92,6 @@ def _item_id_from_next_result(kind, result):
92
92
 
93
93
 
94
94
  def _write_semantic_completion_checkpoint(project_root, artifact_dir, workflow_type="feature-pipeline"):
95
- validator = (
96
- project_root / ".claude" / "command-assets" / "prizmkit-test"
97
- / "scripts" / "validate_test_evidence.py"
98
- )
99
- validator.parent.mkdir(parents=True, exist_ok=True)
100
- validator.write_text("import sys\nsys.exit(0)\n", encoding="utf-8")
101
95
  contracts = {
102
96
  "feature-pipeline": (
103
97
  "feature_state",
@@ -123,25 +117,6 @@ def _write_semantic_completion_checkpoint(project_root, artifact_dir, workflow_t
123
117
  ),
124
118
  }
125
119
  state_key, skills = contracts[workflow_type]
126
- evidence_id = "semantic-evidence"
127
- evidence_dir = project_root / ".prizmkit" / "test" / "evidence" / evidence_id
128
- evidence_dir.mkdir(parents=True, exist_ok=True)
129
- evidence = {
130
- "manifest": evidence_dir / "manifest.json",
131
- "verdict": evidence_dir / "verdict.json",
132
- "validation": evidence_dir / "validation.json",
133
- }
134
- evidence["manifest"].write_text(
135
- json.dumps({"evidence_id": evidence_id, "final_verdict": "TEST_PASS"}),
136
- encoding="utf-8",
137
- )
138
- evidence["verdict"].write_text(json.dumps({"verdict": "TEST_PASS"}), encoding="utf-8")
139
- evidence["validation"].write_text(
140
- json.dumps({"verdict": "TEST_PASS", "result": "passed"}), encoding="utf-8"
141
- )
142
- relative_evidence = {
143
- key: str(path.relative_to(project_root)) for key, path in evidence.items()
144
- }
145
120
  steps = []
146
121
  previous = None
147
122
  for index, skill in enumerate(skills, start=1):
@@ -157,10 +132,38 @@ def _write_semantic_completion_checkpoint(project_root, artifact_dir, workflow_t
157
132
  step["stage_result"] = "REVIEW_PASS"
158
133
  if skill == "prizmkit-test":
159
134
  step["stage_result"] = "TEST_PASS"
160
- step["authoritative_evidence_paths"] = relative_evidence
135
+ relative_artifact = artifact_dir.relative_to(project_root)
136
+ step["required_artifacts"] = [
137
+ str(relative_artifact / "test-report.md"),
138
+ str(relative_artifact / "test-result.json"),
139
+ ]
161
140
  steps.append(step)
162
141
  previous = step["id"]
163
142
  artifact_dir.mkdir(parents=True, exist_ok=True)
143
+ (artifact_dir / "test-report.md").write_text(
144
+ "# Test Report\n\n## Final Result\n\n- Result: TEST_PASS\n",
145
+ encoding="utf-8",
146
+ )
147
+ (artifact_dir / "test-result.json").write_text(
148
+ json.dumps({
149
+ "schema_version": 1,
150
+ "result": "TEST_PASS",
151
+ "report": "test-report.md",
152
+ "main_review_rounds": 1,
153
+ "independent_review": {
154
+ "status": "downgraded",
155
+ "responses": 0,
156
+ "downgrade_reason": "read-only continuation capability unavailable",
157
+ "final_state_rechecked": False,
158
+ },
159
+ "repair_rounds": 0,
160
+ "production_changed": False,
161
+ "review_required": False,
162
+ "review_scope": None,
163
+ "unresolved_items": [],
164
+ }),
165
+ encoding="utf-8",
166
+ )
164
167
  checkpoint = artifact_dir / "workflow-checkpoint.json"
165
168
  checkpoint.write_text(
166
169
  json.dumps({
@@ -169,7 +172,6 @@ def _write_semantic_completion_checkpoint(project_root, artifact_dir, workflow_t
169
172
  "steps": steps,
170
173
  state_key: {
171
174
  "repair_round": 0,
172
- "authoritative_evidence_paths": relative_evidence,
173
175
  "terminal_status": "WORKFLOW_COMPLETED",
174
176
  },
175
177
  }),
@@ -3424,7 +3426,150 @@ def _terminal_success_result(tmp_path):
3424
3426
  )
3425
3427
 
3426
3428
 
3427
- def test_invalid_existing_checkpoint_blocks_terminal_success_with_completion_summary(tmp_path):
3429
+ def test_session_status_parser_preserves_current_runtime_outcomes():
3430
+ import importlib.util
3431
+
3432
+ script = PIPELINE_ROOT / "scripts" / "check-session-status.py"
3433
+ spec = importlib.util.spec_from_file_location("check_session_status_contract", script)
3434
+ module = importlib.util.module_from_spec(spec)
3435
+ spec.loader.exec_module(module)
3436
+
3437
+ for status in (
3438
+ "infra_error",
3439
+ "stalled_context_continuation",
3440
+ "workflow_blocked",
3441
+ "workflow_skipped",
3442
+ ):
3443
+ assert module.determine_status({"status": status}) == status
3444
+
3445
+
3446
+ def test_terminal_success_without_semantic_completion_is_skipped(tmp_path):
3447
+ from prizmkit_runtime.runner_classification import classify_session
3448
+ from prizmkit_runtime.runner_models import PromptGenerationResult
3449
+
3450
+ base_head = _init_git_repo_for_invalid_checkpoint_test(tmp_path)
3451
+ artifact_dir = tmp_path / ".prizmkit" / "specs" / "001-incomplete"
3452
+ checkpoint = _write_semantic_completion_checkpoint(tmp_path, artifact_dir)
3453
+ payload = json.loads(checkpoint.read_text(encoding="utf-8"))
3454
+ payload["steps"][2]["required_artifacts"] = [
3455
+ ".prizmkit/specs/001-incomplete/test-report.md",
3456
+ ".prizmkit/specs/001-incomplete/missing-test-result.json",
3457
+ ]
3458
+ checkpoint.write_text(json.dumps(payload), encoding="utf-8")
3459
+ prompt = PromptGenerationResult(
3460
+ output_path=tmp_path / "prompt.md",
3461
+ checkpoint_path=checkpoint,
3462
+ artifact_path=artifact_dir,
3463
+ )
3464
+
3465
+ classification = classify_session(
3466
+ _terminal_success_result(tmp_path),
3467
+ project_root=tmp_path,
3468
+ base_head=base_head,
3469
+ prompt=prompt,
3470
+ )
3471
+
3472
+ assert classification.session_status == "workflow_skipped"
3473
+ assert classification.reason == "no_semantic_completion:incomplete_semantic_evidence"
3474
+ assert classification.fatal_error_code == ""
3475
+
3476
+
3477
+ def test_terminal_success_text_does_not_hide_provider_failure(tmp_path):
3478
+ from prizmkit_runtime.runner_classification import classify_session
3479
+ from prizmkit_runtime.runner_models import PromptGenerationResult
3480
+ from prizmkit_runtime.sessions import AISessionCommand, AISessionResult
3481
+ from prizmkit_runtime.status import ProgressSummary
3482
+
3483
+ base_head = _init_git_repo_for_invalid_checkpoint_test(tmp_path)
3484
+ artifact_dir = tmp_path / ".prizmkit" / "specs" / "001-provider-error"
3485
+ checkpoint = _write_semantic_completion_checkpoint(tmp_path, artifact_dir)
3486
+ payload = json.loads(checkpoint.read_text(encoding="utf-8"))
3487
+ payload["steps"][2]["required_artifacts"] = [
3488
+ ".prizmkit/specs/001-provider-error/test-report.md",
3489
+ ".prizmkit/specs/001-provider-error/missing-test-result.json",
3490
+ ]
3491
+ checkpoint.write_text(json.dumps(payload), encoding="utf-8")
3492
+ log = tmp_path / "provider-error.log"
3493
+ log.write_text("gateway failure after output", encoding="utf-8")
3494
+ raw = AISessionResult(
3495
+ command=AISessionCommand(("fake",), None, "claude", "stdin"),
3496
+ exit_code=0,
3497
+ timed_out=False,
3498
+ termination_reason=None,
3499
+ stale_marker=None,
3500
+ fatal_error_code="provider_error",
3501
+ progress_summary=ProgressSummary(result_subtype="success"),
3502
+ session_log=log,
3503
+ backup_log=tmp_path / "backup.log",
3504
+ log_recovery=None,
3505
+ started_epoch=0,
3506
+ ended_epoch=1,
3507
+ )
3508
+
3509
+ classification = classify_session(
3510
+ raw,
3511
+ project_root=tmp_path,
3512
+ base_head=base_head,
3513
+ prompt=PromptGenerationResult(
3514
+ output_path=tmp_path / "prompt.md",
3515
+ checkpoint_path=checkpoint,
3516
+ artifact_path=artifact_dir,
3517
+ ),
3518
+ )
3519
+
3520
+ assert classification.session_status == "infra_error"
3521
+ assert classification.reason == "ai_runtime_or_provider_error"
3522
+
3523
+
3524
+ @pytest.mark.parametrize(
3525
+ ("kind", "item_id"),
3526
+ [("feature", "F-001"), ("bugfix", "B-001"), ("refactor", "R-001")],
3527
+ )
3528
+ def test_family_status_skips_semantic_completion_failure_without_retry_spend(
3529
+ tmp_path, kind, item_id
3530
+ ):
3531
+ from prizmkit_runtime.runner_models import family_for, parse_invocation
3532
+ from prizmkit_runtime.runner_status import start_item, update_item
3533
+
3534
+ paths = _make_paths(tmp_path / kind)
3535
+ item = {
3536
+ "id": item_id,
3537
+ "title": "Skip invalid completion evidence",
3538
+ "status": "pending",
3539
+ "priority": "high",
3540
+ "dependencies": [],
3541
+ }
3542
+ if kind == "bugfix":
3543
+ item.update(severity="high", description="invalid evidence", reproduction_steps=["run"])
3544
+ elif kind == "refactor":
3545
+ item.update(description="invalid evidence", targets=["src"], goals=["preserve"])
3546
+ _write_family_plan(paths, kind, [item])
3547
+ family = family_for(kind, paths)
3548
+ invocation = parse_invocation(family, "run", ())
3549
+ invocation = invocation.__class__(**{**invocation.__dict__, "list_path": family.plan_path})
3550
+ assert start_item(family, invocation, item_id, paths.project_root).ok is True
3551
+
3552
+ result = update_item(
3553
+ family,
3554
+ invocation,
3555
+ item_id,
3556
+ "workflow_skipped",
3557
+ "session-1",
3558
+ paths.project_root,
3559
+ checkpoint_state={},
3560
+ )
3561
+ status = json.loads((family.state_dir / item_id / "status.json").read_text(encoding="utf-8"))
3562
+
3563
+ assert result.ok is True
3564
+ assert result.data["new_status"] == "skipped"
3565
+ assert result.data["restart_policy"] == "terminal_skipped"
3566
+ assert status["retry_count"] == 0
3567
+ assert status["infra_error_count"] == 0
3568
+ assert status["needs_attention"] is True
3569
+ assert status["skipped_reason"] == "workflow_completion_evidence_invalid"
3570
+
3571
+
3572
+ def test_invalid_existing_checkpoint_skips_terminal_success_with_completion_summary(tmp_path):
3428
3573
  from prizmkit_runtime.runner_classification import classify_session
3429
3574
  from prizmkit_runtime.runner_models import PromptGenerationResult
3430
3575
 
@@ -3438,11 +3583,11 @@ def test_invalid_existing_checkpoint_blocks_terminal_success_with_completion_sum
3438
3583
 
3439
3584
  classification = classify_session(_terminal_success_result(tmp_path), project_root=tmp_path, base_head=base_head, prompt=prompt)
3440
3585
 
3441
- assert classification.session_status == "crashed"
3586
+ assert classification.session_status == "workflow_skipped"
3442
3587
  assert classification.reason == "invalid_workflow_checkpoint:invalid_status"
3443
3588
 
3444
3589
 
3445
- def test_invalid_existing_checkpoint_blocks_head_change_success(tmp_path):
3590
+ def test_invalid_existing_checkpoint_blocks_runtime_failure_with_head_change(tmp_path):
3446
3591
  from prizmkit_runtime.runner_classification import classify_session
3447
3592
  from prizmkit_runtime.runner_models import PromptGenerationResult
3448
3593
  from prizmkit_runtime.sessions import AISessionCommand, AISessionResult
@@ -3479,7 +3624,7 @@ def test_invalid_existing_checkpoint_blocks_head_change_success(tmp_path):
3479
3624
  assert classification.reason == "invalid_workflow_checkpoint:malformed_step_id"
3480
3625
 
3481
3626
 
3482
- def test_invalid_existing_checkpoint_blocks_workspace_auto_commit_success(tmp_path):
3627
+ def test_invalid_existing_checkpoint_blocks_ambiguous_clean_exit(tmp_path):
3483
3628
  from prizmkit_runtime.runner_classification import classify_session
3484
3629
  from prizmkit_runtime.runner_models import PromptGenerationResult
3485
3630
  from prizmkit_runtime.sessions import AISessionCommand, AISessionResult
@@ -3877,11 +4022,6 @@ def test_family_status_persists_identical_semantic_blocked_snapshot_without_retr
3877
4022
  "stage_result": "TEST_BLOCKED",
3878
4023
  "repair_scope": "production",
3879
4024
  "repair_round": 2,
3880
- "authoritative_evidence_paths": {
3881
- "manifest": ".prizmkit/test/evidence/id/manifest.json",
3882
- "verdict": ".prizmkit/test/evidence/id/verdict.json",
3883
- "validation": ".prizmkit/test/evidence/id/validation.json",
3884
- },
3885
4025
  "blocked_reason": "test_blocked",
3886
4026
  "terminal_status": "WORKFLOW_BLOCKED",
3887
4027
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.1.140",
2
+ "version": "1.1.142",
3
3
  "skills": {
4
4
  "prizmkit": {
5
5
  "description": "Framework introduction and navigation for the formal single-requirement lifecycle, project initialization, Prizm docs, and independent deployment.",
@@ -9,7 +9,7 @@
9
9
  "hasScripts": false
10
10
  },
11
11
  "prizmkit-workflow": {
12
- "description": "Composite L1 workflow for one explicitly requested formal requirement: plan → implement → code-review → test → retrospective → committer, with stable artifact identity and deterministic repair routing.",
12
+ "description": "Composite workflow for one explicitly requested formal requirement: plan → implement → code-review → test → retrospective → committer, with stable artifact identity and deterministic repair routing.",
13
13
  "tier": "foundation",
14
14
  "category": "prizmkit-skill",
15
15
  "hasAssets": false,
@@ -44,7 +44,7 @@
44
44
  "hasScripts": true
45
45
  },
46
46
  "prizmkit-committer": {
47
- "description": "Final formal-requirement commit gate: verifies all prior stages, confirms interactive commits or performs authorized L4-headless local commits, and never pushes automatically.",
47
+ "description": "Final formal-requirement commit gate: verifies all prior stages, confirms interactive commits or performs authorized headless pipeline commits, and never pushes automatically.",
48
48
  "tier": "1",
49
49
  "category": "prizmkit-skill",
50
50
  "hasAssets": false,
@@ -72,11 +72,11 @@
72
72
  "hasScripts": false
73
73
  },
74
74
  "prizmkit-test": {
75
- "description": "Mandatory post-review auditable test evidence with TEST_PASS/TEST_FAIL/TEST_BLOCKED verdicts, repair-scope routing, current-workspace execution evidence, replay, and deterministic validation.",
75
+ "description": "AI-led project-native testing for the affected business module and Regression Ring, with bounded failure repair, mandatory Main-Agent review, optional strict independent Test Reviewer, and TEST_PASS/TEST_NEEDS_FIXES/TEST_BLOCKED results.",
76
76
  "tier": "1",
77
77
  "category": "prizmkit-skill",
78
- "hasAssets": true,
79
- "hasScripts": true
78
+ "hasAssets": false,
79
+ "hasScripts": false
80
80
  },
81
81
  "feature-workflow": {
82
82
  "description": "Thin feature scenario router. Clarifies whether the request needs direct single-requirement guidance, app planning, feature planning, or command construction from an existing feature list.",
@@ -69,12 +69,12 @@ Typos, pure formatting, small documentation edits, and other explicitly low-risk
69
69
 
70
70
  | Stage | Responsibility | Success handoff |
71
71
  |---|---|---|
72
- | `prizmkit-plan` | Clarify the requirement and create/review `spec.md` and `plan.md`. | `PLAN_READY` → `prizmkit-implement` |
73
- | `prizmkit-implement` | Execute the plan tasks and record completion. | `IMPLEMENTED` → `prizmkit-code-review` |
74
- | `prizmkit-code-review` | Main Agent reviews, repairs, verifies, and loops until convergence. | `REVIEW_PASS` → `prizmkit-test` |
75
- | `prizmkit-test` | Validate the final reviewed workspace with project-native evidence. | `TEST_PASS` → `prizmkit-retrospective` |
76
- | `prizmkit-retrospective` | Synchronize durable project documentation or record no documentation change. | `RETRO_COMPLETE` → `prizmkit-committer` |
77
- | `prizmkit-committer` | Verify gates, request commit confirmation, and create the local commit. | `COMMITTED` |
72
+ | `prizmkit-plan` | Clarify the requirement and create/review `spec.md` and `plan.md`. | `status=completed`, `stage_result=PLAN_READY` → `prizmkit-implement` |
73
+ | `prizmkit-implement` | Execute the plan tasks and record completion. | `status=completed`, `stage_result=IMPLEMENTED` → `prizmkit-code-review` |
74
+ | `prizmkit-code-review` | Main Agent reviews, repairs, verifies, and loops until convergence. | `status=completed`, `stage_result=REVIEW_PASS` → `prizmkit-test` |
75
+ | `prizmkit-test` | Validate the final reviewed workspace with project-native tests and a consistent terminal report/result pair. | `status=completed`, `stage_result=TEST_PASS` → `prizmkit-retrospective` |
76
+ | `prizmkit-retrospective` | Synchronize durable project documentation or record no documentation change. | `status=completed`, `stage_result=RETRO_COMPLETE` → `prizmkit-committer` |
77
+ | `prizmkit-committer` | Verify gates, request commit confirmation, and create the local commit. | `status=completed`, `stage_result=COMMITTED` |
78
78
 
79
79
  ### `prizmkit-workflow`
80
80
 
@@ -108,19 +108,14 @@ REVIEW_NEEDS_FIXES
108
108
  → prizmkit-implement
109
109
  → prizmkit-code-review
110
110
 
111
- TEST_FAIL affecting only tests, fixtures, or test-runner configuration
112
- prizmkit-implement
113
- prizmkit-test
114
-
115
- TEST_FAIL affecting production code, runtime configuration, schema,
116
- dependencies, or public interfaces
117
- → prizmkit-implement
118
- → prizmkit-code-review
119
- → prizmkit-test
111
+ TEST_NEEDS_FIXES
112
+ preserve test-report.md and test-result.json
113
+ stop with the known correction or delta-review requirement
114
+ → caller owns any later review/retest route
120
115
 
121
116
  TEST_BLOCKED
122
- pause without speculative code changes
123
- resume from prizmkit-test when the environment is available
117
+ preserve the blocker without speculative code changes
118
+ caller owns recovery after truth, input, safety, environment, or reliability is restored
124
119
  ```
125
120
 
126
121
  Automatic outer repair is limited to three rounds. The workflow stops with a resumable blocked result when the limit is reached or a gate cannot be safely completed.
@@ -141,7 +136,7 @@ An active requirement may use:
141
136
 
142
137
  This runtime state records the current stage, terminal status, repair scope, repair round, and resume entry. The skill set does not prescribe whether the target project commits, ignores, or shares this file.
143
138
 
144
- Read `${SKILL_DIR}/references/workflow-state-protocol.md` for the state protocol. If the state file is missing or stale, use `spec.md`, `plan.md`, review evidence, and test evidence to reconstruct the safest recoverable stage and report that reconstruction.
139
+ Read `${SKILL_DIR}/references/workflow-state-protocol.md` for the state protocol. If the state file is missing or stale, use `spec.md`, `plan.md`, the review report, `test-report.md`, and `test-result.json` to reconstruct the safest recoverable stage and report that reconstruction.
145
140
 
146
141
  ## Quick Start
147
142