prizmkit 1.1.139 → 1.1.141

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 (74) hide show
  1. package/bundled/VERSION.json +3 -3
  2. package/bundled/dev-pipeline/prizmkit_runtime/checkpoint_state.py +41 -121
  3. package/bundled/dev-pipeline/prizmkit_runtime/runner_models.py +0 -6
  4. package/bundled/dev-pipeline/prizmkit_runtime/runners.py +1 -2
  5. package/bundled/dev-pipeline/prizmkit_runtime/test_result.py +150 -0
  6. package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +21 -804
  7. package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +4 -6
  8. package/bundled/dev-pipeline/scripts/generate-recovery-prompt.py +1 -1
  9. package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +4 -6
  10. package/bundled/dev-pipeline/scripts/prompt_framework.py +56 -55
  11. package/bundled/dev-pipeline/scripts/update-bug-status.py +1 -2
  12. package/bundled/dev-pipeline/scripts/update-checkpoint.py +14 -96
  13. package/bundled/dev-pipeline/scripts/update-feature-status.py +1 -2
  14. package/bundled/dev-pipeline/scripts/update-refactor-status.py +1 -2
  15. package/bundled/dev-pipeline/templates/bootstrap-prompt.md +3 -3
  16. package/bundled/dev-pipeline/templates/bootstrap-tier3.md +7 -18
  17. package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +6 -6
  18. package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +5 -5
  19. package/bundled/dev-pipeline/templates/sections/bugfix-phase-commit-report.md +1 -1
  20. package/bundled/dev-pipeline/templates/sections/bugfix-phase-diagnose-plan.md +1 -1
  21. package/bundled/dev-pipeline/templates/sections/bugfix-phase-manual-verification.md +1 -1
  22. package/bundled/dev-pipeline/templates/sections/bugfix-phase-test.md +13 -10
  23. package/bundled/dev-pipeline/templates/sections/bugfix-reminders.md +1 -1
  24. package/bundled/dev-pipeline/templates/sections/checkpoint-system.md +14 -9
  25. package/bundled/dev-pipeline/templates/sections/headless-commit-authorization.md +1 -1
  26. package/bundled/dev-pipeline/templates/sections/phase-commit-full.md +1 -1
  27. package/bundled/dev-pipeline/templates/sections/phase-commit.md +1 -1
  28. package/bundled/dev-pipeline/templates/sections/phase-context-snapshot-agent-suffix.md +2 -2
  29. package/bundled/dev-pipeline/templates/sections/phase-context-snapshot-base.md +1 -1
  30. package/bundled/dev-pipeline/templates/sections/phase-context-snapshot-lite-suffix.md +1 -1
  31. package/bundled/dev-pipeline/templates/sections/phase-implement-lite.md +1 -1
  32. package/bundled/dev-pipeline/templates/sections/phase-prizmkit-test.md +14 -26
  33. package/bundled/dev-pipeline/templates/sections/phase-specify-plan-full.md +3 -3
  34. package/bundled/dev-pipeline/templates/sections/refactor-phase-test.md +13 -10
  35. package/bundled/dev-pipeline/templates/sections/refactor-reminders.md +1 -1
  36. package/bundled/dev-pipeline/tests/test_checkpoint_state.py +287 -384
  37. package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +119 -684
  38. package/bundled/dev-pipeline/tests/test_generate_bugfix_prompt.py +17 -40
  39. package/bundled/dev-pipeline/tests/test_generate_refactor_prompt.py +20 -23
  40. package/bundled/dev-pipeline/tests/test_python_runner_parity.py +29 -32
  41. package/bundled/skills/_metadata.json +6 -6
  42. package/bundled/skills/prizmkit/SKILL.md +8 -13
  43. package/bundled/skills/prizmkit/references/workflow-state-protocol.md +61 -80
  44. package/bundled/skills/prizmkit-code-review/SKILL.md +3 -3
  45. package/bundled/skills/prizmkit-code-review/references/workflow-state-protocol.md +61 -80
  46. package/bundled/skills/prizmkit-committer/SKILL.md +3 -3
  47. package/bundled/skills/prizmkit-committer/references/workflow-state-protocol.md +61 -80
  48. package/bundled/skills/prizmkit-implement/references/workflow-state-protocol.md +61 -80
  49. package/bundled/skills/prizmkit-plan/references/workflow-state-protocol.md +61 -80
  50. package/bundled/skills/prizmkit-retrospective/SKILL.md +2 -2
  51. package/bundled/skills/prizmkit-retrospective/references/workflow-state-protocol.md +61 -80
  52. package/bundled/skills/prizmkit-test/SKILL.md +217 -187
  53. package/bundled/skills/prizmkit-test/references/external-contract-mock-guidance.md +119 -0
  54. package/bundled/skills/prizmkit-test/references/independent-test-review.md +269 -0
  55. package/bundled/skills/prizmkit-test/references/test-coverage-model.md +193 -0
  56. package/bundled/skills/prizmkit-test/references/test-report-template.md +164 -79
  57. package/bundled/skills/prizmkit-workflow/SKILL.md +15 -23
  58. package/bundled/skills/prizmkit-workflow/references/workflow-state-protocol.md +61 -80
  59. package/package.json +1 -1
  60. package/bundled/skills/prizmkit-test/assets/authoritative-records.schema.json +0 -476
  61. package/bundled/skills/prizmkit-test/assets/behavior-risk-matrix.schema.json +0 -116
  62. package/bundled/skills/prizmkit-test/assets/evidence-manifest.schema.json +0 -111
  63. package/bundled/skills/prizmkit-test/assets/evidence-package-template.json +0 -66
  64. package/bundled/skills/prizmkit-test/references/boundary-coverage-protocol.md +0 -104
  65. package/bundled/skills/prizmkit-test/references/contract-mock-protocol.md +0 -65
  66. package/bundled/skills/prizmkit-test/references/evidence-protocol.md +0 -208
  67. package/bundled/skills/prizmkit-test/references/evidence-request-protocol.md +0 -80
  68. package/bundled/skills/prizmkit-test/references/examples.md +0 -100
  69. package/bundled/skills/prizmkit-test/references/service-boundary-test-catalog.md +0 -228
  70. package/bundled/skills/prizmkit-test/references/test-generation-steps.md +0 -118
  71. package/bundled/skills/prizmkit-test/references/trusted-evidence-execution.md +0 -110
  72. package/bundled/skills/prizmkit-test/references/workflow-state-protocol.md +0 -181
  73. package/bundled/skills/prizmkit-test/scripts/build_test_evidence.py +0 -1851
  74. package/bundled/skills/prizmkit-test/scripts/validate_test_evidence.py +0 -1793
@@ -40,15 +40,14 @@ def route_bugfix_repair(stage_result, repair_scope=None, repair_round=0):
40
40
  return route_pipeline_repair(stage_result, repair_scope, repair_round)
41
41
 
42
42
 
43
- def bugfix_checkpoint_metadata(artifact_dir, evidence=None, stage="plan",
43
+ def bugfix_checkpoint_metadata(artifact_dir, stage="plan",
44
44
  status="PLAN_READY", stage_result=None,
45
45
  repair_scope=None, repair_round=0,
46
46
  next_stage="prizmkit-implement",
47
47
  resume_from="prizmkit-implement"):
48
- """Build Bugfix L4 handoff metadata while preserving Bugfix L1 state."""
48
+ """Build Bugfix pipeline handoff metadata while preserving skill state."""
49
49
  return pipeline_checkpoint_metadata(
50
50
  artifact_dir,
51
- evidence=evidence,
52
51
  stage=stage,
53
52
  status=status,
54
53
  stage_result=stage_result,
@@ -71,9 +70,8 @@ BUGFIX_SECTION_TO_SKILL = {
71
70
  "bugfix-phase-test": checkpoint_step(
72
71
  "prizmkit-test", "Post-Review Test Gate",
73
72
  [
74
- ".prizmkit/test/evidence/*/manifest.json",
75
- ".prizmkit/test/evidence/*/verdict.json",
76
- ".prizmkit/test/evidence/*/validation.json",
73
+ ".prizmkit/bugfix/{slug}/test-report.md",
74
+ ".prizmkit/bugfix/{slug}/test-result.json",
77
75
  ],
78
76
  ),
79
77
  "phase-browser": checkpoint_step("browser-verification", "Browser Verification", []),
@@ -67,7 +67,7 @@ affected files, and root cause hypothesis.""",
67
67
  "Triage",
68
68
  """\
69
69
  Locate affected code and identify root cause:
70
- 1. Read `.prizmkit/prizm-docs/root.prizm` then relevant L1/L2 docs for affected modules
70
+ 1. Read `.prizmkit/prizm-docs/root.prizm` then the relevant module indexes and detail docs for affected modules
71
71
  2. Read files mentioned in the bug description or error/stack trace
72
72
  3. Check `.prizmkit/prizm-docs/` TRAPS for known patterns
73
73
  4. Classify: root cause (confirmed/suspected), blast radius, fix complexity
@@ -40,15 +40,14 @@ def route_refactor_repair(stage_result, repair_scope=None, repair_round=0):
40
40
  return route_pipeline_repair(stage_result, repair_scope, repair_round)
41
41
 
42
42
 
43
- def refactor_checkpoint_metadata(artifact_dir, evidence=None, stage="plan",
43
+ def refactor_checkpoint_metadata(artifact_dir, stage="plan",
44
44
  status="PLAN_READY", stage_result=None,
45
45
  repair_scope=None, repair_round=0,
46
46
  next_stage="prizmkit-implement",
47
47
  resume_from="prizmkit-implement"):
48
- """Build Refactor L4 handoff metadata while preserving Refactor L1 state."""
48
+ """Build Refactor pipeline handoff metadata while preserving skill state."""
49
49
  return pipeline_checkpoint_metadata(
50
50
  artifact_dir,
51
- evidence=evidence,
52
51
  stage=stage,
53
52
  status=status,
54
53
  stage_result=stage_result,
@@ -76,9 +75,8 @@ REFACTOR_SECTION_TO_SKILL = {
76
75
  "refactor-phase-test": checkpoint_step(
77
76
  "prizmkit-test", "Post-Review Test Gate",
78
77
  [
79
- ".prizmkit/test/evidence/*/manifest.json",
80
- ".prizmkit/test/evidence/*/verdict.json",
81
- ".prizmkit/test/evidence/*/validation.json",
78
+ ".prizmkit/refactor/{slug}/test-report.md",
79
+ ".prizmkit/refactor/{slug}/test-result.json",
82
80
  ],
83
81
  ),
84
82
  "phase-browser": checkpoint_step("browser-verification", "Browser Verification", []),
@@ -8,20 +8,20 @@ so feature, bugfix, and refactor prompts do not drift.
8
8
  import glob
9
9
  import os
10
10
  import re
11
+ import sys
12
+
13
+ _PIPELINE_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
14
+ if _PIPELINE_ROOT not in sys.path:
15
+ sys.path.insert(0, _PIPELINE_ROOT)
16
+
17
+ from prizmkit_runtime.test_result import valid_test_artifact_pair # noqa: E402
11
18
 
12
19
 
13
20
  MAX_OUTER_REPAIR_ROUNDS = 3
14
- REPAIR_SCOPES_REQUIRING_REVIEW = {
15
- "production",
16
- "runtime",
17
- "schema",
18
- "dependency",
19
- "public-interface",
20
- }
21
21
 
22
22
 
23
23
  def route_pipeline_repair(stage_result, repair_scope=None, repair_round=0):
24
- """Map review/test outcomes to bounded, safe L4 continuation routes."""
24
+ """Map review/test outcomes to bounded, safe pipeline continuation routes."""
25
25
  try:
26
26
  current_round = int(repair_round)
27
27
  except (TypeError, ValueError):
@@ -46,19 +46,28 @@ def route_pipeline_repair(stage_result, repair_scope=None, repair_round=0):
46
46
  result.update(
47
47
  next_stage="prizmkit-retrospective",
48
48
  resume_from="prizmkit-retrospective",
49
- reason="authoritative test evidence passed",
49
+ reason="project-native tests passed",
50
50
  )
51
51
  return result
52
52
  if stage_result == "TEST_BLOCKED":
53
53
  result.update(
54
54
  blocked=True,
55
55
  resumable=False,
56
- reason="bounded automatic recovery cannot safely edit production",
56
+ reason="testing could not establish a safe verdict",
57
57
  blocked_reason="test_blocked",
58
58
  terminal_status="WORKFLOW_BLOCKED",
59
59
  )
60
60
  return result
61
- if stage_result not in {"REVIEW_NEEDS_FIXES", "TEST_FAIL"}:
61
+ if stage_result == "TEST_NEEDS_FIXES":
62
+ result.update(
63
+ blocked=True,
64
+ resumable=False,
65
+ reason="prizmkit-test stopped with a known remaining correction",
66
+ blocked_reason="test_needs_fixes",
67
+ terminal_status="WORKFLOW_BLOCKED",
68
+ )
69
+ return result
70
+ if stage_result != "REVIEW_NEEDS_FIXES":
62
71
  result.update(
63
72
  blocked=True,
64
73
  reason="unknown stage result is unsafe",
@@ -76,55 +85,22 @@ def route_pipeline_repair(stage_result, repair_scope=None, repair_round=0):
76
85
  return result
77
86
 
78
87
  result["repair_round"] = current_round + 1
79
- if stage_result == "REVIEW_NEEDS_FIXES":
80
- result.update(
81
- next_stage="prizmkit-implement",
82
- resume_from="prizmkit-implement",
83
- route=["prizmkit-implement", "prizmkit-code-review", "prizmkit-test"],
84
- reason="review findings require implementation and fresh review",
85
- )
86
- return result
87
- if repair_scope == "test-infrastructure":
88
- result.update(
89
- next_stage="prizmkit-implement",
90
- resume_from="prizmkit-implement",
91
- route=["prizmkit-implement", "prizmkit-test"],
92
- reason="test infrastructure failure must not edit production speculatively",
93
- )
94
- return result
95
- if repair_scope in REPAIR_SCOPES_REQUIRING_REVIEW:
96
- result.update(
97
- next_stage="prizmkit-implement",
98
- resume_from="prizmkit-implement",
99
- route=["prizmkit-implement", "prizmkit-code-review", "prizmkit-test"],
100
- reason="production-facing failure requires review before retesting",
101
- )
102
- return result
103
88
  result.update(
104
- blocked=True,
105
- reason="unknown repair scope has no safe automatic route",
106
- blocked_reason="unsafe_repair_scope",
107
- terminal_status="WORKFLOW_BLOCKED",
89
+ next_stage="prizmkit-implement",
90
+ resume_from="prizmkit-implement",
91
+ route=["prizmkit-implement", "prizmkit-code-review", "prizmkit-test"],
92
+ reason="review findings require implementation and fresh review",
108
93
  )
109
94
  return result
110
95
 
111
96
 
112
- def pipeline_checkpoint_metadata(artifact_dir, evidence=None, stage="plan",
97
+ def pipeline_checkpoint_metadata(artifact_dir, stage="plan",
113
98
  status="PLAN_READY", stage_result=None,
114
99
  repair_scope=None, repair_round=0,
115
100
  next_stage="prizmkit-implement",
116
101
  resume_from="prizmkit-implement",
117
102
  blocked_reason=None, terminal_status=None):
118
- """Build family-neutral semantic L4 metadata without replacing L1 state."""
119
- evidence = evidence or {}
120
- if evidence:
121
- evidence_paths = {
122
- "manifest": evidence.get("manifest_path"),
123
- "verdict": evidence.get("verdict_path"),
124
- "validation": evidence.get("validation_path"),
125
- }
126
- else:
127
- evidence_paths = {"manifest": None, "verdict": None, "validation": None}
103
+ """Build family-neutral pipeline metadata without replacing skill state."""
128
104
  current_stage = None if terminal_status else stage
129
105
  semantic_next_stage = None if terminal_status else next_stage
130
106
  return {
@@ -137,7 +113,6 @@ def pipeline_checkpoint_metadata(artifact_dir, evidence=None, stage="plan",
137
113
  "stage_result": stage_result,
138
114
  "repair_scope": repair_scope,
139
115
  "repair_round": repair_round,
140
- "authoritative_evidence_paths": evidence_paths,
141
116
  "next_stage": semantic_next_stage,
142
117
  "resume_from": resume_from,
143
118
  "blocked_reason": blocked_reason,
@@ -248,6 +223,29 @@ def completed_step_artifacts_valid(project_root, artifacts):
248
223
  return all(artifact_exists(project_root, artifact) for artifact in artifacts)
249
224
 
250
225
 
226
+ def completed_test_artifacts_valid(project_root, artifacts):
227
+ """Validate a sibling test-report.md and TEST_PASS test-result.json pair."""
228
+ reports = [item for item in artifacts if item.endswith("/test-report.md")]
229
+ results = [item for item in artifacts if item.endswith("/test-result.json")]
230
+ if len(reports) != 1 or len(results) != 1:
231
+ return False
232
+ report_path = os.path.realpath(os.path.join(project_root, reports[0]))
233
+ result_path = os.path.realpath(os.path.join(project_root, results[0]))
234
+ root_path = os.path.realpath(project_root)
235
+ try:
236
+ if os.path.commonpath([root_path, report_path]) != root_path:
237
+ return False
238
+ if os.path.commonpath([root_path, result_path]) != root_path:
239
+ return False
240
+ except ValueError:
241
+ return False
242
+ return valid_test_artifact_pair(
243
+ report_path,
244
+ result_path,
245
+ required_result="TEST_PASS",
246
+ )
247
+
248
+
251
249
  def checkpoint_skip():
252
250
  """Return an explicit no-checkpoint-step contract for a prompt section."""
253
251
  return {"kind": "skip"}
@@ -360,7 +358,13 @@ def generate_checkpoint_from_sections(
360
358
 
361
359
  def merge_checkpoint_state(existing, fresh, project_root, validator=None, logger=None):
362
360
  """Merge existing checkpoint state into a freshly generated definition."""
363
- validator = validator or (lambda _skill, artifacts: completed_step_artifacts_valid(project_root, artifacts))
361
+ validator = validator or (
362
+ lambda skill, artifacts: (
363
+ completed_test_artifacts_valid(project_root, artifacts)
364
+ if skill == "prizmkit-test"
365
+ else completed_step_artifacts_valid(project_root, artifacts)
366
+ )
367
+ )
364
368
  existing_by_id = {}
365
369
  existing_by_skill = {}
366
370
  for step in existing.get("steps", []):
@@ -402,9 +406,6 @@ def merge_checkpoint_state(existing, fresh, project_root, validator=None, logger
402
406
  step["status"] = "completed"
403
407
  if stage_result:
404
408
  step["stage_result"] = stage_result
405
- evidence = previous.get("authoritative_evidence_paths")
406
- if isinstance(evidence, dict):
407
- step["authoritative_evidence_paths"] = evidence
408
409
  continue
409
410
  if logger is not None:
410
411
  logger.warning(
@@ -89,7 +89,7 @@ def parse_args():
89
89
  parser.add_argument("--continuation-summary-path", default=None, help="Optional continuation summary artifact path.")
90
90
  parser.add_argument("--no-progress-count", type=int, default=None, help="Consecutive context-overflow sessions without objective progress.")
91
91
  parser.add_argument("--progress-fingerprint", default=None, help="JSON progress fingerprint captured after the session.")
92
- parser.add_argument("--checkpoint-state", default=None, help="JSON semantic L4 checkpoint snapshot captured after the session.")
92
+ parser.add_argument("--checkpoint-state", default=None, help="JSON semantic pipeline checkpoint snapshot captured after the session.")
93
93
  return parser.parse_args()
94
94
 
95
95
 
@@ -261,7 +261,6 @@ SEMANTIC_CHECKPOINT_FIELDS = (
261
261
  "stage_result",
262
262
  "repair_scope",
263
263
  "repair_round",
264
- "authoritative_evidence_paths",
265
264
  "blocked_reason",
266
265
  "terminal_status",
267
266
  )
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env python3
2
- """Atomically update one semantic L4 workflow checkpoint."""
2
+ """Atomically update one semantic pipeline workflow checkpoint."""
3
3
 
4
4
  import argparse
5
5
  import json
@@ -120,13 +120,11 @@ def _mandatory_predecessor_verdict_error(steps, index, workflow_type):
120
120
  return None
121
121
 
122
122
  def _normalize_semantic_update(semantic_update):
123
- values = dict(semantic_update or {})
124
- evidence = values.pop("authoritative_evidence_paths", None)
125
- if evidence is not None:
126
- evidence = {key: value for key, value in evidence.items() if value}
127
- if evidence:
128
- values["authoritative_evidence_paths"] = evidence
129
- return {key: value for key, value in values.items() if value is not None}
123
+ return {
124
+ key: value
125
+ for key, value in dict(semantic_update or {}).items()
126
+ if value is not None
127
+ }
130
128
 
131
129
 
132
130
  def _validate_semantic_update(step, semantic_update):
@@ -145,24 +143,25 @@ def _validate_semantic_update(step, semantic_update):
145
143
  terminal_status = semantic_update.get("terminal_status")
146
144
  if terminal_status is not None and terminal_status not in VALID_TERMINAL_STATUSES:
147
145
  return "Invalid terminal_status '{}'".format(terminal_status)
148
- evidence = semantic_update.get("authoritative_evidence_paths")
149
- if evidence is not None and set(evidence) != {"manifest", "verdict", "validation"}:
150
- return "Authoritative test evidence requires manifest, verdict, and validation paths"
151
146
  if terminal_status == "WORKFLOW_BLOCKED" and not semantic_update.get("blocked_reason"):
152
147
  return "WORKFLOW_BLOCKED requires blocked_reason"
153
148
  return None
154
149
 
155
150
 
156
151
  def _apply_repair_policy(l4_state, stage_result, repair_scope):
157
- if stage_result not in {"REVIEW_NEEDS_FIXES", "TEST_FAIL", "TEST_BLOCKED"}:
152
+ if stage_result not in {"REVIEW_NEEDS_FIXES", "TEST_NEEDS_FIXES", "TEST_BLOCKED"}:
158
153
  return
159
154
  current_round = l4_state.get("repair_round", 0)
160
155
  if not isinstance(current_round, int) or isinstance(current_round, bool):
161
156
  current_round = MAX_OUTER_REPAIR_ROUNDS
162
- if stage_result == "TEST_BLOCKED":
157
+ if stage_result in {"TEST_NEEDS_FIXES", "TEST_BLOCKED"}:
163
158
  l4_state.update(
164
159
  terminal_status="WORKFLOW_BLOCKED",
165
- blocked_reason="test_blocked",
160
+ blocked_reason=(
161
+ "test_needs_fixes"
162
+ if stage_result == "TEST_NEEDS_FIXES"
163
+ else "test_blocked"
164
+ ),
166
165
  current_stage=None,
167
166
  next_stage=None,
168
167
  )
@@ -202,9 +201,6 @@ def _sync_cursor(data, l4_state):
202
201
  l4_state["current_stage"] = active.get("skill") if active else None
203
202
  l4_state["next_stage"] = active.get("skill") if active else None
204
203
 
205
-
206
-
207
-
208
204
  def _checkpoint_project_root(checkpoint_path):
209
205
  """Resolve the project root from a conventional .prizmkit checkpoint path."""
210
206
  path = Path(os.path.abspath(checkpoint_path))
@@ -213,42 +209,6 @@ def _checkpoint_project_root(checkpoint_path):
213
209
  return str(parent.parent)
214
210
  return str(path.parent)
215
211
 
216
- def _discover_test_evidence_paths(checkpoint_path, data):
217
- """Discover the latest finalized test package from the artifact handoff pointer."""
218
- project_root = Path(_checkpoint_project_root(checkpoint_path))
219
- candidates = []
220
- artifact_dir = data.get("artifact_dir")
221
- if isinstance(artifact_dir, str) and artifact_dir:
222
- candidates.append(project_root / artifact_dir)
223
- for state_key in ("feature_state", "bugfix_state", "refactor_state"):
224
- state = data.get(state_key)
225
- if isinstance(state, dict) and isinstance(state.get("artifact_dir"), str):
226
- candidates.append(project_root / state["artifact_dir"])
227
- item_slug = data.get("item_slug")
228
- if isinstance(item_slug, str) and item_slug:
229
- candidates.append(project_root / ".prizmkit" / "specs" / item_slug)
230
- candidates.append(project_root / ".prizmkit" / "bugfix" / item_slug)
231
- candidates.append(project_root / ".prizmkit" / "refactor" / item_slug)
232
-
233
- for artifact in candidates:
234
- pointer = artifact / "test-report-path.txt"
235
- try:
236
- report = Path(pointer.read_text(encoding="utf-8").strip()).resolve()
237
- except (OSError, ValueError):
238
- continue
239
- evidence_dir = report.parent
240
- paths = {
241
- "manifest": str(evidence_dir / "manifest.json"),
242
- "verdict": str(evidence_dir / "verdict.json"),
243
- "validation": str(evidence_dir / "validation.json"),
244
- }
245
- if all(Path(value).is_file() for value in paths.values()):
246
- return {
247
- key: str(Path(value).relative_to(project_root))
248
- for key, value in paths.items()
249
- }
250
- return None
251
-
252
212
 
253
213
  def _finalize_semantics(checkpoint_path, data, state_key):
254
214
  """Derive a deterministic terminal status after an atomic mutation."""
@@ -286,7 +246,7 @@ def update_checkpoint(
286
246
  note=None,
287
247
  semantic_update=None,
288
248
  ):
289
- """Update one step and its cohesive semantic L4 state atomically."""
249
+ """Update one step and its cohesive semantic pipeline state atomically."""
290
250
  if new_status not in VALID_STATUSES:
291
251
  return {
292
252
  "ok": False,
@@ -323,25 +283,11 @@ def update_checkpoint(
323
283
  return {"ok": False, "error": verdict_error}
324
284
 
325
285
  semantic_update = _normalize_semantic_update(semantic_update)
326
- if (
327
- semantic_update.get("stage_result") == "TEST_BLOCKED"
328
- and not semantic_update.get("authoritative_evidence_paths")
329
- ):
330
- discovered = _discover_test_evidence_paths(checkpoint_path, data)
331
- if discovered:
332
- semantic_update["authoritative_evidence_paths"] = discovered
333
286
  semantic_error = _validate_semantic_update(step, semantic_update)
334
287
  if semantic_error:
335
288
  return {"ok": False, "error": semantic_error}
336
289
 
337
290
  stage_result = semantic_update.get("stage_result")
338
- if step.get("skill") == "prizmkit-test" and stage_result in TEST_RESULTS:
339
- evidence = semantic_update.get("authoritative_evidence_paths") or step.get("authoritative_evidence_paths")
340
- if not isinstance(evidence, dict) or set(evidence) != {"manifest", "verdict", "validation"}:
341
- return {
342
- "ok": False,
343
- "error": "Every terminal test verdict requires manifest, verdict, and validation evidence paths",
344
- }
345
291
  if new_status == "completed" and step.get("skill") == "prizmkit-code-review":
346
292
  stage_result = stage_result or step.get("stage_result")
347
293
  if stage_result != "REVIEW_PASS":
@@ -350,9 +296,6 @@ def update_checkpoint(
350
296
  stage_result = stage_result or step.get("stage_result")
351
297
  if stage_result != "TEST_PASS":
352
298
  return {"ok": False, "error": "Test completion requires TEST_PASS"}
353
- evidence = semantic_update.get("authoritative_evidence_paths") or step.get("authoritative_evidence_paths")
354
- if not isinstance(evidence, dict) or set(evidence) != {"manifest", "verdict", "validation"}:
355
- return {"ok": False, "error": "Test completion requires all authoritative evidence paths"}
356
299
 
357
300
  old_status = step.get("status", "unknown")
358
301
  step["status"] = new_status
@@ -360,20 +303,6 @@ def update_checkpoint(
360
303
  step["note"] = note
361
304
  if stage_result:
362
305
  step["stage_result"] = stage_result
363
- if semantic_update.get("authoritative_evidence_paths"):
364
- step["authoritative_evidence_paths"] = semantic_update["authoritative_evidence_paths"]
365
- if new_status == "completed" and step.get("skill") == "prizmkit-test":
366
- candidate = validate_checkpoint_data(
367
- data,
368
- path=checkpoint_path,
369
- exists=True,
370
- project_root=_checkpoint_project_root(checkpoint_path),
371
- )
372
- if not candidate.valid or not candidate.semantic.evidence_valid:
373
- return {
374
- "ok": False,
375
- "error": "Test completion requires validator-attested authoritative evidence",
376
- }
377
306
 
378
307
  workflow_type = str(data.get("workflow_type") or "")
379
308
  state_key = semantic_state_key(workflow_type)
@@ -384,7 +313,6 @@ def update_checkpoint(
384
313
  "stage_result",
385
314
  "repair_scope",
386
315
  "repair_round",
387
- "authoritative_evidence_paths",
388
316
  "blocked_reason",
389
317
  "terminal_status",
390
318
  ):
@@ -394,8 +322,6 @@ def update_checkpoint(
394
322
  l4_state["orchestrator"] = "prizmkit-l4"
395
323
  if stage_result:
396
324
  l4_state["stage_result"] = stage_result
397
- if semantic_update.get("authoritative_evidence_paths"):
398
- l4_state["authoritative_evidence_paths"] = semantic_update["authoritative_evidence_paths"]
399
325
  _apply_repair_policy(l4_state, stage_result, semantic_update.get("repair_scope") or l4_state.get("repair_scope"))
400
326
  _sync_cursor(data, l4_state)
401
327
  _finalize_semantics(checkpoint_path, data, state_key)
@@ -439,9 +365,6 @@ def main():
439
365
  parser.add_argument("--stage-result", choices=sorted(REVIEW_RESULTS | TEST_RESULTS), default=None)
440
366
  parser.add_argument("--repair-scope", choices=sorted(VALID_REPAIR_SCOPES), default=None)
441
367
  parser.add_argument("--repair-round", type=int, default=None)
442
- parser.add_argument("--manifest-path", default=None)
443
- parser.add_argument("--verdict-path", default=None)
444
- parser.add_argument("--validation-path", default=None)
445
368
  parser.add_argument("--blocked-reason", default=None)
446
369
  parser.add_argument("--terminal-status", choices=sorted(VALID_TERMINAL_STATUSES), default=None)
447
370
 
@@ -450,11 +373,6 @@ def main():
450
373
  "stage_result": args.stage_result,
451
374
  "repair_scope": args.repair_scope,
452
375
  "repair_round": args.repair_round,
453
- "authoritative_evidence_paths": {
454
- "manifest": args.manifest_path,
455
- "verdict": args.verdict_path,
456
- "validation": args.validation_path,
457
- },
458
376
  "blocked_reason": args.blocked_reason,
459
377
  "terminal_status": args.terminal_status,
460
378
  }
@@ -156,7 +156,7 @@ def parse_args():
156
156
  parser.add_argument(
157
157
  "--checkpoint-state",
158
158
  default=None,
159
- help="JSON semantic L4 checkpoint snapshot captured after the session.",
159
+ help="JSON semantic pipeline checkpoint snapshot captured after the session.",
160
160
  )
161
161
  return parser.parse_args()
162
162
 
@@ -370,7 +370,6 @@ SEMANTIC_CHECKPOINT_FIELDS = (
370
370
  "stage_result",
371
371
  "repair_scope",
372
372
  "repair_round",
373
- "authoritative_evidence_paths",
374
373
  "blocked_reason",
375
374
  "terminal_status",
376
375
  )
@@ -101,7 +101,7 @@ def parse_args():
101
101
  parser.add_argument("--continuation-summary-path", default=None, help="Optional continuation summary artifact path.")
102
102
  parser.add_argument("--no-progress-count", type=int, default=None, help="Consecutive context-overflow sessions without objective progress.")
103
103
  parser.add_argument("--progress-fingerprint", default=None, help="JSON progress fingerprint captured after the session.")
104
- parser.add_argument("--checkpoint-state", default=None, help="JSON semantic L4 checkpoint snapshot captured after the session.")
104
+ parser.add_argument("--checkpoint-state", default=None, help="JSON semantic pipeline checkpoint snapshot captured after the session.")
105
105
  return parser.parse_args()
106
106
 
107
107
 
@@ -260,7 +260,6 @@ SEMANTIC_CHECKPOINT_FIELDS = (
260
260
  "stage_result",
261
261
  "repair_scope",
262
262
  "repair_round",
263
- "authoritative_evidence_paths",
264
263
  "blocked_reason",
265
264
  "terminal_status",
266
265
  )
@@ -24,7 +24,7 @@ Infer what needs to be done from the feature context above and follow the active
24
24
 
25
25
  ### Execution Steps
26
26
 
27
- 1. **Read context**: Read `.prizmkit/prizm-docs/root.prizm` and relevant L1/L2 docs to understand the codebase.
27
+ 1. **Read context**: Read `.prizmkit/prizm-docs/root.prizm` and the relevant module indexes and detail docs to understand the codebase.
28
28
 
29
29
  2. **Plan**: Run `/prizmkit-plan` with `artifact_dir=.prizmkit/specs/{{FEATURE_SLUG}}/` to produce `spec.md` and `plan.md`.
30
30
 
@@ -32,7 +32,7 @@ Infer what needs to be done from the feature context above and follow the active
32
32
 
33
33
  4. **Review**: Run `/prizmkit-code-review` with `artifact_dir=.prizmkit/specs/{{FEATURE_SLUG}}/` and follow the skill's current review contract for review execution, repairs, verification, evidence, and handoff. Require the last `## Final Result`. `REVIEW_PASS` proceeds to test; `REVIEW_NEEDS_FIXES` increments the shared outer repair round and routes implement → code-review → test. Do not invoke another review entry point or add a second review path outside the skill contract.
34
34
 
35
- 5. **Test**: After review passes, run `/prizmkit-test scope=this-change artifact_dir=.prizmkit/specs/{{FEATURE_SLUG}}/`. Treat the Markdown report only as a derived view. Consume `.prizmkit/test/evidence/<evidence-id>/manifest.json`, `verdict.json`, and `validation.json`; verify identity/scope, every manifest hash, verdict/validator agreement, and current target hashes before accepting `TEST_PASS`. `TEST_FAIL/test-infrastructure` routes implement test; production/runtime/schema/dependency/public-interface routes implement code-review test; unknown unsafe scope blocks. `TEST_BLOCKED` allows bounded environment recovery or a test-stage resume but never speculative production edits. Stop outer repairs after three rounds; preserve evidence and truthful recovery metadata.
35
+ 5. **Test**: After review passes, run `/prizmkit-test scope=this-change artifact_dir=.prizmkit/specs/{{FEATURE_SLUG}}/`. Consume the sibling `test-report.md` and `test-result.json`; they must agree. `TEST_PASS` proceeds to retrospective. `TEST_NEEDS_FIXES` or `TEST_BLOCKED` preserves its known correction or blocker and stops truthfully. Do not require an evidence package, reinterpret a testing result as a runtime crash, or recreate the skill's bounded review and repair loops.
36
36
 
37
37
  6. **Retrospective**: Run `/prizmkit-retrospective` to sync `.prizmkit/prizm-docs/` with code changes.
38
38
 
@@ -46,5 +46,5 @@ Infer what needs to be done from the feature context above and follow the active
46
46
  - If a step fails after 3 attempts, write a status report and stop.
47
47
  - **Never re-read unmodified files**: once you read a file into context, do NOT read it again unless it was modified by an Edit/Write after your last read — use `grep -n`/`sed -n` for specific lines. Before issuing a Read, ask: "Have I read this file before, and has it changed since?" If no — do NOT read it. Follow the active skill and runtime contracts when an execution unit is created; do not infer its permissions, continuation, or retry behavior from this fallback prompt.
48
48
  - **Read offset safety**: if Read returns "shorter than offset"/"empty" — run `wc -l` then `sed -n`, do NOT retry same offset.
49
- - **Hard Round Cap**: after 6 total test-fix rounds, STOP trial-and-error. Switch to read-once-then-rewrite. Do NOT exceed 7 rounds.
49
+ - Follow each skill's own bounded loops; do not add a second cross-skill test-fix loop in this fallback prompt.
50
50
  - **Layered test**: debug with single-file tests, only run full suite as gate when single-file is green.
@@ -128,7 +128,7 @@ If `EXISTING_CODE` is non-empty: your spec/plan/tasks must reflect this existing
128
128
 
129
129
  **Step A — Build Context Snapshot** (skip if `context-snapshot.md` already exists):
130
130
 
131
- 1. Read `.prizmkit/prizm-docs/root.prizm` and relevant L1/L2 prizm docs
131
+ 1. Read `.prizmkit/prizm-docs/root.prizm` and the relevant module indexes and detail docs
132
132
  2. Detect source code directories from KEY_FILES and STRUCTURE sections in `root.prizm`; if root docs are unavailable, use the helper to list likely source files:
133
133
  ```bash
134
134
  {{RUNTIME_HELPER_CMD}} artifact source-files . --json
@@ -138,7 +138,7 @@ If `EXISTING_CODE` is non-empty: your spec/plan/tasks must reflect this existing
138
138
  4. Write `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md`:
139
139
  - **Section 1 — Feature Brief**: feature description (2-3 lines) + acceptance criteria (copy from above)
140
140
  - **Section 2 — Verification Gates**: copy the gate checklist from the Task Contract above
141
- - **Section 3 — Key TRAPS & RULES**: extract only relevant TRAPS/RULES from prizm-docs that apply to files in this scope. Do NOT copy full L0/L1/L2 content.
141
+ - **Section 3 — Key TRAPS & RULES**: extract only relevant TRAPS/RULES from the loaded Prizm docs that apply to files in this scope. Do NOT copy complete documentation files.
142
142
  - **Section 4 — File Manifest**: For each file relevant to this feature, list: file path, why it's needed (modify/reference/test), key interface signatures (function names + params + return types). Do NOT include full file content — agents read files on-demand. Format:
143
143
  ### Files to Modify
144
144
  | File | Why Needed | Key Interfaces |
@@ -151,7 +151,7 @@ If `EXISTING_CODE` is non-empty: your spec/plan/tasks must reflect this existing
151
151
  | `<source-dir>/security/permission-guard.js` | Permission check integration | `checkCommandPermission(userId, cmd)` |
152
152
 
153
153
  ### Known TRAPS (from .prizmkit/prizm-docs/)
154
- - <trap entries extracted from L1/L2 docs>
154
+ - <trap entries extracted from the loaded Prizm docs>
155
155
  4. Confirm: `{{RUNTIME_HELPER_CMD}} artifact exists .prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md`
156
156
 
157
157
  **After Step A**: Use context-snapshot.md Section 4 File Manifest to guide targeted file reads. Do NOT scan directories or read unrelated files.
@@ -252,26 +252,15 @@ Only `REVIEW_PASS` can proceed to the structured Feature test gate. `REVIEW_INCO
252
252
 
253
253
  ### Scoped Feature Test Gate — PrizmKit Test
254
254
 
255
- Create the current-run marker, then invoke the Feature gate:
256
-
257
- ```bash
258
- {{RUNTIME_HELPER_CMD}} artifact ensure-dir .prizmkit/specs/{{FEATURE_SLUG}}
259
- {{RUNTIME_HELPER_CMD}} artifact touch .prizmkit/specs/{{FEATURE_SLUG}}/.prizmkit-test-started
260
- ```
255
+ Invoke the Feature test gate:
261
256
 
262
257
  ```text
263
258
  /prizmkit-test scope=this-change artifact_dir=.prizmkit/specs/{{FEATURE_SLUG}}/
264
259
  ```
265
260
 
266
- The Markdown `test-report.md` is a derived view only. Locate its package through `.prizmkit/specs/{{FEATURE_SLUG}}/test-report-path.txt` and consume authoritative `.prizmkit/test/evidence/<evidence-id>/manifest.json`, `verdict.json`, and `validation.json`. Before accepting `TEST_PASS`, verify evidence identity/scope, every manifest file hash, final-verdict agreement, validator result and payload hash, current inventory target hashes, and the compatibility value `legacy-test-report-interface-not-supported`. Never accept a Markdown-only PASS.
267
-
268
- Repair routes:
269
- - `TEST_FAIL` with `repair_scope=test-infrastructure` → implement → test, without speculative production edits.
270
- - `TEST_FAIL` with production/runtime/schema/dependency/public-interface scope → implement → code-review → test.
271
- - Unknown unsafe scope → `WORKFLOW_BLOCKED`; do not guess a production edit.
272
- - `TEST_BLOCKED` → preserve evidence/artifacts, perform bounded environment recovery, then resume from test or finish terminal `WORKFLOW_BLOCKED`; never edit production speculatively.
261
+ Consume `.prizmkit/specs/{{FEATURE_SLUG}}/test-report.md` and `test-result.json`. They must agree. `TEST_PASS` completes the gate; `TEST_NEEDS_FIXES` preserves a known correction or delta-review requirement and stops truthfully; `TEST_BLOCKED` preserves the blocker and becomes `WORKFLOW_BLOCKED`. Do not require an evidence package, manifest, hashes, attestation, or test-internal checkpoint, and do not reinterpret a testing result as an AI CLI crash.
273
262
 
274
- Record `stage`, `status`, `stage_result`, `repair_scope`, `repair_round`, structured evidence paths, `next_stage`, and `resume_from` in truthful recovery metadata. Keep L1 workflow state separate from L4 `workflow-checkpoint.json`. The outer repair round stops after three and is independent of the internal review loop.
263
+ Record only caller-owned `stage`, `status`, `stage_result`, `repair_scope`, `repair_round`, `next_stage`, and `resume_from` in recovery metadata. Keep testing reports/results separate from `workflow-checkpoint.json`. The skill owns its internal ten-round Main-Agent review, five-response optional independent review, and three-round execution-failure repair budgets.
275
264
 
276
265
  {{IF_BROWSER_INTERACTION}}
277
266
  ### Phase 5.5: Browser Verification — MANDATORY
@@ -448,7 +437,7 @@ git log --oneline
448
437
  **6b.** Run `/prizmkit-retrospective` (**before commit**, maintains `.prizmkit/prizm-docs/` architecture index):
449
438
  - **Structural sync**: update KEY_FILES/INTERFACES/DEPENDENCIES/file counts for changed modules
450
439
  - **Architecture knowledge** (feature sessions only): extract TRAPS, RULES, DECISIONS from completed work into `.prizmkit/prizm-docs/`
451
- - **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.
440
+ - **Detail-doc coverage check**: For any module/sub-module with source files created or significantly modified in this session but no detail `.prizm` doc — evaluate whether one is warranted and create it when needed. The current session has the best context for accurate KEY_FILES, TRAPS, and DECISIONS.
452
441
  - Stage doc changes: `git add .prizmkit/prizm-docs/`
453
442
  ⚠️ Do NOT commit here. Only stage.
454
443