prizmkit 1.1.127 → 1.1.128

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 (24) hide show
  1. package/bundled/VERSION.json +3 -3
  2. package/bundled/adapters/claude/command-adapter.js +2 -75
  3. package/bundled/dev-pipeline/assets/skill-subagent-integration.md +14 -11
  4. package/bundled/dev-pipeline/prizmkit_runtime/runtime_helper.py +0 -1
  5. package/bundled/dev-pipeline/scripts/generate-recovery-prompt.py +3 -3
  6. package/bundled/dev-pipeline/templates/bootstrap-prompt.md +1 -1
  7. package/bundled/dev-pipeline/templates/bootstrap-tier3.md +3 -3
  8. package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +4 -4
  9. package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +3 -3
  10. package/bundled/dev-pipeline/templates/sections/bugfix-phase-review.md +3 -4
  11. package/bundled/dev-pipeline/templates/sections/phase-review-agent.md +3 -4
  12. package/bundled/dev-pipeline/templates/sections/phase-review-full.md +3 -4
  13. package/bundled/dev-pipeline/templates/sections/refactor-phase-review.md +4 -5
  14. package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +11 -7
  15. package/bundled/dev-pipeline/tests/test_runtime_helper.py +9 -3
  16. package/bundled/dev-pipeline/tests/test_unified_cli.py +11 -16
  17. package/bundled/skills/_metadata.json +3 -3
  18. package/bundled/skills/prizmkit-code-review/SKILL.md +54 -122
  19. package/bundled/skills/prizmkit-code-review/references/review-report-template.md +9 -36
  20. package/bundled/skills/prizmkit-code-review/scripts/render_review_report.py +21 -111
  21. package/package.json +1 -1
  22. package/src/scaffold.js +5 -16
  23. package/bundled/skills/prizmkit-code-review/assets/reviewer-role.json +0 -19
  24. package/bundled/skills/prizmkit-code-review/references/reviewer-agent-prompt.md +0 -120
@@ -1,16 +1,16 @@
1
1
  ---
2
2
  name: "prizmkit-code-review"
3
- description: "Run a risk-routed dual-layer code review against the current spec, plan, workspace changes, applicable rules, contracts, and test evidence. The Main Agent first self-reviews and repairs for up to ten rounds, then semantic risk determines whether zero, one, or two fresh read-only independent Reviewers are required. Findings remain Main-Agent adjudicated, Reviewer 3 is forbidden, and one append-only progress report records the execution through PASS, NEEDS_FIXES, or BLOCKED. (project)"
3
+ description: "Review the complete current change in a bounded Main-Agent loop. Adjudicate findings with evidence, directly repair accepted findings, verify repairs, and append progress until the review converges to PASS or stops with unresolved findings as NEEDS_FIXES. (project)"
4
4
  ---
5
5
 
6
6
  # PrizmKit Code Review
7
7
 
8
- Use a dual-layer review loop: the Main Agent owns iterative review and repair, while fresh independent Reviewers act only as semantic-risk gates.
8
+ Use one Main-Agent review loop. The Main Agent performs the complete review, filters candidate findings, repairs accepted findings, verifies the repairs, and decides the final result without delegating code review.
9
9
 
10
10
  ## When to Use
11
11
 
12
12
  - After `/prizmkit-implement` as the Full path quality gate
13
- - For Fast path when behavior, risk, or the user warrants review
13
+ - For Fast path when behavior, impact, or the user warrants review
14
14
  - When the user asks to validate implementation, find defects, assess regressions, or decide commit readiness
15
15
 
16
16
  ## Input
@@ -19,167 +19,101 @@ Use a dual-layer review loop: the Main Agent owns iterative review and repair, w
19
19
  |---|---|---|
20
20
  | `artifact_dir` | No | Directory containing `spec.md` and `plan.md`. Reuse a caller-provided directory; otherwise locate the current completed change artifact. |
21
21
 
22
- ## Required Assets
22
+ ## Required Asset
23
23
 
24
- - `${SKILL_DIR}/references/reviewer-agent-prompt.md`: independent Reviewer input and output contract
25
24
  - `${SKILL_DIR}/references/review-report-template.md`: report lifecycle and append contract
26
- - `${SKILL_DIR}/assets/reviewer-role.json`: semantic read-only and non-delegating Reviewer boundary
27
-
28
- Do not weaken or summarize the Reviewer prompt. The protocol specifies semantic capabilities rather than platform-specific tool names.
29
25
 
30
26
  ## Phase 0: Initialize Report and Collect Context
31
27
 
32
28
  1. Resolve `{artifact_dir}` and `{artifact_dir}/review-report.md`.
33
- 2. replace any prior report with a new execution header using the report template. The new report begins with `## Status: IN_PROGRESS` and contains no prior Final Result.
29
+ 2. At the start of every execution, replace any prior report with a new execution header using the report template. The new report begins with `## Status: IN_PROGRESS` and contains no prior Final Result.
34
30
  3. Read `spec.md`, `plan.md`, relevant `/prizmkit-test` evidence, `.prizmkit/prizm-docs/root.prizm`, applicable progressive docs, and project rules.
35
- 4. Inspect and capture the complete current Git change:
31
+ 4. Inspect the complete current Git change:
36
32
  - staged and unstaged tracked changes;
37
33
  - untracked files;
38
34
  - deleted and renamed files;
39
35
  - relevant unchanged callers, dependents, contracts, and tests.
40
- 5. Preserve the existing Reviewer input behavior: staged and unstaged Git diffs, full content of every untracked file, and explicit deleted/renamed states.
41
- 6. If no changes exist, append risk `low` and exactly one final result with `PASS`, then finish without a Reviewer.
42
-
43
- ### Checkout Access
44
-
45
- Prefer direct access to the active checkout. If the platform forces an isolated worktree, provide the same staged and unstaged diffs, untracked file contents, and changed-path states; use the worktree only for baseline and surrounding-context reads. Do not require workspace-equivalence proof.
46
-
47
- ## Phase 1: Semantic Risk Assessment
36
+ 5. Review in the active workspace so dirty and untracked content is authoritative.
37
+ 6. If no changes exist, append final verification and exactly one final result with `PASS`, then finish.
48
38
 
49
- Classify the current change from behavior and failure impact, not changed-file count or a fixed path allowlist:
39
+ ## Phase 1: Main-Agent Review Loop
50
40
 
51
- - `low: 0` independent Reviewers documentation, test text, mechanical change, local low-impact configuration, or trivially verifiable behavior.
52
- - `medium: 1` independent Reviewer — general business behavior, internal interface changes, or non-critical data processing with user-visible regression potential.
53
- - `high: 2` independent Reviewers maximum — payments, financial ledgers, authentication, authorization, security, migration, concurrent transactions, irreversible data operations, or public contracts.
41
+ The Main Agent reviews and repairs in the current context. The fixed limit is ten completed review rounds.
54
42
 
55
- Mixed risks use the highest applicable level. A large mechanical diff is not automatically high; a small money or authorization change is high.
56
-
57
- Append `## Risk Assessment` with the selected risk and concrete reasons before review begins.
58
-
59
- ## Phase 2: Main-Agent Self-Review Loop
60
-
61
- The Main Agent reviews and repairs in the current context. Track Main-Agent rounds independently from Reviewer launch attempts:
43
+ Track cumulative counts:
62
44
 
63
45
  ```yaml
64
46
  main_review_rounds: 0
65
- independent_reviewers_started: 0
66
- reviewer_1_accepted_high: false
47
+ accepted_findings: 0
48
+ fixed_findings: 0
49
+ rejected_findings: 0
50
+ unresolved_findings: 0
67
51
  ```
68
52
 
69
- Every Reviewer Agent launch attempt increments `independent_reviewers_started`, including a retry that starts a new Agent. The total may never exceed the semantic-risk limit.
70
-
71
- ### Main-Agent Self-Review Loop
53
+ ### Review One Round
72
54
 
73
55
  Each round examines the complete current change against goals, contracts, rules, callers, dependents, regression risks, and test evidence.
74
56
 
75
- 1. Identify concrete candidate findings.
76
- 2. Classify each as:
77
- - `accepted`: evidence supports the failure scenario;
78
- - `rejected`: code or governing evidence disproves it or its regression path.
79
- 3. Append `## Main Review Round N` with findings, accepted, rejected, and next action.
80
- 4. Apply these rules:
57
+ 1. Identify concrete candidate findings. A finding must describe a reproducible failure scenario, affected behavior, and supporting evidence.
58
+ 2. Classify each candidate as exactly one of:
59
+ - `accepted`: concrete evidence supports the failure scenario and an in-scope repair is required;
60
+ - `rejected`: code, tests, contracts, or governing evidence disproves the failure scenario;
61
+ - `unresolved`: correctness cannot be established or repaired safely with the available evidence or environment.
62
+ 3. Treat Missing tools, permissions, environment, or required evidence as an unresolved finding when they prevent required verification. Do not treat missing evidence as success.
63
+ 4. Append `## Main Review Round N` with findings, accepted, rejected, unresolved, and the next action.
64
+ 5. Apply these rules:
81
65
 
82
66
  ```text
83
- accepted = 0 -> self-review converged
84
- accepted > 0 and round < 10 -> Main Agent directly repairs, verifies, and continues
85
- accepted > 0 at ten completed Main-Agent rounds -> NEEDS_FIXES
86
- repair cannot be completed safely -> NEEDS_FIXES
87
- unresolved new in-scope test failure -> NEEDS_FIXES
67
+ accepted = 0 and unresolved = 0 -> review converged
68
+ accepted > 0 and round < 10 -> Main Agent directly repairs, verifies, and continues
69
+ accepted > 0 at ten completed review rounds -> NEEDS_FIXES
70
+ unresolved > 0 -> NEEDS_FIXES
71
+ repair cannot be completed safely -> unresolved finding -> NEEDS_FIXES
72
+ required verification fails or cannot be performed -> unresolved finding -> NEEDS_FIXES
88
73
  ```
89
74
 
90
- When all findings are rejected, `accepted = 0` and the phase converges. Main-Agent rounds never increase the independent Reviewer counter. The fixed limit is ten completed Main-Agent rounds.
75
+ When all candidate findings are rejected, `accepted = 0` and `unresolved = 0`, so the review converges. Rejected findings do not cause another round.
91
76
 
92
- After each repair batch, append `## Repair Verification` with fixed findings, verification evidence, and next phase.
93
-
94
- ## Phase 3: Independent Reviewer 1
95
-
96
- After Main-Agent self-review and required tests converge:
97
-
98
- - low risk: skip all independent Reviewers and proceed to final verification;
99
- - medium or high risk: launch Reviewer 1.
100
-
101
- Before launch, append:
102
-
103
- ```markdown
104
- ## Independent Reviewer 1
105
-
106
- - Status: RUNNING
107
- - Risk Trigger: <medium|high>
108
- ```
77
+ ## Phase 2: Repair and Verification
109
78
 
110
- Launch exactly one fresh foreground Reviewer using the unchanged prompt and role. Do not provide previous review findings, filtering decisions, rejection reasons, or repair explanations.
79
+ When a round has accepted findings and fewer than ten rounds have completed:
111
80
 
112
- ### Reviewer Infrastructure Failure
81
+ 1. Main Agent directly repairs every accepted in-scope finding in the active workspace.
82
+ 2. Run targeted tests, static checks, or other verification appropriate to each repaired behavior.
83
+ 3. Inspect resulting changes and ensure the repair did not introduce a new regression.
84
+ 4. Append `## Repair Verification` with fixed findings, verification evidence, and the next round.
85
+ 5. Start the next complete review round.
113
86
 
114
- If the Reviewer cannot start, exits abnormally, returns unusable output, or lacks essential context:
87
+ If a repair is unsafe, incomplete, or cannot receive required verification, record the affected finding as unresolved and finish with `NEEDS_FIXES`.
115
88
 
116
- 1. append the observable failure;
117
- 2. count the failed launch attempt against the semantic-risk Reviewer limit;
118
- 3. allow at most one infrastructure retry at this same Reviewer position only when the risk limit still has an unused launch;
119
- 4. append a new RUNNING retry section before retrying and increment the Reviewer launch counter;
120
- 5. if the retry fails or the risk limit is exhausted, append Final Result `BLOCKED` and stop;
121
- 6. do not convert infrastructure failure into a code finding;
122
- 7. Do not substitute Main-Agent self-review for a required independent result.
123
-
124
- ### Finding Adjudication
125
-
126
- For a usable Reviewer result, append `## Independent Reviewer 1 Result`, then classify every finding as accepted or rejected with evidence.
127
-
128
- ```text
129
- accepted = 0 -> Reviewer 1 converged
130
- accepted > 0 -> Main Agent repairs, verifies, and reruns its self-review loop
131
- ```
132
-
133
- Accepted findings do not automatically trigger another independent Reviewer.
134
-
135
- ## Phase 4: Reviewer 2 Eligibility
136
-
137
- Reviewer 2 is allowed only when every condition is true:
138
-
139
- - risk is `high`;
140
- - Reviewer 1 contained at least one accepted high-severity finding;
141
- - all accepted high findings were repaired;
142
- - targeted verification passed;
143
- - Main-Agent self-review reconverged.
144
-
145
- Accepted medium or low findings alone never trigger Reviewer 2. Medium risk never starts Reviewer 2.
146
-
147
- When eligible, append a RUNNING section and launch one fresh Reviewer 2 with the unchanged complete-review prompt and current change input.
148
-
149
- After Reviewer 2:
150
-
151
- - accepted = 0: proceed to final verification;
152
- - accepted > 0: Main Agent repairs, verifies, and runs its final self-review loop;
153
- - unresolved repair: `NEEDS_FIXES`;
154
- - Do not launch Reviewer 3 under any condition.
155
-
156
- ## Phase 5: Append-Only Reporting
89
+ ## Phase 3: Append-Only Reporting
157
90
 
158
91
  `{artifact_dir}/review-report.md` is the only required persisted review artifact.
159
92
 
160
93
  Within one execution, append new sections only. Do not rewrite an earlier progress section. Append after:
161
94
 
162
- - risk assessment;
163
95
  - every Main-Agent review round;
164
96
  - every repair and verification batch;
165
- - every Reviewer launch;
166
- - every Reviewer result and adjudication;
167
- - every infrastructure retry;
168
- - final verification.
97
+ - final verification;
98
+ - the final result.
99
+
100
+ An interrupted execution remains `IN_PROGRESS` and shows its latest completed phase. It has no terminal verdict.
169
101
 
170
- A RUNNING section is not edited after completion; append a separate result section. An interrupted execution remains `IN_PROGRESS` and shows its latest running or completed phase.
102
+ ## Phase 4: Final Verification and Result
171
103
 
172
- ## Phase 6: Final Result
104
+ Before completing:
173
105
 
174
- Append exactly one final result:
106
+ 1. Confirm the final workspace still represents the complete reviewed change.
107
+ 2. Confirm required tests and checks have credible evidence.
108
+ 3. Confirm no accepted or unresolved finding remains for `PASS`.
109
+ 4. Append `## Final Verification`.
110
+ 5. Append exactly one final result:
175
111
 
176
112
  ```markdown
177
113
  ## Final Result
178
114
 
179
- - Verdict: PASS | NEEDS_FIXES | BLOCKED
180
- - Risk: low | medium | high
115
+ - Verdict: PASS | NEEDS_FIXES
181
116
  - Main Review Rounds: <count>
182
- - Independent Reviewers Started: <count>
183
117
  - Accepted Findings: <count>
184
118
  - Fixed Findings: <count>
185
119
  - Rejected Findings: <count>
@@ -189,9 +123,8 @@ Append exactly one final result:
189
123
 
190
124
  Final outcomes:
191
125
 
192
- - `PASS`: Main-Agent review converged, every required independent review completed, and no accepted finding remains unresolved.
193
- - `NEEDS_FIXES`: Main-Agent round ten still has accepted findings, a repair is unsafe, or verification remains unresolved.
194
- - `BLOCKED`: a required independent Reviewer position failed and either its one permitted retry failed or the semantic-risk launch limit left no retry capacity; essential independent-review context is unavailable.
126
+ - `PASS`: review converged with `accepted = 0`, `unresolved = 0`, and required verification evidence is complete.
127
+ - `NEEDS_FIXES`: round ten still has accepted findings, any finding remains unresolved, a repair cannot be completed safely, or required verification is unavailable or failed.
195
128
 
196
129
  Exactly one final result is allowed. Do not append progress after Final Result.
197
130
 
@@ -199,4 +132,3 @@ Completion handoff:
199
132
 
200
133
  - `PASS`: run `/prizmkit-retrospective` when structural docs or durable knowledge changed; otherwise proceed to `/prizmkit-committer`.
201
134
  - `NEEDS_FIXES`: report unresolved findings and stop.
202
- - `BLOCKED`: report infrastructure evidence and permit recovery.
@@ -16,17 +16,6 @@ Within that execution, append sections only. Never edit or replace an earlier pr
16
16
 
17
17
  ## Progress Sections
18
18
 
19
- ### Risk Assessment
20
-
21
- ```markdown
22
- ## Risk Assessment
23
-
24
- - Risk: <low|medium|high>
25
- - Independent Reviewer Limit: <0|1|2>
26
- - Reasons:
27
- - <concrete behavioral reason>
28
- ```
29
-
30
19
  ### Main-Agent Review Round
31
20
 
32
21
  ```markdown
@@ -36,6 +25,7 @@ Within that execution, append sections only. Never edit or replace an earlier pr
36
25
  - Findings: <count>
37
26
  - Accepted: <count>
38
27
  - Rejected: <count>
28
+ - Unresolved: <count>
39
29
  - Next: <next action>
40
30
  ```
41
31
 
@@ -44,34 +34,18 @@ Within that execution, append sections only. Never edit or replace an earlier pr
44
34
  ```markdown
45
35
  ## Repair Verification
46
36
 
47
- - Source: <main|reviewer-1|reviewer-2>
48
37
  - Fixed Findings: <count>
49
38
  - Verification: <evidence summary>
50
39
  - Next: <next action>
51
40
  ```
52
41
 
53
- ### Independent Reviewer Running
54
-
55
- ```markdown
56
- ## Independent Reviewer <N>
57
-
58
- - Status: RUNNING
59
- - Risk Trigger: <medium|high>
60
- - Attempt: <1|2>
61
- ```
62
-
63
- ### Independent Reviewer Result
42
+ ### Final Verification
64
43
 
65
44
  ```markdown
66
- ## Independent Reviewer <N> Result
45
+ ## Final Verification
67
46
 
68
- - Status: <COMPLETED|BLOCKED>
69
- - Result: <PASS|FINDINGS|BLOCKED>
70
- - Findings: <count>
71
- - Accepted: <count>
72
- - Rejected: <count>
73
- - Accepted High: <count>
74
- - Next: <next action>
47
+ - Status: <COMPLETED|FAILED>
48
+ - Evidence: <evidence summary>
75
49
  ```
76
50
 
77
51
  ## Final Result
@@ -81,10 +55,8 @@ Exactly one Final Result terminates a completed execution:
81
55
  ```markdown
82
56
  ## Final Result
83
57
 
84
- - Verdict: <PASS|NEEDS_FIXES|BLOCKED>
85
- - Risk: <low|medium|high>
58
+ - Verdict: <PASS | NEEDS_FIXES>
86
59
  - Main Review Rounds: <count>
87
- - Independent Reviewers Started: <count>
88
60
  - Accepted Findings: <count>
89
61
  - Fixed Findings: <count>
90
62
  - Rejected Findings: <count>
@@ -96,8 +68,9 @@ Exactly one Final Result terminates a completed execution:
96
68
 
97
69
  - Start of a new execution removes stale progress and terminal results from prior executions.
98
70
  - A phase appends its result before the next phase starts.
99
- - Append RUNNING before each independent Reviewer launch or retry.
100
- - Do not modify a RUNNING section after completion; append its Result section.
71
+ - Finding counts satisfy `accepted + rejected + unresolved = findings`.
72
+ - `PASS` requires every accepted finding fixed and zero unresolved findings.
73
+ - `NEEDS_FIXES` requires at least one unfixed accepted or unresolved finding.
101
74
  - An IN_PROGRESS report without Final Result is incomplete.
102
75
  - Generic or incidental verdict text outside the last Final Result does not prove completion.
103
76
  - Do not append any section after Final Result.
@@ -9,15 +9,10 @@ import sys
9
9
  from pathlib import Path
10
10
  from typing import Any
11
11
 
12
- VERDICTS = {"PASS", "NEEDS_FIXES", "BLOCKED"}
13
- RISKS = {"low", "medium", "high"}
12
+ VERDICTS = {"PASS", "NEEDS_FIXES"}
14
13
  EVENTS = {
15
- "risk-assessment",
16
14
  "main-review-round",
17
15
  "repair-verification",
18
- "reviewer-running",
19
- "reviewer-result",
20
- "infrastructure-failure",
21
16
  "final-verification",
22
17
  }
23
18
  FINAL_HEADING = "## Final Result"
@@ -49,13 +44,6 @@ def _require_count(data: dict[str, Any], name: str, *, maximum: int | None = Non
49
44
  return value
50
45
 
51
46
 
52
- def _require_risk(data: dict[str, Any]) -> str:
53
- risk = data.get("risk")
54
- if risk not in RISKS:
55
- raise ReportStateError(f"risk has invalid value: {risk!r}")
56
- return risk
57
-
58
-
59
47
  def _report_text(path: Path) -> str:
60
48
  try:
61
49
  return path.read_text(encoding="utf-8")
@@ -87,24 +75,6 @@ def _render_event(data: dict[str, Any]) -> str:
87
75
  if event not in EVENTS:
88
76
  raise ReportStateError(f"event has invalid value: {event!r}")
89
77
 
90
- if event == "risk-assessment":
91
- risk = _require_risk(data)
92
- reasons = data.get("reasons")
93
- if not isinstance(reasons, list) or not reasons or not all(
94
- isinstance(reason, str) and reason.strip() for reason in reasons
95
- ):
96
- raise ReportStateError("reasons must be a non-empty string array")
97
- limit = {"low": 0, "medium": 1, "high": 2}[risk]
98
- lines = [
99
- "## Risk Assessment",
100
- "",
101
- f"- Risk: {risk}",
102
- f"- Independent Reviewer Limit: {limit}",
103
- "- Reasons:",
104
- ]
105
- lines.extend(f" - {reason.strip()}" for reason in reasons)
106
- return "\n".join(lines)
107
-
108
78
  if event == "main-review-round":
109
79
  round_number = _require_count(data, "round", maximum=10)
110
80
  if round_number < 1:
@@ -112,8 +82,11 @@ def _render_event(data: dict[str, Any]) -> str:
112
82
  findings = _require_count(data, "findings")
113
83
  accepted = _require_count(data, "accepted")
114
84
  rejected = _require_count(data, "rejected")
115
- if accepted + rejected != findings:
116
- raise ReportStateError("accepted + rejected must equal findings")
85
+ unresolved = _require_count(data, "unresolved")
86
+ if accepted + rejected + unresolved != findings:
87
+ raise ReportStateError(
88
+ "accepted + rejected + unresolved must equal findings"
89
+ )
117
90
  return "\n".join(
118
91
  [
119
92
  f"## Main Review Round {round_number}",
@@ -122,93 +95,30 @@ def _render_event(data: dict[str, Any]) -> str:
122
95
  f"- Findings: {findings}",
123
96
  f"- Accepted: {accepted}",
124
97
  f"- Rejected: {rejected}",
98
+ f"- Unresolved: {unresolved}",
125
99
  f"- Next: {_require_text(data, 'next')}",
126
100
  ]
127
101
  )
128
102
 
129
103
  if event == "repair-verification":
130
- source = _require_text(data, "source")
131
- if source not in {"main", "reviewer-1", "reviewer-2"}:
132
- raise ReportStateError(f"source has invalid value: {source!r}")
133
104
  return "\n".join(
134
105
  [
135
106
  "## Repair Verification",
136
107
  "",
137
- f"- Source: {source}",
138
108
  f"- Fixed Findings: {_require_count(data, 'fixed_findings')}",
139
109
  f"- Verification: {_require_text(data, 'verification')}",
140
110
  f"- Next: {_require_text(data, 'next')}",
141
111
  ]
142
112
  )
143
113
 
144
- if event == "reviewer-running":
145
- reviewer = _require_count(data, "reviewer", maximum=2)
146
- if reviewer < 1:
147
- raise ReportStateError("reviewer must be 1 or 2")
148
- risk = _require_risk(data)
149
- if risk == "low" or (risk == "medium" and reviewer == 2):
150
- raise ReportStateError("reviewer exceeds the semantic risk limit")
151
- attempt = data.get("attempt", 1)
152
- if attempt not in {1, 2}:
153
- raise ReportStateError("attempt must be 1 or 2")
154
- return "\n".join(
155
- [
156
- f"## Independent Reviewer {reviewer}",
157
- "",
158
- "- Status: RUNNING",
159
- f"- Risk Trigger: {risk}",
160
- f"- Attempt: {attempt}",
161
- ]
162
- )
163
-
164
- if event == "reviewer-result":
165
- reviewer = _require_count(data, "reviewer", maximum=2)
166
- if reviewer < 1:
167
- raise ReportStateError("reviewer must be 1 or 2")
168
- result = data.get("result")
169
- if result not in {"PASS", "FINDINGS", "BLOCKED"}:
170
- raise ReportStateError(f"result has invalid value: {result!r}")
171
- findings = _require_count(data, "findings")
172
- accepted = _require_count(data, "accepted")
173
- rejected = _require_count(data, "rejected")
174
- accepted_high = _require_count(data, "accepted_high")
175
- if accepted + rejected != findings or accepted_high > accepted:
176
- raise ReportStateError("reviewer finding counts are inconsistent")
177
- status = "BLOCKED" if result == "BLOCKED" else "COMPLETED"
178
- return "\n".join(
179
- [
180
- f"## Independent Reviewer {reviewer} Result",
181
- "",
182
- f"- Status: {status}",
183
- f"- Result: {result}",
184
- f"- Findings: {findings}",
185
- f"- Accepted: {accepted}",
186
- f"- Rejected: {rejected}",
187
- f"- Accepted High: {accepted_high}",
188
- f"- Next: {_require_text(data, 'next')}",
189
- ]
190
- )
191
-
192
- if event == "infrastructure-failure":
193
- reviewer = _require_count(data, "reviewer", maximum=2)
194
- attempt = _require_count(data, "attempt", maximum=2)
195
- if reviewer < 1 or attempt < 1:
196
- raise ReportStateError("reviewer and attempt must be at least 1")
197
- return "\n".join(
198
- [
199
- f"## Independent Reviewer {reviewer} Infrastructure Failure",
200
- "",
201
- f"- Attempt: {attempt}",
202
- f"- Evidence: {_require_text(data, 'evidence')}",
203
- f"- Next: {_require_text(data, 'next')}",
204
- ]
205
- )
206
-
114
+ status = _require_text(data, "status")
115
+ if status not in {"COMPLETED", "FAILED"}:
116
+ raise ReportStateError(f"status has invalid value: {status!r}")
207
117
  return "\n".join(
208
118
  [
209
119
  "## Final Verification",
210
120
  "",
211
- f"- Status: {_require_text(data, 'status')}",
121
+ f"- Status: {status}",
212
122
  f"- Evidence: {_require_text(data, 'evidence')}",
213
123
  ]
214
124
  )
@@ -227,28 +137,28 @@ def append_final_result(path: Path, data: Any) -> None:
227
137
  verdict = valid.get("verdict")
228
138
  if verdict not in VERDICTS:
229
139
  raise ReportStateError(f"verdict has invalid value: {verdict!r}")
230
- risk = _require_risk(valid)
231
140
  main_rounds = _require_count(valid, "main_review_rounds", maximum=10)
232
- reviewers = _require_count(valid, "independent_reviewers_started", maximum=2)
233
- if reviewers > {"low": 0, "medium": 1, "high": 2}[risk]:
234
- raise ReportStateError("independent_reviewers_started exceeds risk limit")
235
141
  accepted = _require_count(valid, "accepted_findings")
236
142
  fixed = _require_count(valid, "fixed_findings")
237
143
  rejected = _require_count(valid, "rejected_findings")
238
144
  unresolved = _require_count(valid, "unresolved_findings")
239
- if verdict == "PASS" and unresolved:
240
- raise ReportStateError("PASS cannot contain unresolved findings")
241
- if verdict == "NEEDS_FIXES" and not unresolved:
242
- raise ReportStateError("NEEDS_FIXES requires unresolved findings")
145
+ if fixed > accepted:
146
+ raise ReportStateError("fixed_findings cannot exceed accepted_findings")
147
+ if verdict == "PASS" and (unresolved or fixed != accepted):
148
+ raise ReportStateError(
149
+ "PASS requires every accepted finding fixed and no unresolved findings"
150
+ )
151
+ if verdict == "NEEDS_FIXES" and not unresolved and fixed == accepted:
152
+ raise ReportStateError(
153
+ "NEEDS_FIXES requires an unfixed accepted or unresolved finding"
154
+ )
243
155
 
244
156
  section = "\n".join(
245
157
  [
246
158
  FINAL_HEADING,
247
159
  "",
248
160
  f"- Verdict: {verdict}",
249
- f"- Risk: {risk}",
250
161
  f"- Main Review Rounds: {main_rounds}",
251
- f"- Independent Reviewers Started: {reviewers}",
252
162
  f"- Accepted Findings: {accepted}",
253
163
  f"- Fixed Findings: {fixed}",
254
164
  f"- Rejected Findings: {rejected}",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prizmkit",
3
- "version": "1.1.127",
3
+ "version": "1.1.128",
4
4
  "description": "Create a new PrizmKit-powered project with clean initialization — no framework dev files, just what you need.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/scaffold.js CHANGED
@@ -81,6 +81,7 @@ const RETIRED_POWERSHELL_RUNTIME_FILES = new Set([
81
81
  'lib/heartbeat.ps1',
82
82
  ]);
83
83
  const LEGACY_TEAM_NAME = ['prizm', 'dev', 'team'].join('-');
84
+ const RETIRED_CODE_REVIEW_AGENT_BASENAME = 'prizmkit-code-reviewer';
84
85
  const LEGACY_AGENT_BASENAMES = [
85
86
  `${LEGACY_TEAM_NAME}-dev`,
86
87
  `${LEGACY_TEAM_NAME}-reviewer`,
@@ -102,7 +103,10 @@ export async function removeRetiredAgentTeamArtifacts(platform, projectRoot, dry
102
103
  : path.join(projectRoot, '.codebuddy', 'agents');
103
104
  const agentExtensions = platform === 'codex' ? ['.toml', '.md'] : ['.md'];
104
105
 
105
- for (const basename of LEGACY_AGENT_BASENAMES) {
106
+ const retiredBasenames = platform === 'claude'
107
+ ? [...LEGACY_AGENT_BASENAMES, RETIRED_CODE_REVIEW_AGENT_BASENAME]
108
+ : LEGACY_AGENT_BASENAMES;
109
+ for (const basename of retiredBasenames) {
106
110
  for (const extension of agentExtensions) {
107
111
  const filePath = path.join(agentDir, `${basename}${extension}`);
108
112
  if (!await fs.pathExists(filePath)) continue;
@@ -226,12 +230,10 @@ export async function installSkills(platform, skills, projectRoot, dryRun, runti
226
230
 
227
231
  // Load Claude command adapter for skill conversion
228
232
  let convertSkillToCommand;
229
- let getClaudeSkillAgentDefinitions;
230
233
  let convertSkillToCodex;
231
234
  if (platform === 'claude') {
232
235
  const commandAdapter = await loadAdapter('claude', 'command-adapter.js');
233
236
  convertSkillToCommand = commandAdapter.convertSkillToCommand;
234
- getClaudeSkillAgentDefinitions = commandAdapter.getClaudeSkillAgentDefinitions;
235
237
  } else if (platform === 'codex') {
236
238
  const codexSkillAdapter = await loadAdapter('codex', 'skill-adapter.js');
237
239
  convertSkillToCodex = codexSkillAdapter.convertSkill;
@@ -323,19 +325,6 @@ export async function installSkills(platform, skills, projectRoot, dryRun, runti
323
325
  await fs.copy(path.join(corePath, subdir), path.join(assetTargetDir, subdir));
324
326
  }
325
327
  }
326
-
327
- const roleManifestPath = path.join(corePath, 'assets', 'reviewer-role.json');
328
- const roleManifest = await fs.pathExists(roleManifestPath)
329
- ? await fs.readJson(roleManifestPath)
330
- : null;
331
- const agentDefinitions = getClaudeSkillAgentDefinitions(skillName, roleManifest);
332
- if (agentDefinitions.length > 0) {
333
- const agentsDir = path.join(projectRoot, '.claude', 'agents');
334
- await fs.ensureDir(agentsDir);
335
- for (const definition of agentDefinitions) {
336
- await fs.writeFile(path.join(agentsDir, definition.fileName), definition.content);
337
- }
338
- }
339
328
  console.log(chalk.green(` ✓ .claude/commands/${skillName}.md`));
340
329
  } else if (platform === 'codex') {
341
330
  const content = await fs.readFile(skillMdPath, 'utf8');
@@ -1,19 +0,0 @@
1
- {
2
- "protocol_version": 2,
3
- "role_name": "prizmkit-code-reviewer",
4
- "description": "Use only as the one fresh independent read-only Reviewer for a completed /prizmkit-code-review round.",
5
- "observational_capabilities": [
6
- "read-files",
7
- "search-content",
8
- "search-paths"
9
- ],
10
- "unavailable_capabilities": [
11
- "workspace-mutation",
12
- "shell-execution",
13
- "downstream-execution-creation",
14
- "delegation-equivalent-behavior",
15
- "orchestration-reentry",
16
- "skill-invocation"
17
- ],
18
- "execution_mode": "foreground-independent-review"
19
- }