prizmkit 1.1.130 → 1.1.134

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 (119) hide show
  1. package/bundled/VERSION.json +3 -3
  2. package/bundled/adapters/claude/command-adapter.js +0 -2
  3. package/bundled/dev-pipeline/.env.example +1 -1
  4. package/bundled/dev-pipeline/assets/skill-subagent-integration.md +11 -6
  5. package/bundled/dev-pipeline/prizmkit_runtime/checkpoint_state.py +445 -8
  6. package/bundled/dev-pipeline/prizmkit_runtime/gitops.py +2 -9
  7. package/bundled/dev-pipeline/prizmkit_runtime/processes.py +21 -1
  8. package/bundled/dev-pipeline/prizmkit_runtime/runner_classification.py +87 -66
  9. package/bundled/dev-pipeline/prizmkit_runtime/runner_models.py +53 -3
  10. package/bundled/dev-pipeline/prizmkit_runtime/runner_recovery.py +55 -25
  11. package/bundled/dev-pipeline/prizmkit_runtime/runner_status.py +4 -0
  12. package/bundled/dev-pipeline/prizmkit_runtime/runners.py +119 -18
  13. package/bundled/dev-pipeline/prizmkit_runtime/sessions.py +3 -2
  14. package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +411 -17
  15. package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +57 -14
  16. package/bundled/dev-pipeline/scripts/generate-recovery-prompt.py +5 -4
  17. package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +55 -2
  18. package/bundled/dev-pipeline/scripts/prompt_framework.py +152 -1
  19. package/bundled/dev-pipeline/scripts/update-bug-status.py +53 -0
  20. package/bundled/dev-pipeline/scripts/update-checkpoint.py +294 -69
  21. package/bundled/dev-pipeline/scripts/update-feature-status.py +57 -0
  22. package/bundled/dev-pipeline/scripts/update-refactor-status.py +53 -0
  23. package/bundled/dev-pipeline/templates/bootstrap-prompt.md +5 -5
  24. package/bundled/dev-pipeline/templates/bootstrap-tier3.md +28 -22
  25. package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +24 -10
  26. package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +20 -2
  27. package/bundled/dev-pipeline/templates/sections/bugfix-phase-commit-report.md +2 -2
  28. package/bundled/dev-pipeline/templates/sections/bugfix-phase-diagnose-plan.md +1 -1
  29. package/bundled/dev-pipeline/templates/sections/bugfix-phase-manual-verification.md +5 -10
  30. package/bundled/dev-pipeline/templates/sections/bugfix-phase-review.md +9 -19
  31. package/bundled/dev-pipeline/templates/sections/bugfix-phase-test.md +21 -0
  32. package/bundled/dev-pipeline/templates/sections/bugfix-session-status.md +1 -1
  33. package/bundled/dev-pipeline/templates/sections/checkpoint-system.md +10 -10
  34. package/bundled/dev-pipeline/templates/sections/context-budget-rules.md +1 -1
  35. package/bundled/dev-pipeline/templates/sections/headless-commit-authorization.md +15 -0
  36. package/bundled/dev-pipeline/templates/sections/phase-commit-full.md +2 -2
  37. package/bundled/dev-pipeline/templates/sections/phase-commit.md +2 -2
  38. package/bundled/dev-pipeline/templates/sections/phase-prizmkit-test.md +26 -23
  39. package/bundled/dev-pipeline/templates/sections/phase-review-agent.md +5 -5
  40. package/bundled/dev-pipeline/templates/sections/phase-review-full.md +15 -11
  41. package/bundled/dev-pipeline/templates/sections/refactor-phase-commit-report.md +1 -1
  42. package/bundled/dev-pipeline/templates/sections/refactor-phase-review.md +6 -6
  43. package/bundled/dev-pipeline/templates/sections/refactor-phase-test.md +21 -0
  44. package/bundled/dev-pipeline/templates/sections/refactor-reminders.md +1 -1
  45. package/bundled/dev-pipeline/templates/sections/subagent-timeout-recovery.md +1 -1
  46. package/bundled/dev-pipeline/templates/sections/task-contract.md +4 -0
  47. package/bundled/dev-pipeline/tests/test_checkpoint_state.py +362 -3
  48. package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +349 -48
  49. package/bundled/dev-pipeline/tests/test_generate_bugfix_prompt.py +129 -0
  50. package/bundled/dev-pipeline/tests/test_generate_refactor_prompt.py +91 -0
  51. package/bundled/dev-pipeline/tests/test_python_runner_parity.py +567 -23
  52. package/bundled/dev-pipeline/tests/test_unified_cli.py +37 -10
  53. package/bundled/skills/_metadata.json +63 -26
  54. package/bundled/skills/app-planner/SKILL.md +4 -3
  55. package/bundled/skills/bug-fix-workflow/SKILL.md +89 -180
  56. package/bundled/skills/bug-planner/SKILL.md +12 -27
  57. package/bundled/skills/bugfix-pipeline-launcher/SKILL.md +131 -220
  58. package/bundled/skills/bugfix-pipeline-launcher/references/configuration.md +36 -90
  59. package/bundled/skills/feature-pipeline-launcher/SKILL.md +129 -271
  60. package/bundled/skills/feature-pipeline-launcher/references/configuration.md +35 -76
  61. package/bundled/skills/feature-planner/SKILL.md +27 -22
  62. package/bundled/skills/feature-planner/assets/planning-guide.md +4 -4
  63. package/bundled/skills/feature-workflow/SKILL.md +94 -121
  64. package/bundled/skills/prizmkit/SKILL.md +130 -94
  65. package/bundled/skills/prizmkit/references/workflow-state-protocol.md +181 -0
  66. package/bundled/skills/prizmkit-code-review/SKILL.md +132 -86
  67. package/bundled/skills/prizmkit-code-review/references/independent-code-review.md +243 -0
  68. package/bundled/skills/prizmkit-code-review/references/review-report-template.md +42 -1
  69. package/bundled/skills/prizmkit-code-review/references/workflow-state-protocol.md +181 -0
  70. package/bundled/skills/prizmkit-code-review/scripts/render_review_report.py +93 -1
  71. package/bundled/skills/prizmkit-committer/SKILL.md +125 -48
  72. package/bundled/skills/prizmkit-committer/references/workflow-state-protocol.md +181 -0
  73. package/bundled/skills/prizmkit-implement/SKILL.md +99 -73
  74. package/bundled/skills/prizmkit-implement/references/implementation-subagent-procedure.md +1 -1
  75. package/bundled/skills/prizmkit-implement/references/workflow-state-protocol.md +181 -0
  76. package/bundled/skills/prizmkit-init/SKILL.md +5 -5
  77. package/bundled/skills/prizmkit-plan/SKILL.md +146 -105
  78. package/bundled/skills/prizmkit-plan/assets/plan-template.md +18 -0
  79. package/bundled/skills/prizmkit-plan/references/independent-plan-review.md +242 -0
  80. package/bundled/skills/prizmkit-plan/references/review-plan-spec-loop.md +4 -4
  81. package/bundled/skills/prizmkit-plan/references/workflow-state-protocol.md +181 -0
  82. package/bundled/skills/prizmkit-retrospective/SKILL.md +111 -53
  83. package/bundled/skills/prizmkit-retrospective/references/knowledge-injection-steps.md +7 -6
  84. package/bundled/skills/prizmkit-retrospective/references/structural-sync-steps.md +5 -4
  85. package/bundled/skills/prizmkit-retrospective/references/workflow-state-protocol.md +181 -0
  86. package/bundled/skills/prizmkit-test/SKILL.md +52 -6
  87. package/bundled/skills/prizmkit-test/assets/authoritative-records.schema.json +63 -12
  88. package/bundled/skills/prizmkit-test/assets/evidence-manifest.schema.json +1 -1
  89. package/bundled/skills/prizmkit-test/assets/evidence-package-template.json +13 -0
  90. package/bundled/skills/prizmkit-test/references/evidence-protocol.md +6 -1
  91. package/bundled/skills/prizmkit-test/references/evidence-request-protocol.md +8 -1
  92. package/bundled/skills/prizmkit-test/references/examples.md +1 -1
  93. package/bundled/skills/prizmkit-test/references/test-generation-steps.md +4 -1
  94. package/bundled/skills/prizmkit-test/references/test-report-template.md +1 -1
  95. package/bundled/skills/prizmkit-test/references/trusted-evidence-execution.md +15 -0
  96. package/bundled/skills/prizmkit-test/references/workflow-state-protocol.md +181 -0
  97. package/bundled/skills/prizmkit-test/scripts/build_test_evidence.py +744 -23
  98. package/bundled/skills/prizmkit-test/scripts/validate_test_evidence.py +194 -15
  99. package/bundled/skills/prizmkit-workflow/SKILL.md +266 -0
  100. package/bundled/skills/prizmkit-workflow/references/workflow-state-protocol.md +181 -0
  101. package/bundled/skills/recovery-workflow/SKILL.md +62 -241
  102. package/bundled/skills/recovery-workflow/evals/evals.json +17 -33
  103. package/bundled/skills/recovery-workflow/references/detection.md +28 -52
  104. package/bundled/skills/recovery-workflow/scripts/detect-recovery-state.py +105 -439
  105. package/bundled/skills/refactor-pipeline-launcher/SKILL.md +136 -275
  106. package/bundled/skills/refactor-pipeline-launcher/references/configuration.md +53 -88
  107. package/bundled/skills/refactor-planner/SKILL.md +12 -57
  108. package/bundled/skills/refactor-planner/references/behavior-preservation.md +111 -230
  109. package/bundled/skills/refactor-planner/references/error-recovery.md +37 -0
  110. package/bundled/skills/refactor-planner/references/planning-phases.md +11 -17
  111. package/bundled/skills/refactor-planner/scripts/validate-and-generate-refactor.py +1 -1
  112. package/bundled/skills/refactor-workflow/SKILL.md +98 -139
  113. package/bundled/templates/project-memory-template.md +4 -4
  114. package/package.json +1 -1
  115. package/src/index.js +4 -0
  116. package/src/prompts.js +10 -3
  117. package/src/scaffold.js +1 -1
  118. package/bundled/dev-pipeline/tests/test-deploy-safety.sh +0 -223
  119. package/bundled/skills/feature-pipeline-launcher/scripts/preflight-check.py +0 -462
@@ -2,13 +2,13 @@
2
2
 
3
3
  Review the completed implementation before the scoped feature test gate runs. Use `artifact_dir=.prizmkit/specs/{{FEATURE_SLUG}}/` so `/prizmkit-code-review` can read the spec, plan, context snapshot, implementation log, and current diff. Do not require a prior `/prizmkit-test` report here; the next phase owns the formal test gate.
4
4
 
5
- Run `/prizmkit-code-review` with `artifact_dir=.prizmkit/specs/{{FEATURE_SLUG}}/`. The skill runs a Main-Agent review loop for up to ten completed rounds. The current Main Agent is the only Code Review executor: it reviews the complete current change, rejects unsupported candidate findings, directly repairs accepted findings, verifies repairs, and repeats until `accepted = 0` with no unresolved findings.
5
+ Run `/prizmkit-code-review` with `artifact_dir=.prizmkit/specs/{{FEATURE_SLUG}}/`. The skill runs a mandatory Main-Agent review loop for up to ten completed rounds: the Main Agent reviews the complete current change, rejects unsupported candidate findings, directly repairs accepted findings, verifies repairs, and repeats until `accepted = 0` with no unresolved findings. After convergence, one skill-owned independent Reviewer is optional only when the strict structural capability gate passes; otherwise no Reviewer is created.
6
6
 
7
- The Code Review execution boundary is absolute for this phase:
7
+ The Code Review execution boundary is closed for this phase:
8
8
 
9
- - Do not delegate any review work directly or indirectly.
10
- - Do not invoke another review skill or review workflow.
11
- - Do not use a general-purpose execution unit for review or relabel delegated work as a finder, verifier, audit, compatibility review, verification, or gap sweep.
9
+ - Do not delegate the mandatory Main-Agent review or invoke another review skill or workflow.
10
+ - Do not add review execution outside the single optional Reviewer owned and gated by `prizmkit-code-review`.
11
+ - The optional Reviewer must be structurally read-only, unable to execute arbitrary commands or downstream execution, and natively resumable as the same unit; otherwise strict downgrade applies.
12
12
  - Direct reading, searching, editing, and testing by the current Main Agent remain allowed.
13
13
  - `review-report.md` is the only persisted review artifact; do not append separate Review Notes to `context-snapshot.md`.
14
14
 
@@ -1,19 +1,23 @@
1
1
  ### Review — Code Review
2
2
 
3
- Review the completed implementation before the scoped feature test gate runs. Use `artifact_dir=.prizmkit/specs/{{FEATURE_SLUG}}/` so `/prizmkit-code-review` can read the spec, plan, context snapshot, implementation log, and current diff. Do not require a prior `/prizmkit-test` report here; the next phase owns the formal test gate.
3
+ Review the completed implementation before the full Feature test gate runs. A review result is a required predecessor; never accept or route around testing as if a review had passed.
4
4
 
5
- Run `/prizmkit-code-review` with `artifact_dir=.prizmkit/specs/{{FEATURE_SLUG}}/`. The skill runs a Main-Agent review loop for up to ten completed rounds. The current Main Agent is the only Code Review executor: it reviews the complete current change, rejects unsupported candidate findings, directly repairs accepted findings, verifies repairs, and repeats until `accepted = 0` with no unresolved findings.
5
+ Use `artifact_dir=.prizmkit/specs/{{FEATURE_SLUG}}/` so `/prizmkit-code-review` can read the spec, plan, context snapshot, implementation log, and current diff. The skill runs a mandatory Main-Agent review loop of up to ten completed rounds and writes only `review-report.md`. After Main-Agent convergence, the skill may create one skill-owned independent Reviewer only when its strict structural capability gate passes; otherwise it records downgrade and creates none.
6
6
 
7
- The Code Review execution boundary is absolute for this phase:
7
+ - `REVIEW_PASS` update checkpoint metadata with `stage=code-review`, `status=REVIEW_PASS`, `stage_result=REVIEW_PASS`, `next_stage=prizmkit-test`, and `resume_from=prizmkit-test`; then run the full test gate.
8
+ - `REVIEW_NEEDS_FIXES` → preserve findings, increment the shared outer `repair_round`, route `prizmkit-implement` → `prizmkit-code-review` → `prizmkit-test`, and do not accept any test result from before the repaired review.
9
+ - If the outer repair round is already three, record `WORKFLOW_BLOCKED`; do not start another repair route.
8
10
 
9
- - Do not delegate any review work directly or indirectly.
10
- - Do not invoke another review skill or review workflow.
11
- - Do not use a general-purpose execution unit for review or relabel delegated work as a finder, verifier, audit, compatibility review, verification, or gap sweep.
11
+ Missing required evidence, unsafe repair, failed verification, or failure to converge by round ten produces `REVIEW_NEEDS_FIXES`.
12
+
13
+ The Code Review execution boundary is closed:
14
+
15
+ - Do not delegate the mandatory Main-Agent review or invoke another review skill or workflow.
16
+ - Do not add review execution outside the single optional Reviewer owned and gated by `prizmkit-code-review`.
17
+ - The optional Reviewer must be structurally read-only, unable to execute arbitrary commands or downstream execution, and natively resumable as the same unit; otherwise strict downgrade applies.
12
18
  - Direct reading, searching, editing, and testing by the current Main Agent remain allowed.
13
19
  - `review-report.md` is the only persisted review artifact; do not append separate Review Notes to `context-snapshot.md`.
14
20
 
15
- Missing required evidence, an unsafe repair, a failed verification, or failure to converge by round ten produces `NEEDS_FIXES`.
16
-
17
21
  **Gate Check — Final Review Result**:
18
22
 
19
23
  ```bash
@@ -22,9 +26,9 @@ Missing required evidence, an unsafe repair, a failed verification, or failure t
22
26
 
23
27
  Handle the marker:
24
28
 
25
- - `REVIEW_PASS` → proceed to next phase.
26
- - `REVIEW_NEEDS_FIXES` → log unresolved findings and follow the task failure policy; do not externally restart the review loop.
27
- - `REVIEW_INCOMPLETE` or `REVIEW_INVALID` → inspect the append-only progress once, write `failure-log.md`, and stop. Do not treat an old or incidental verdict as completion and do not synthesize a passing result outside the skill.
29
+ - `REVIEW_PASS` → proceed to the structured test gate.
30
+ - `REVIEW_NEEDS_FIXES` → follow the repair route above; do not externally restart the review loop.
31
+ - `REVIEW_INCOMPLETE` or `REVIEW_INVALID` → inspect append-only progress once, write `failure-log.md`, and stop. Do not accept old/incidental verdict text or synthesize a pass.
28
32
 
29
33
  **CP-3**: Review has a valid Final Result and `review-report.md` preserves this execution's progress.
30
34
 
@@ -14,7 +14,7 @@ Run `/prizmkit-committer` with commit prefix:
14
14
  refactor({{REFACTOR_ID}}): {{REFACTOR_TITLE}}
15
15
  ```
16
16
 
17
- Do not push.
17
+ The runtime controls any optional remote publication after this local commit; do not make a publication decision in this session.
18
18
 
19
19
  Write `.prizmkit/refactor/{{REFACTOR_ID}}/refactor-report.md` with:
20
20
  - refactor summary;
@@ -1,12 +1,12 @@
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 skill runs a Main-Agent review loop for up to ten completed rounds. The current Main Agent is the only Code Review executor: it reviews the complete current change, rejects unsupported candidate findings, directly repairs accepted findings, verifies repairs, and repeats until `accepted = 0` with no unresolved findings.
3
+ Run `/prizmkit-code-review` directly with `artifact_dir=.prizmkit/refactor/{{REFACTOR_ID}}/`. The skill runs a mandatory Main-Agent review loop for up to ten completed rounds: the Main Agent reviews the complete current change, rejects unsupported candidate findings, directly repairs accepted findings, verifies repairs, and repeats until `accepted = 0` with no unresolved findings. After convergence, one skill-owned independent Reviewer is optional only when the strict structural capability gate passes; otherwise no Reviewer is created.
4
4
 
5
- The Code Review execution boundary is absolute for this phase:
5
+ The Code Review execution boundary is closed for this phase:
6
6
 
7
- - Do not delegate any review work directly or indirectly.
8
- - Do not invoke another review skill or review workflow.
9
- - Do not use a general-purpose execution unit for review or relabel delegated work as a finder, verifier, audit, compatibility review, verification, or gap sweep.
7
+ - Do not delegate the mandatory Main-Agent review or invoke another review skill or workflow.
8
+ - Do not add review execution outside the single optional Reviewer owned and gated by `prizmkit-code-review`.
9
+ - The optional Reviewer must be structurally read-only, unable to execute arbitrary commands or downstream execution, and natively resumable as the same unit; otherwise strict downgrade applies.
10
10
  - Direct reading, searching, editing, and testing by the current Main Agent remain allowed.
11
11
  - `review-report.md` is the only persisted review artifact; do not append separate Review Notes to another artifact.
12
12
 
@@ -24,4 +24,4 @@ Missing required evidence, an unsafe repair, a failed verification, or failure t
24
24
 
25
25
  Verify directly that the review checks behavior preservation, public API compatibility, imports, tests, and rollback assumptions.
26
26
 
27
- **Checkpoint update**: Set step `prizmkit-code-review` to `completed` only for an accepted valid Final Result. Do not complete the checkpoint for incomplete or invalid reports.
27
+ **Checkpoint update**: Set step `prizmkit-code-review` to `completed` with `stage_result=REVIEW_PASS` only for an accepted valid Final Result. Do not complete the checkpoint for incomplete or invalid reports.
@@ -0,0 +1,21 @@
1
+ ### Refactor Test Gate — PrizmKit Test
2
+
3
+ After Main-Agent code review returns a valid `PASS`, run the mandatory post-review test stage against the same Refactor artifact root. Behavior-preservation checks collected during planning and implementation remain supporting evidence; they never replace this authoritative evidence gate.
4
+
5
+ ```text
6
+ /prizmkit-test scope=this-change artifact_dir=.prizmkit/refactor/{{REFACTOR_ID}}/
7
+ ```
8
+
9
+ Read the current structured evidence package under `.prizmkit/test/evidence/<evidence-id>/`: `manifest.json`, `verdict.json`, and `validation.json`. A derived Markdown report is not completion authority. Confirm scope, hashes, final verdict, and validator result before accepting `TEST_PASS`.
10
+
11
+ Gate outcomes and authoritative routing:
12
+
13
+ - `TEST_PASS`: verify behavior-preservation evidence remains recorded, update the checkpoint handoff, and continue to retrospective.
14
+ - `TEST_FAIL` with `repair_scope=test-infrastructure`: return to `/prizmkit-implement`, preserve the behavior baseline, then return directly to this test gate; do not make speculative production edits.
15
+ - `TEST_FAIL` with `repair_scope=production|runtime|schema|dependency|public-interface`: return to implementation, obtain a fresh code-review result, then return to this test gate.
16
+ - `TEST_FAIL` with an unknown or missing `repair_scope`: record `WORKFLOW_BLOCKED` and leave a safe checkpoint at the test stage; do not guess a production edit.
17
+ - `TEST_BLOCKED`: preserve all evidence and artifacts, perform only bounded automatic environment recovery, then terminate as `WORKFLOW_BLOCKED` with `blocked_reason=test_blocked`. Never edit production speculatively and never ask the user.
18
+
19
+ The `repair_round` counter is shared with review failures and may not exceed three outer rounds. At the limit, leave a truthful blocked terminal result. Internal code-review convergence has its separate ten-round limit.
20
+
21
+ **Checkpoint update**: Only a validated structured `TEST_PASS` may complete `prizmkit-test` with `stage_result=TEST_PASS` plus `manifest`, `verdict`, and `validation` evidence paths, then proceed to retrospective.
@@ -3,7 +3,7 @@
3
3
  - Use L1 skills: `/prizmkit-plan`, `/prizmkit-implement`, `/prizmkit-code-review`, `/prizmkit-retrospective`, `/prizmkit-committer`.
4
4
  - All refactor skills use `artifact_dir=.prizmkit/refactor/{{REFACTOR_ID}}/`.
5
5
  - Behavior preservation is the first priority.
6
- - Do not spawn a top-level Dev implementation subagent; Code Review runs only in the current Main Agent without delegation.
6
+ - Do not spawn a top-level Dev implementation subagent; Code Review keeps mandatory Main-Agent ownership and may use only its strict-gated skill-owned Reviewer after convergence.
7
7
  - Main orchestrator runs `/prizmkit-code-review` directly.
8
8
  - Commit with `refactor(<scope>):`, not `feat:` or `fix:`.
9
9
  - Checkpoint state is the recovery truth; skipped steps must be marked `skipped`.
@@ -1,6 +1,6 @@
1
1
  ## Normal Work Delegation Timeout Recovery
2
2
 
3
- This recovery path applies only to normal work delegated outside Code Review. Code Review never uses delegated execution or this retry procedure.
3
+ This recovery path applies only to normal work delegated outside the optional skill-owned review contract. Code Review never applies this retry procedure to its independent Reviewer; Reviewer creation or native-resume failure uses the skill's strict downgrade instead.
4
4
 
5
5
  If a normal work execution unit times out:
6
6
  1. `{{RUNTIME_HELPER_CMD}} artifact list .prizmkit/specs/{{FEATURE_SLUG}}` — check what exists
@@ -8,6 +8,10 @@ Implement {{FEATURE_ID}}: "{{FEATURE_TITLE}}".
8
8
 
9
9
  {{FEATURE_DESCRIPTION}}
10
10
 
11
+ ### User Context
12
+
13
+ {{USER_CONTEXT}}
14
+
11
15
  ### Scope Rule
12
16
 
13
17
  Current scope is limited to the intersection of:
@@ -4,7 +4,7 @@ from __future__ import annotations
4
4
 
5
5
  import json
6
6
 
7
- from prizmkit_runtime.checkpoint_state import load_checkpoint_state, read_checkpoint_cursor
7
+ from prizmkit_runtime.checkpoint_state import load_checkpoint_state, read_checkpoint_cursor, validate_checkpoint_data
8
8
  from update_checkpoint import update_checkpoint
9
9
 
10
10
 
@@ -138,7 +138,7 @@ def test_update_checkpoint_rejects_ambiguous_skill_without_mutation(tmp_path):
138
138
 
139
139
  def test_update_checkpoint_exact_id_updates_one_duplicate_skill_step(tmp_path):
140
140
  path = _write(tmp_path / "workflow-checkpoint.json", _checkpoint([
141
- _step("S01", "prizmkit-committer", "Commit First", "pending"),
141
+ _step("S01", "prizmkit-committer", "Commit First", "completed"),
142
142
  _step("S02", "prizmkit-committer", "Commit Second", "pending", "S01"),
143
143
  ]))
144
144
 
@@ -147,7 +147,7 @@ def test_update_checkpoint_exact_id_updates_one_duplicate_skill_step(tmp_path):
147
147
 
148
148
  assert result["ok"] is True
149
149
  assert result["step_id"] == "S02"
150
- assert data["steps"][0]["status"] == "pending"
150
+ assert data["steps"][0]["status"] == "completed"
151
151
  assert data["steps"][1]["status"] == "completed"
152
152
 
153
153
 
@@ -162,3 +162,362 @@ def test_update_checkpoint_invalid_checkpoint_fails_without_mutation(tmp_path):
162
162
  assert result["ok"] is False
163
163
  assert "invalid_status" in result["error"]
164
164
  assert path.read_text(encoding="utf-8") == before
165
+
166
+
167
+
168
+ def _family_checkpoint(workflow_type, skills, *, semantic=None):
169
+ steps = []
170
+ previous = None
171
+ for index, skill in enumerate(skills, start=1):
172
+ step = _step(f"S{index:02d}", skill, skill, "completed", previous)
173
+ if skill == "prizmkit-code-review":
174
+ step["stage_result"] = "REVIEW_PASS"
175
+ if skill == "prizmkit-test":
176
+ step["stage_result"] = "TEST_PASS"
177
+ steps.append(step)
178
+ previous = step["id"]
179
+ payload = {"version": 1, "workflow_type": workflow_type, "steps": steps}
180
+ state_key = {
181
+ "feature-pipeline": "feature_state",
182
+ "bugfix-pipeline": "bugfix_state",
183
+ "refactor-pipeline": "refactor_state",
184
+ }[workflow_type]
185
+ payload[state_key] = semantic or {}
186
+ return payload
187
+
188
+
189
+ def _write_test_evidence(root, verdict="TEST_PASS", validation_result="passed", evidence_id="evidence-1"):
190
+ evidence = root / ".prizmkit" / "test" / "evidence" / evidence_id
191
+ evidence.mkdir(parents=True)
192
+ manifest = evidence / "manifest.json"
193
+ verdict_path = evidence / "verdict.json"
194
+ validation = evidence / "validation.json"
195
+ manifest.write_text(json.dumps({"evidence_id": evidence_id, "final_verdict": verdict}), encoding="utf-8")
196
+ verdict_path.write_text(json.dumps({"verdict": verdict}), encoding="utf-8")
197
+ validation.write_text(json.dumps({"verdict": verdict, "result": validation_result}), encoding="utf-8")
198
+ return {
199
+ "manifest": str(manifest.relative_to(root)),
200
+ "verdict": str(verdict_path.relative_to(root)),
201
+ "validation": str(validation.relative_to(root)),
202
+ }
203
+
204
+
205
+ def test_semantic_completion_requires_family_sequence_verdicts_and_structured_evidence(tmp_path, monkeypatch):
206
+ monkeypatch.setattr(
207
+ "prizmkit_runtime.checkpoint_state._resolve_evidence_validator",
208
+ lambda _root: tmp_path / "validator.py",
209
+ )
210
+ monkeypatch.setattr(
211
+ "prizmkit_runtime.checkpoint_state._evidence_validator_passes",
212
+ lambda *_args: True,
213
+ )
214
+ paths = _write_test_evidence(tmp_path)
215
+ skills = [
216
+ "prizmkit-implement", "prizmkit-code-review", "prizmkit-test",
217
+ "prizmkit-retrospective", "prizmkit-committer", "completion-summary",
218
+ ]
219
+ payload = _family_checkpoint(
220
+ "feature-pipeline",
221
+ skills,
222
+ semantic={
223
+ "repair_round": 0,
224
+ "authoritative_evidence_paths": paths,
225
+ "terminal_status": "WORKFLOW_COMPLETED",
226
+ },
227
+ )
228
+ payload["steps"][2]["authoritative_evidence_paths"] = paths
229
+ checkpoint = tmp_path / ".prizmkit" / "specs" / "feature" / "workflow-checkpoint.json"
230
+ checkpoint.parent.mkdir(parents=True)
231
+ _write(checkpoint, payload)
232
+
233
+ state = load_checkpoint_state(checkpoint, project_root=tmp_path)
234
+
235
+ assert state.valid is True
236
+ assert state.all_completed is True
237
+ assert state.semantic_complete is True
238
+ assert state.semantic.evidence_valid is True
239
+ assert state.semantic.terminal_status == "WORKFLOW_COMPLETED"
240
+
241
+
242
+ def test_completed_steps_without_stage_verdicts_are_not_semantic_completion(tmp_path):
243
+ skills = [
244
+ "prizmkit-implement", "prizmkit-code-review", "prizmkit-test",
245
+ "prizmkit-retrospective", "prizmkit-committer", "completion-summary",
246
+ ]
247
+ payload = _family_checkpoint("feature-pipeline", skills)
248
+ payload["steps"][1].pop("stage_result")
249
+ payload["steps"][2].pop("stage_result")
250
+ payload["feature_state"]["terminal_status"] = "WORKFLOW_COMPLETED"
251
+
252
+ state = validate_checkpoint_data(payload, project_root=tmp_path)
253
+
254
+ assert state.valid is True
255
+ assert state.all_completed is True
256
+ assert state.semantic_complete is False
257
+ assert state.semantic.error_code == "incomplete_semantic_evidence"
258
+
259
+
260
+ def test_family_sequence_mismatch_cannot_complete(tmp_path):
261
+ paths = _write_test_evidence(tmp_path)
262
+ skills = [
263
+ "prizmkit-implement", "prizmkit-test", "prizmkit-code-review",
264
+ "prizmkit-retrospective", "prizmkit-committer", "completion-summary",
265
+ ]
266
+ payload = _family_checkpoint(
267
+ "feature-pipeline",
268
+ skills,
269
+ semantic={"authoritative_evidence_paths": paths, "terminal_status": "WORKFLOW_COMPLETED"},
270
+ )
271
+ payload["steps"][1]["authoritative_evidence_paths"] = paths
272
+
273
+ state = validate_checkpoint_data(payload, project_root=tmp_path)
274
+
275
+ assert state.semantic_complete is False
276
+ assert state.semantic.sequence_valid is False
277
+ assert state.semantic.error_code == "invalid_stage_sequence"
278
+
279
+
280
+ def test_stale_or_mismatched_test_evidence_cannot_complete(tmp_path):
281
+ paths = _write_test_evidence(tmp_path, verdict="TEST_FAIL")
282
+ skills = [
283
+ "prizmkit-implement", "prizmkit-code-review", "prizmkit-test",
284
+ "prizmkit-retrospective", "prizmkit-committer", "completion-summary",
285
+ ]
286
+ payload = _family_checkpoint(
287
+ "feature-pipeline",
288
+ skills,
289
+ semantic={"authoritative_evidence_paths": paths, "terminal_status": "WORKFLOW_COMPLETED"},
290
+ )
291
+ payload["steps"][2]["authoritative_evidence_paths"] = paths
292
+
293
+ state = validate_checkpoint_data(payload, project_root=tmp_path)
294
+
295
+ assert state.semantic_complete is False
296
+ assert state.semantic.evidence_valid is False
297
+ assert state.semantic.error_code == "incomplete_semantic_evidence"
298
+
299
+
300
+ def test_blocked_terminal_is_semantic_and_requires_reason(tmp_path):
301
+ payload = _family_checkpoint(
302
+ "feature-pipeline",
303
+ [
304
+ "prizmkit-implement", "prizmkit-code-review", "prizmkit-test",
305
+ "prizmkit-retrospective", "prizmkit-committer", "completion-summary",
306
+ ],
307
+ semantic={
308
+ "repair_scope": "production",
309
+ "repair_round": 3,
310
+ "blocked_reason": "repair_round_limit",
311
+ "terminal_status": "WORKFLOW_BLOCKED",
312
+ },
313
+ )
314
+ payload["steps"][2]["stage_result"] = "TEST_FAIL"
315
+
316
+ state = validate_checkpoint_data(payload, project_root=tmp_path)
317
+
318
+ assert state.semantic_blocked is True
319
+ assert state.semantic_complete is False
320
+ assert state.semantic.blocked_reason == "repair_round_limit"
321
+ assert state.cursor_signature == "blocked:repair_round_limit"
322
+
323
+
324
+ def test_step_progress_must_be_a_terminal_prefix(tmp_path):
325
+ payload = _checkpoint([
326
+ _step("S01", "plan", "Plan", "pending"),
327
+ _step("S02", "implement", "Implement", "completed", "S01"),
328
+ ])
329
+
330
+ state = validate_checkpoint_data(payload)
331
+
332
+ assert state.valid is False
333
+ assert state.error_code == "invalid_step_progress"
334
+
335
+
336
+
337
+ def test_update_checkpoint_rejects_out_of_order_transition(tmp_path):
338
+ path = _write(tmp_path / "workflow-checkpoint.json", _checkpoint([
339
+ _step("S01", "plan", "Plan", "pending"),
340
+ _step("S02", "implement", "Implement", "pending", "S01"),
341
+ ]))
342
+
343
+ result = update_checkpoint(str(path), "S02", "in_progress")
344
+
345
+ assert result["ok"] is False
346
+ assert "before all predecessors" in result["error"]
347
+
348
+
349
+ def test_update_checkpoint_blocks_unknown_repair_scope_without_mutating_retry_budget(tmp_path):
350
+ payload = _family_checkpoint(
351
+ "feature-pipeline",
352
+ [
353
+ "prizmkit-implement", "prizmkit-code-review", "prizmkit-test",
354
+ "prizmkit-retrospective", "prizmkit-committer", "completion-summary",
355
+ ],
356
+ )
357
+ payload["steps"][1]["status"] = "in_progress"
358
+ for step in payload["steps"][2:]:
359
+ step["status"] = "pending"
360
+ step.pop("stage_result", None)
361
+ path = _write(tmp_path / "workflow-checkpoint.json", payload)
362
+
363
+ result = update_checkpoint(
364
+ str(path),
365
+ "prizmkit-code-review",
366
+ "failed",
367
+ semantic_update={"stage_result": "REVIEW_NEEDS_FIXES", "repair_round": 0},
368
+ )
369
+ data = json.loads(path.read_text(encoding="utf-8"))
370
+
371
+ assert result["ok"] is True
372
+ assert data["feature_state"]["terminal_status"] == "WORKFLOW_BLOCKED"
373
+ assert data["feature_state"]["blocked_reason"] == "unsafe_repair_scope"
374
+ assert "retry_count" not in data["feature_state"]
375
+
376
+
377
+ def test_update_checkpoint_enforces_three_outer_repair_rounds(tmp_path):
378
+ payload = _family_checkpoint(
379
+ "feature-pipeline",
380
+ [
381
+ "prizmkit-implement", "prizmkit-code-review", "prizmkit-test",
382
+ "prizmkit-retrospective", "prizmkit-committer", "completion-summary",
383
+ ],
384
+ semantic={"repair_scope": "production", "repair_round": 3},
385
+ )
386
+ payload["steps"][1]["status"] = "in_progress"
387
+ for step in payload["steps"][2:]:
388
+ step["status"] = "pending"
389
+ step.pop("stage_result", None)
390
+ path = _write(tmp_path / "workflow-checkpoint.json", payload)
391
+
392
+ result = update_checkpoint(
393
+ str(path),
394
+ "prizmkit-code-review",
395
+ "failed",
396
+ semantic_update={"stage_result": "REVIEW_NEEDS_FIXES", "repair_scope": "production"},
397
+ )
398
+ data = json.loads(path.read_text(encoding="utf-8"))
399
+
400
+ assert result["ok"] is True
401
+ assert data["feature_state"]["repair_round"] == 3
402
+ assert data["feature_state"]["terminal_status"] == "WORKFLOW_BLOCKED"
403
+ assert data["feature_state"]["blocked_reason"] == "repair_round_limit"
404
+
405
+
406
+
407
+ def test_declared_final_artifact_must_exist_for_semantic_completion(tmp_path, monkeypatch):
408
+ monkeypatch.setattr(
409
+ "prizmkit_runtime.checkpoint_state._resolve_evidence_validator",
410
+ lambda _root: tmp_path / "validator.py",
411
+ )
412
+ monkeypatch.setattr(
413
+ "prizmkit_runtime.checkpoint_state._evidence_validator_passes",
414
+ lambda *_args: True,
415
+ )
416
+ paths = _write_test_evidence(tmp_path)
417
+ skills = [
418
+ "prizmkit-implement", "prizmkit-code-review", "prizmkit-test",
419
+ "prizmkit-retrospective", "prizmkit-committer", "completion-summary",
420
+ ]
421
+ payload = _family_checkpoint(
422
+ "feature-pipeline",
423
+ skills,
424
+ semantic={"authoritative_evidence_paths": paths, "terminal_status": "WORKFLOW_COMPLETED"},
425
+ )
426
+ payload["steps"][2]["authoritative_evidence_paths"] = paths
427
+ payload["steps"][-1]["required_artifacts"] = [".prizmkit/specs/feature/completion-summary.json"]
428
+ checkpoint = tmp_path / ".prizmkit" / "specs" / "feature" / "workflow-checkpoint.json"
429
+ checkpoint.parent.mkdir(parents=True)
430
+ _write(checkpoint, payload)
431
+
432
+ missing = load_checkpoint_state(checkpoint, project_root=tmp_path)
433
+ (checkpoint.parent / "completion-summary.json").write_text("{}", encoding="utf-8")
434
+ present = load_checkpoint_state(checkpoint, project_root=tmp_path)
435
+
436
+ assert missing.semantic_complete is False
437
+ assert missing.semantic.artifacts_valid is False
438
+ assert present.semantic_complete is True
439
+ assert present.semantic.artifacts_valid is True
440
+
441
+
442
+
443
+ def test_update_checkpoint_rejects_test_pass_when_validator_replay_fails(tmp_path, monkeypatch):
444
+ paths = _write_test_evidence(tmp_path)
445
+ payload = _family_checkpoint(
446
+ "feature-pipeline",
447
+ [
448
+ "prizmkit-implement", "prizmkit-code-review", "prizmkit-test",
449
+ "prizmkit-retrospective", "prizmkit-committer", "completion-summary",
450
+ ],
451
+ )
452
+ payload["steps"][2]["status"] = "in_progress"
453
+ for step in payload["steps"][3:]:
454
+ step["status"] = "pending"
455
+ step.pop("stage_result", None)
456
+ checkpoint = tmp_path / "workflow-checkpoint.json"
457
+ _write(checkpoint, payload)
458
+ monkeypatch.setattr(
459
+ "prizmkit_runtime.checkpoint_state._resolve_evidence_validator",
460
+ lambda _root: tmp_path / "validator.py",
461
+ )
462
+ monkeypatch.setattr(
463
+ "prizmkit_runtime.checkpoint_state._evidence_validator_passes",
464
+ lambda *_args: False,
465
+ )
466
+
467
+ result = update_checkpoint(
468
+ str(checkpoint),
469
+ "prizmkit-test",
470
+ "completed",
471
+ semantic_update={
472
+ "stage_result": "TEST_PASS",
473
+ "authoritative_evidence_paths": paths,
474
+ },
475
+ )
476
+
477
+ assert result["ok"] is False
478
+ assert "validator-attested" in result["error"]
479
+
480
+
481
+
482
+ def test_update_checkpoint_rejects_test_before_review_pass(tmp_path):
483
+ payload = _family_checkpoint(
484
+ "feature-pipeline",
485
+ [
486
+ "prizmkit-implement", "prizmkit-code-review", "prizmkit-test",
487
+ "prizmkit-retrospective", "prizmkit-committer", "completion-summary",
488
+ ],
489
+ )
490
+ payload["steps"][1]["status"] = "skipped"
491
+ payload["steps"][1].pop("stage_result", None)
492
+ payload["steps"][2]["status"] = "pending"
493
+ for step in payload["steps"][3:]:
494
+ step["status"] = "pending"
495
+ step.pop("stage_result", None)
496
+ checkpoint = _write(tmp_path / "workflow-checkpoint.json", payload)
497
+
498
+ result = update_checkpoint(str(checkpoint), "prizmkit-test", "in_progress")
499
+
500
+ assert result["ok"] is False
501
+ assert "REVIEW_PASS" in result["error"]
502
+
503
+
504
+ def test_update_checkpoint_rejects_finalization_before_test_pass(tmp_path):
505
+ payload = _family_checkpoint(
506
+ "feature-pipeline",
507
+ [
508
+ "prizmkit-implement", "prizmkit-code-review", "prizmkit-test",
509
+ "prizmkit-retrospective", "prizmkit-committer", "completion-summary",
510
+ ],
511
+ )
512
+ payload["steps"][2]["status"] = "skipped"
513
+ payload["steps"][2].pop("stage_result", None)
514
+ payload["steps"][3]["status"] = "pending"
515
+ for step in payload["steps"][4:]:
516
+ step["status"] = "pending"
517
+ step.pop("stage_result", None)
518
+ checkpoint = _write(tmp_path / "workflow-checkpoint.json", payload)
519
+
520
+ result = update_checkpoint(str(checkpoint), "prizmkit-retrospective", "in_progress")
521
+
522
+ assert result["ok"] is False
523
+ assert "TEST_PASS" in result["error"]