prizmkit 1.1.126 → 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.
- package/bundled/VERSION.json +3 -3
- package/bundled/adapters/claude/command-adapter.js +2 -75
- package/bundled/dev-pipeline/assets/skill-subagent-integration.md +14 -11
- package/bundled/dev-pipeline/prizmkit_runtime/runtime_helper.py +0 -1
- package/bundled/dev-pipeline/scripts/generate-recovery-prompt.py +3 -3
- package/bundled/dev-pipeline/templates/bootstrap-prompt.md +1 -1
- package/bundled/dev-pipeline/templates/bootstrap-tier3.md +3 -3
- package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +4 -4
- package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +3 -3
- package/bundled/dev-pipeline/templates/sections/bugfix-phase-review.md +3 -4
- package/bundled/dev-pipeline/templates/sections/phase-review-agent.md +3 -4
- package/bundled/dev-pipeline/templates/sections/phase-review-full.md +3 -4
- package/bundled/dev-pipeline/templates/sections/refactor-phase-review.md +4 -5
- package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +11 -7
- package/bundled/dev-pipeline/tests/test_runtime_helper.py +9 -3
- package/bundled/dev-pipeline/tests/test_unified_cli.py +11 -16
- package/bundled/skills/_metadata.json +3 -3
- package/bundled/skills/prizmkit-code-review/SKILL.md +54 -122
- package/bundled/skills/prizmkit-code-review/references/review-report-template.md +9 -36
- package/bundled/skills/prizmkit-code-review/scripts/render_review_report.py +21 -111
- package/package.json +1 -1
- package/src/scaffold.js +5 -16
- package/bundled/skills/prizmkit-code-review/assets/reviewer-role.json +0 -19
- 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: "
|
|
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
|
|
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,
|
|
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
|
|
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
|
|
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.
|
|
41
|
-
6. If no changes exist, append
|
|
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
|
-
|
|
39
|
+
## Phase 1: Main-Agent Review Loop
|
|
50
40
|
|
|
51
|
-
|
|
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
|
-
|
|
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
|
-
|
|
66
|
-
|
|
47
|
+
accepted_findings: 0
|
|
48
|
+
fixed_findings: 0
|
|
49
|
+
rejected_findings: 0
|
|
50
|
+
unresolved_findings: 0
|
|
67
51
|
```
|
|
68
52
|
|
|
69
|
-
|
|
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
|
|
79
|
-
|
|
80
|
-
|
|
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
|
|
84
|
-
accepted > 0 and round < 10
|
|
85
|
-
accepted > 0 at ten completed
|
|
86
|
-
|
|
87
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
79
|
+
When a round has accepted findings and fewer than ten rounds have completed:
|
|
111
80
|
|
|
112
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
-
|
|
166
|
-
-
|
|
167
|
-
|
|
168
|
-
|
|
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
|
-
|
|
102
|
+
## Phase 4: Final Verification and Result
|
|
171
103
|
|
|
172
|
-
|
|
104
|
+
Before completing:
|
|
173
105
|
|
|
174
|
-
|
|
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
|
|
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`:
|
|
193
|
-
- `NEEDS_FIXES`:
|
|
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
|
-
###
|
|
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
|
-
##
|
|
45
|
+
## Final Verification
|
|
67
46
|
|
|
68
|
-
- Status: <COMPLETED|
|
|
69
|
-
-
|
|
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
|
|
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
|
-
-
|
|
100
|
-
-
|
|
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"
|
|
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
|
-
|
|
116
|
-
|
|
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
|
-
|
|
145
|
-
|
|
146
|
-
|
|
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: {
|
|
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
|
|
240
|
-
raise ReportStateError("
|
|
241
|
-
if verdict == "
|
|
242
|
-
raise ReportStateError(
|
|
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
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
|
-
|
|
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
|
-
}
|