claude-dev-env 8.11.0 → 8.12.0
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/.agents/skills/e-code-review/SKILL.md +24 -71
- package/.agents/skills/e-code-review/reference/fix.md +7 -78
- package/.agents/skills/e-code-review/reference/high.md +129 -0
- package/.agents/skills/e-code-review/reference/low.md +20 -51
- package/.agents/skills/e-code-review/reference/max.md +169 -0
- package/.agents/skills/e-code-review/reference/medium.md +7 -191
- package/.agents/skills/e-code-review/reference/xhigh.md +47 -91
- package/_shared/pr-loop/scripts/fix_pr_test_proof.py +113 -12
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/fix_pr_test_proof_constants.py +5 -1
- package/_shared/pr-loop/scripts/test_fix_pr_test_proof.py +63 -3
- package/bin/codex-skill-load-block.mjs +67 -19
- package/bin/codex-skill-load-block.test.mjs +87 -25
- package/bin/install.agents-home.test.mjs +9 -9
- package/bin/install.mjs +4 -2
- package/bin/install.test.mjs +20 -0
- package/commands/sr-loop.md +3 -1
- package/hooks/blocking/pii_prevention_blocker_parts/repository_exemption.py +3 -3
- package/hooks/blocking/tests/test_repository_exemption.py +7 -0
- package/hooks/hooks_constants/code_rules_path_utils_constants.py +0 -1
- package/package.json +1 -1
- package/rules/build-needs-a-user.md +1 -1
- package/rules/testing.md +1 -1
- package/scripts/policy_lint/config/constants.py +1 -1
- package/scripts/repository_checks/tracked_private_terms.py +15 -1
- package/scripts/tests/test_policy_lint_rules_callers.py +14 -0
- package/scripts/tests/test_tracked_private_terms.py +35 -0
- package/.agents/skills/e-code-review/preflight-proposal.contract.test.mjs +0 -20
- package/.agents/skills/e-code-review/reference/effort-evaluation.md +0 -35
- package/.agents/skills/e-code-review/reference/loop.md +0 -261
- package/.agents/skills/e-code-review/reference/mode-contract.test.mjs +0 -67
- package/.agents/skills/e-code-review/reference/preflight-proposal.md +0 -75
- package/.agents/skills/e-code-review/reference/runner-selection.md +0 -40
- package/.agents/skills/e-code-review/scripts/config/e_code_review_effort_constants/__init__.py +0 -41
- package/.agents/skills/e-code-review/scripts/config/e_code_review_effort_constants/effort_constants.py +0 -40
- package/.agents/skills/e-code-review/scripts/e_code_review_scripts_constants/__init__.py +0 -1
- package/.agents/skills/e-code-review/scripts/e_code_review_scripts_constants/finding_pipeline_constants.py +0 -49
- package/.agents/skills/e-code-review/scripts/e_code_review_scripts_constants/grok_code_review_constants.py +0 -55
- package/.agents/skills/e-code-review/scripts/effort_defaults_evidence.json +0 -186
- package/.agents/skills/e-code-review/scripts/effort_evaluation.py +0 -362
- package/.agents/skills/e-code-review/scripts/finding_pipeline.py +0 -140
- package/.agents/skills/e-code-review/scripts/fixtures/demanding.json +0 -26
- package/.agents/skills/e-code-review/scripts/fixtures/easy.json +0 -14
- package/.agents/skills/e-code-review/scripts/fixtures/medium.json +0 -20
- package/.agents/skills/e-code-review/scripts/grok_code_review.py +0 -230
- package/.agents/skills/e-code-review/scripts/test_effort_evaluation.py +0 -180
- package/.agents/skills/e-code-review/scripts/test_finding_pipeline.py +0 -197
- package/.agents/skills/e-code-review/scripts/test_grok_code_review.py +0 -289
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import hashlib
|
|
6
|
+
import subprocess
|
|
6
7
|
import sys
|
|
7
8
|
from pathlib import Path
|
|
8
9
|
|
|
@@ -69,3 +70,37 @@ def test_should_pass_a_tree_that_names_no_private_organization(
|
|
|
69
70
|
exit_code, stdout_text, _stderr_text = run_policy(repository_root)
|
|
70
71
|
assert exit_code == SUCCESS_EXIT_CODE
|
|
71
72
|
assert stdout_text == ""
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def test_should_pass_a_repository_the_named_organization_owns(
|
|
76
|
+
tmp_path: Path,
|
|
77
|
+
) -> None:
|
|
78
|
+
repository_root = tmp_path / "repo"
|
|
79
|
+
initialize_repository(repository_root)
|
|
80
|
+
subprocess.run(
|
|
81
|
+
["git", "remote", "add", "origin", "https://github.com/AcmeWidget/app.git"],
|
|
82
|
+
cwd=repository_root,
|
|
83
|
+
check=True,
|
|
84
|
+
)
|
|
85
|
+
write_text(repository_root / "docs" / "notes.md", "Built by Acme Widgets.\n")
|
|
86
|
+
commit_tracked_files(repository_root)
|
|
87
|
+
exit_code, stdout_text, _stderr_text = run_policy(repository_root)
|
|
88
|
+
assert exit_code == SUCCESS_EXIT_CODE
|
|
89
|
+
assert stdout_text == ""
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def test_should_flag_a_repository_another_owner_holds(
|
|
93
|
+
tmp_path: Path,
|
|
94
|
+
) -> None:
|
|
95
|
+
repository_root = tmp_path / "repo"
|
|
96
|
+
initialize_repository(repository_root)
|
|
97
|
+
subprocess.run(
|
|
98
|
+
["git", "remote", "add", "origin", "https://github.com/someone/app.git"],
|
|
99
|
+
cwd=repository_root,
|
|
100
|
+
check=True,
|
|
101
|
+
)
|
|
102
|
+
write_text(repository_root / "docs" / "notes.md", "Built by Acme Widgets.\n")
|
|
103
|
+
commit_tracked_files(repository_root)
|
|
104
|
+
exit_code, stdout_text, _stderr_text = run_policy(repository_root)
|
|
105
|
+
assert exit_code == FINDINGS_EXIT_CODE
|
|
106
|
+
assert f"{CHECK_ID_TRACKED_PRIVATE_TERMS}: docs/notes.md:" in stdout_text
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import assert from 'node:assert/strict'
|
|
2
|
-
import { readFileSync } from 'node:fs'
|
|
3
|
-
import { dirname, resolve } from 'node:path'
|
|
4
|
-
import test from 'node:test'
|
|
5
|
-
import { fileURLToPath } from 'node:url'
|
|
6
|
-
|
|
7
|
-
const here = dirname(fileURLToPath(import.meta.url))
|
|
8
|
-
const skill = readFileSync(resolve(here, 'SKILL.md'), 'utf8')
|
|
9
|
-
const contract = readFileSync(resolve(here, 'reference/preflight-proposal.md'), 'utf8')
|
|
10
|
-
|
|
11
|
-
test('e-code-review owns its preflight proposal contract', () => {
|
|
12
|
-
assert.match(skill, /reference\/preflight-proposal\.md/)
|
|
13
|
-
assert.doesNotMatch(skill, /_shared\/pr-loop/)
|
|
14
|
-
assert.match(contract, /caller-supplied isolated worktree/)
|
|
15
|
-
assert.match(contract, /exact `base_sha\.\.\.head_sha` range/)
|
|
16
|
-
assert.match(contract, /immutable proposal identity/)
|
|
17
|
-
assert.match(contract, /selected or dispositioned proposal collection/)
|
|
18
|
-
assert.match(contract, /review_level: low \| medium \| xhigh/)
|
|
19
|
-
assert.match(contract, /outcome: fixed \| no_change_needed \| skipped/)
|
|
20
|
-
})
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
# Effort evaluation sweep (Opus)
|
|
2
|
-
|
|
3
|
-
Offline-first harness for choosing e-code-review effort and publishing cited skill defaults.
|
|
4
|
-
|
|
5
|
-
## What it holds
|
|
6
|
-
|
|
7
|
-
| Piece | Path |
|
|
8
|
-
|---|---|
|
|
9
|
-
| Fixtures | `scripts/fixtures/{easy,medium,demanding}.json` |
|
|
10
|
-
| Schema + recommend | `scripts/effort_evaluation.py` |
|
|
11
|
-
| Constants | `scripts/config/e_code_review_effort_constants/` |
|
|
12
|
-
| Tests | `scripts/test_effort_evaluation.py` |
|
|
13
|
-
|
|
14
|
-
## How to run offline tests
|
|
15
|
-
|
|
16
|
-
```
|
|
17
|
-
python -m pytest packages/claude-dev-env/.agents/skills/e-code-review/scripts/test_effort_evaluation.py -q
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
## Skill defaults (OP-02C — e-code-review family)
|
|
21
|
-
|
|
22
|
-
Committed evidence: `scripts/effort_defaults_evidence.json`.
|
|
23
|
-
|
|
24
|
-
- `resolve_skill_effort_for_band("easy"|"medium"|"demanding")` → `low`|`medium`|`xhigh`
|
|
25
|
-
- Evaluation `high` / `max` map to skill `xhigh` (skill surface has three levels only)
|
|
26
|
-
- Every skill default cites a completed evaluation row with `thinking_enabled: true`
|
|
27
|
-
|
|
28
|
-
## Paid / live runs (optional)
|
|
29
|
-
|
|
30
|
-
1. For each fixture, run the matching e-code-review level at each CLI-supported effort (`low` … `max`) with thinking on.
|
|
31
|
-
2. Score quality, finding recall, finding precision; record visible tokens and latency.
|
|
32
|
-
3. Feed completed rows into `recommend_effort_by_band` and `skill_defaults_from_recommendation`.
|
|
33
|
-
4. Replace `effort_defaults_evidence.json` when live rows supersede the offline baseline.
|
|
34
|
-
|
|
35
|
-
Stop if the Opus 5 CLI model is unavailable, or if results cannot separate quality from cost/latency.
|
|
@@ -1,261 +0,0 @@
|
|
|
1
|
-
# Loop until clean
|
|
2
|
-
|
|
3
|
-
## Preflight-proposal mode
|
|
4
|
-
|
|
5
|
-
When the hub selects `preflight-proposal`, continue the review loop with the established proposal context. Proposal mode ends with proposal evidence. Normal mode keeps its GitHub disclosure and Ready actions.
|
|
6
|
-
|
|
7
|
-
## Act
|
|
8
|
-
|
|
9
|
-
`loop` on the hub command authorizes the full cycle. After the effort level procedure returns findings, run the gate sequence below immediately.
|
|
10
|
-
|
|
11
|
-
Do not ask whether to fix, which nits to keep, whether to commit or push, or whether to re-review. Do not open a plan fork. Do not end the turn on a recommendation.
|
|
12
|
-
|
|
13
|
-
Report progress while you work. Stop for the user only on a terminal outcome below.
|
|
14
|
-
|
|
15
|
-
## Where fixes come from
|
|
16
|
-
|
|
17
|
-
A round always applies fixes. Gate 2 below is the only place a round applies a
|
|
18
|
-
fix. `--fix` chooses the mechanics. With the flag, Gate 2 loads
|
|
19
|
-
`reference\fix.md` (relative to this skill's folder) for which agent applies
|
|
20
|
-
each fix, agent resume, the code-rules gate, skip logging, and outcome
|
|
21
|
-
reporting. Without the flag, this session applies each fix itself.
|
|
22
|
-
|
|
23
|
-
The gate sequence still decides whether a round fixes, commits, pushes, and
|
|
24
|
-
re-reviews.
|
|
25
|
-
|
|
26
|
-
## Scope stays narrow
|
|
27
|
-
|
|
28
|
-
Auto-fix only verified findings on the review target. Leave deferred PR-body follow-ups and unrelated refactors alone.
|
|
29
|
-
|
|
30
|
-
## How to class each finding
|
|
31
|
-
|
|
32
|
-
Every retained finding carries a verified `severity` and a verification
|
|
33
|
-
`verdict` (`CONFIRMED` or `PLAUSIBLE`). The frozen severity set is exactly
|
|
34
|
-
`blocker`, `high`, `medium`, `low`, `nit`.
|
|
35
|
-
|
|
36
|
-
A finding is a `nit` only when that severity is `nit`. Runtime-correctness,
|
|
37
|
-
security, data-loss, compatibility, and every other non-nit finding is a
|
|
38
|
-
`bug`.
|
|
39
|
-
|
|
40
|
-
A finding that lacks severity is **unclassified**. Consult the assigned
|
|
41
|
-
advisor to classify it before Gate 2. When that advisor is unreachable,
|
|
42
|
-
terminate with `advisor_blocked` and preserve draft state.
|
|
43
|
-
|
|
44
|
-
A finding this document has already classed keeps that class at every level. An
|
|
45
|
-
on-target shape-reader break is `bug` under *A shape change names its readers*;
|
|
46
|
-
no advisor call reopens that.
|
|
47
|
-
|
|
48
|
-
## Required checks
|
|
49
|
-
|
|
50
|
-
"Run required checks" means: run
|
|
51
|
-
`python ~/.claude/_shared/pr-loop/scripts/code_rules_gate.py --repo-root <repo root>`
|
|
52
|
-
with no file paths and no `--only-under` prefix. The `python` prefix is
|
|
53
|
-
required. On Windows a bare `.py` path opens the file in Cursor, which then
|
|
54
|
-
crashes on the gate flags. On a violation on lines this
|
|
55
|
-
round already owns, fix it and re-run the exact same command until clean. A
|
|
56
|
-
violation outside the review target is reported or skipped, not force-fixed into
|
|
57
|
-
unrelated files, and the skip is logged with path and reason.
|
|
58
|
-
|
|
59
|
-
That bare call gates the git diff since the merge-base (and any staged added
|
|
60
|
-
lines the gate already includes). Working-tree lines that are neither staged
|
|
61
|
-
nor committed sit outside that scope until they are staged or committed. Gate 2
|
|
62
|
-
leaves its edits uncommitted, so the round tail stages those edits before
|
|
63
|
-
required checks when this round produced edits.
|
|
64
|
-
|
|
65
|
-
Two failure scenarios keep the call bare. A file path named on the command line
|
|
66
|
-
puts the gate in whole-file scope on that file: a CODE_RULES violation on a line
|
|
67
|
-
this round never touched fails the round and churns the loop. An `--only-under`
|
|
68
|
-
prefix that matches nothing in the diff leaves the gate zero files to inspect and
|
|
69
|
-
exits clean, so a run that inspected nothing reads as a pass.
|
|
70
|
-
|
|
71
|
-
## Each round reviews new code
|
|
72
|
-
|
|
73
|
-
A repair diff is new code. From the second round on, the round runs the level
|
|
74
|
-
file end to end at the new head. End to end means that file's review phases, up
|
|
75
|
-
to and including its findings report; the round stops there and brings those
|
|
76
|
-
findings back to the gate sequence below. It does not run the level file's
|
|
77
|
-
*Looping* section. That section hands control to this document, and the round
|
|
78
|
-
is already inside it. The round's scope is the level's own review
|
|
79
|
-
target, the diff or path the level gathers up front, called Phase 0 in
|
|
80
|
-
`medium.md` and `xhigh.md`, taken against that target's base. A repair edit
|
|
81
|
-
landing outside that target widens the next round's scope to cover it: the next
|
|
82
|
-
round's review target is the original target **plus** that path, and the round
|
|
83
|
-
reviews both. A later widening adds to that target the same way.
|
|
84
|
-
|
|
85
|
-
The widened target is what the round hands the level file. When a round runs the
|
|
86
|
-
level file end to end, it passes the current review target (the original target
|
|
87
|
-
plus every path a widening has since added) as that run's target argument, in
|
|
88
|
-
place of the argument the first round was given. When the first round was given
|
|
89
|
-
no target argument, the original target is the item `default-range`, the level
|
|
90
|
-
file's own default gather, so the widened target is `default-range` plus every
|
|
91
|
-
added path, and the range the first round reviewed stays in scope. The level
|
|
92
|
-
file gathers what the round hands it, so a widened path is gathered and reviewed
|
|
93
|
-
like any other part of the target.
|
|
94
|
-
|
|
95
|
-
## Dangerous diffs take two full rounds
|
|
96
|
-
|
|
97
|
-
A diff is dangerous when it touches deletion paths, locks or other concurrency
|
|
98
|
-
control, or shared mutable state. A deletion path is a runtime path that removes
|
|
99
|
-
data or files; a dead-code cleanup is not one. Each round names whether the diff
|
|
100
|
-
it reviewed is dangerous. A dangerous diff holds the loop open until two full
|
|
101
|
-
rounds have reviewed it. A repair that rewrites the dangerous surface restarts
|
|
102
|
-
the two-round count at the first round that reviews the rewritten surface.
|
|
103
|
-
|
|
104
|
-
The round's progress report is where both facts are recorded: the dangerous
|
|
105
|
-
classification, and the dangerous-round count written as `N of M`.
|
|
106
|
-
|
|
107
|
-
## A shape change names its readers
|
|
108
|
-
|
|
109
|
-
When a repair changes a key, an identifier format, or a data shape, list every
|
|
110
|
-
reader of the shape it changed and state how each one reads the new shape. The
|
|
111
|
-
list goes in the round's progress report.
|
|
112
|
-
|
|
113
|
-
The round that follows a posted list checks each reader on that list against the
|
|
114
|
-
new shape and names each reader with its result in that round's progress report.
|
|
115
|
-
|
|
116
|
-
Discharge then turns on where the reader sits.
|
|
117
|
-
|
|
118
|
-
- An **off-target** reader discharges once it is named with a result. This
|
|
119
|
-
branch cannot repair it.
|
|
120
|
-
- An **on-target** reader that reads the new shape correctly discharges on that
|
|
121
|
-
result.
|
|
122
|
-
- An **on-target** reader that reads the new shape wrong is a bug-severity
|
|
123
|
-
finding of the round that checked it. It joins that round's findings, and it
|
|
124
|
-
discharges on exactly one of three results, each of them an outcome gate 2
|
|
125
|
-
already produces: it is repaired, it is recorded as a skipped finding, or the
|
|
126
|
-
advisor refutes it. Naming the break discharges nothing on its own, and
|
|
127
|
-
neither does a further round merely happening.
|
|
128
|
-
|
|
129
|
-
The list discharges once every reader on it has discharged.
|
|
130
|
-
|
|
131
|
-
A broken reader outside the review target does not block the loop and does not
|
|
132
|
-
widen scope. Hand it off as a reported finding. Two separate things are owed for
|
|
133
|
-
that hand-off, and they land at different times:
|
|
134
|
-
|
|
135
|
-
- **The round-scoped record.** What a round produces. Check the reader, record
|
|
136
|
-
its result, and name it in that round's progress report. All three are done
|
|
137
|
-
inside the round that checks the reader, and nothing outside that round is
|
|
138
|
-
needed to complete them. This is the record gate 2 reads.
|
|
139
|
-
- **The termination-time disclosure.** What terminating requires. The
|
|
140
|
-
ready-for-review message names every broken off-target reader and every
|
|
141
|
-
skipped finding that still exists, and the pull request body carries the same
|
|
142
|
-
names when the target is a pull request. A target with no pull request owes
|
|
143
|
-
the ready message alone. Gate 3 enforces this at the moment the loop
|
|
144
|
-
terminates; no earlier round owes it.
|
|
145
|
-
|
|
146
|
-
## Terminal outcomes
|
|
147
|
-
|
|
148
|
-
The loop emits exactly one of these terminals when it stops:
|
|
149
|
-
|
|
150
|
-
| Terminal | When |
|
|
151
|
-
|---|---|
|
|
152
|
-
| `clean` | Zero retained findings on the current head, and required checks pass |
|
|
153
|
-
| `nits_fixed` | Every retained finding is a nit with severity and a retained verdict, every nit is fixed, and required checks pass |
|
|
154
|
-
| `advisor_blocked` | Classification needs the assigned advisor and that advisor is unreachable |
|
|
155
|
-
|
|
156
|
-
Every round does this round's own work first, then runs the three gates below,
|
|
157
|
-
in order: gate 1, then gate 2, then gate 3.
|
|
158
|
-
|
|
159
|
-
**This round's work, before the gates.** Record this round's dangerous
|
|
160
|
-
classification and the dangerous-round count as `N of M`; and when a shape-change
|
|
161
|
-
list is open, check each reader on that list and name each reader with its
|
|
162
|
-
result, adding any on-target reader that reads the new shape wrong to this
|
|
163
|
-
round's findings as *A shape change names its readers* directs. Then run the
|
|
164
|
-
gates.
|
|
165
|
-
|
|
166
|
-
**Gate 1, obligations.** Gate 1 is evaluated first in the sequence, and its
|
|
167
|
-
answer turns on the round's open obligations alone. The findings are in hand by
|
|
168
|
-
now, and no content they carry changes it. Ask only: does any obligation remain
|
|
169
|
-
open? Two kinds exist.
|
|
170
|
-
|
|
171
|
-
- A dangerous diff that has had fewer than two full rounds.
|
|
172
|
-
- A posted shape-change list that no round has discharged.
|
|
173
|
-
|
|
174
|
-
Gate 1 states its answer and stops there: an obligation remains open, or none
|
|
175
|
-
does. It states no re-entry, no continuation, and no routing. Gate 3 is the sole
|
|
176
|
-
router. Every path out of a round passes through it.
|
|
177
|
-
|
|
178
|
-
**Gate 2, findings.** When `--fix` is set, load `reference\fix.md` here and
|
|
179
|
-
follow it for the mechanics of every fix this gate applies: the fix agent,
|
|
180
|
-
agent resume, the code-rules gate, skip logging, and outcome reporting. When `--fix` is
|
|
181
|
-
absent, apply each fix in this session yourself, and log each skip in this
|
|
182
|
-
round's progress report. Then take the one case that matches the round's
|
|
183
|
-
findings.
|
|
184
|
-
|
|
185
|
-
- Any bug-severity finding: validate each bug with an advisor before touching
|
|
186
|
-
code. Confirm the bug exists and confirm the intended fix, then fix every
|
|
187
|
-
validated bug and every nit on the review target. A refuted bug removes only
|
|
188
|
-
itself from the round's work; the nits are fixed either way.
|
|
189
|
-
- Nits only, with at least one nit present: fix all of them on the review
|
|
190
|
-
target.
|
|
191
|
-
- No findings at all: make no edits.
|
|
192
|
-
|
|
193
|
-
Gate 2 then ends by stating one of exactly two outcomes: unresolved findings
|
|
194
|
-
remain, or none remain. A refuted bug is resolved. A fixed nit is resolved. A
|
|
195
|
-
fixed validated bug is resolved. A handed-off off-target finding is resolved once
|
|
196
|
-
this round has made its round-scoped record as *A shape change names its readers*
|
|
197
|
-
defines that record (checked, result recorded, named in this round's progress
|
|
198
|
-
report), whether or not the problem behind it is solved. Gate 2 reads the record
|
|
199
|
-
and nothing else; the termination-time disclosure belongs to gate 3.
|
|
200
|
-
|
|
201
|
-
A skipped finding, a finding deliberately not applied because fixing it would
|
|
202
|
-
change intended behavior, would reach beyond the review target, or the finding
|
|
203
|
-
itself is judged a false positive, is resolved once its skip is logged in this
|
|
204
|
-
round's progress report, naming the finding and the reason it was skipped. That
|
|
205
|
-
report is the sink every run has, with or without `--fix`. When `--fix` is set,
|
|
206
|
-
the skip handling `fix.md` carries runs inside this gate and adds to this log
|
|
207
|
-
rather than replacing it.
|
|
208
|
-
|
|
209
|
-
Gate 3 reads that stated outcome, never a case label.
|
|
210
|
-
|
|
211
|
-
**Gate 3, exit test.** Resolve the terminal from the table above, then stop or
|
|
212
|
-
continue:
|
|
213
|
-
|
|
214
|
-
- zero retained findings and required checks pass → `clean`;
|
|
215
|
-
- nits only (each with severity and a retained verdict), all fixed, required checks pass → `nits_fixed`;
|
|
216
|
-
- advisor needed for classification and unreachable → `advisor_blocked`;
|
|
217
|
-
- otherwise continue.
|
|
218
|
-
|
|
219
|
-
Also require, for `clean` and `nits_fixed`:
|
|
220
|
-
|
|
221
|
-
- gate 1 shows no open obligation;
|
|
222
|
-
- gate 2 states no unresolved findings remain;
|
|
223
|
-
- this round produced no edits after the gates settled.
|
|
224
|
-
|
|
225
|
-
Any other combination runs the round tail and re-enters the loop.
|
|
226
|
-
|
|
227
|
-
Terminating with `clean` or `nits_fixed` carries one further condition, the
|
|
228
|
-
termination-time disclosure: the ready-for-review message names every broken
|
|
229
|
-
off-target reader and every skipped finding that still exists. When the target
|
|
230
|
-
is a pull request, the pull request body carries the same names; a target with
|
|
231
|
-
no pull request owes the ready message alone. Every surface this condition
|
|
232
|
-
names is written at termination, the ready message always, the pull request
|
|
233
|
-
body too when the target is a pull request, so each one is available to the
|
|
234
|
-
terminating round. A round that cannot name them does not terminate; it runs
|
|
235
|
-
the round tail and re-enters the loop, the same as any other non-terminating
|
|
236
|
-
round. With that condition met, post the proof-of-work PR comment when the
|
|
237
|
-
target is a PR, then run `gh pr ready` for a draft PR, or state ready
|
|
238
|
-
otherwise.
|
|
239
|
-
|
|
240
|
-
`advisor_blocked` keeps the pull request draft. It does
|
|
241
|
-
not run `gh pr ready`. It reports every surviving structured finding.
|
|
242
|
-
|
|
243
|
-
Gate 3 points at gate 1 for the obligation answer. It does not restate the
|
|
244
|
-
two-round rule or the shape-reader rule; each of those keeps its one home in its
|
|
245
|
-
own section above.
|
|
246
|
-
|
|
247
|
-
**The round tail.** Every round runs required checks here, in the one form
|
|
248
|
-
*Required checks* gives: the bare command, no file paths. When this round
|
|
249
|
-
produced edits, stage those edits first so they enter the bare gate's scope,
|
|
250
|
-
then run the checks. When this round produced no edits, run the same checks.
|
|
251
|
-
Should those checks produce repairs, this round has produced edits. Stage
|
|
252
|
-
them and re-run the checks.
|
|
253
|
-
|
|
254
|
-
**Commit and push are lead-owned.** Gate 2 and the round tail leave every fix
|
|
255
|
-
unstaged-or-staged in the working tree for the lead that owns the branch. A
|
|
256
|
-
fix agent, patch worker, or resumed finding agent never creates the commit and
|
|
257
|
-
never pushes. The lead stages, commits once per review round, and pushes after
|
|
258
|
-
the gates pass. Start the next round under *Each round reviews new code* only
|
|
259
|
-
after that lead commit lands a new head.
|
|
260
|
-
|
|
261
|
-
Do not drop findings to force ready. Without `loop`, run one review at the selected level, fix, and return every validated finding.
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import assert from 'node:assert/strict'
|
|
2
|
-
import { readFileSync } from 'node:fs'
|
|
3
|
-
import test from 'node:test'
|
|
4
|
-
|
|
5
|
-
const proposalSource = readFileSync(new URL('./preflight-proposal.md', import.meta.url), 'utf8')
|
|
6
|
-
const fixSource = readFileSync(new URL('./fix.md', import.meta.url), 'utf8')
|
|
7
|
-
const loopSource = readFileSync(new URL('./loop.md', import.meta.url), 'utf8')
|
|
8
|
-
|
|
9
|
-
function sourceBetweenHeadings(source, fromHeading, toHeading) {
|
|
10
|
-
const fromOffset = source.indexOf(fromHeading)
|
|
11
|
-
const toOffset = source.indexOf(toHeading, fromOffset)
|
|
12
|
-
|
|
13
|
-
assert.ok(fromOffset >= 0)
|
|
14
|
-
assert.ok(toOffset > fromOffset)
|
|
15
|
-
|
|
16
|
-
return source.slice(fromOffset, toOffset)
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function assertReviewLevelExtension() {
|
|
20
|
-
assert.match(proposalSource, /<review_level> --fix loop/)
|
|
21
|
-
const allReviewLevelMappings = [
|
|
22
|
-
['Omitted override', 'low'],
|
|
23
|
-
['`low`', 'low'],
|
|
24
|
-
['`medium`', 'medium'],
|
|
25
|
-
['`xhigh`', 'xhigh'],
|
|
26
|
-
]
|
|
27
|
-
|
|
28
|
-
for (const [eachCallerSelection, eachLevel] of allReviewLevelMappings) {
|
|
29
|
-
const expectedRow = `| ${eachCallerSelection} | \`${eachLevel}\` |`
|
|
30
|
-
assert.match(proposalSource, new RegExp(expectedRow.replaceAll('|', '\\|')))
|
|
31
|
-
}
|
|
32
|
-
assert.match(proposalSource, /`review_level` evidence mirrors the resolved `--level` value/)
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function assertProposalHandoffs() {
|
|
36
|
-
assert.match(proposalSource, /This file owns the proposal contract for `e-code-review`/)
|
|
37
|
-
assert.match(proposalSource, /exact `base_sha\.\.\.head_sha` range/)
|
|
38
|
-
const fixModeSource = sourceBetweenHeadings(
|
|
39
|
-
fixSource,
|
|
40
|
-
'## Preflight-proposal mode',
|
|
41
|
-
'## Resume the finding agent',
|
|
42
|
-
)
|
|
43
|
-
assert.match(fixModeSource, /consume the established proposal context/)
|
|
44
|
-
assert.doesNotMatch(fixModeSource, /follow \[preflight-proposal.md\]/)
|
|
45
|
-
const proposalModeSource = sourceBetweenHeadings(
|
|
46
|
-
loopSource,
|
|
47
|
-
'## Preflight-proposal mode',
|
|
48
|
-
'## Act',
|
|
49
|
-
)
|
|
50
|
-
assert.match(proposalModeSource, /continue the review loop with the established proposal context/)
|
|
51
|
-
assert.doesNotMatch(proposalModeSource, /follow \[preflight-proposal.md\]/)
|
|
52
|
-
assert.match(proposalModeSource, /Proposal mode ends with proposal evidence/)
|
|
53
|
-
assert.doesNotMatch(proposalModeSource, /proof-of-work PR comment|gh pr ready/)
|
|
54
|
-
assert.doesNotMatch(proposalSource, /proof-of-work PR comment|gh pr ready/)
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function assertNormalTerminationContract() {
|
|
58
|
-
const normalTerminalSource = loopSource.slice(loopSource.indexOf('## Terminal outcomes'))
|
|
59
|
-
assert.match(normalTerminalSource, /proof-of-work PR comment/)
|
|
60
|
-
assert.match(normalTerminalSource, /gh pr ready/)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
test('preflight proposal mode isolates review loops and preserves normal termination behavior', () => {
|
|
64
|
-
assertReviewLevelExtension()
|
|
65
|
-
assertProposalHandoffs()
|
|
66
|
-
assertNormalTerminationContract()
|
|
67
|
-
})
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
# Review preflight proposal mode
|
|
2
|
-
|
|
3
|
-
This file owns the proposal contract for `e-code-review`.
|
|
4
|
-
|
|
5
|
-
Use this review mode when the caller selects `preflight-proposal`:
|
|
6
|
-
|
|
7
|
-
```text
|
|
8
|
-
/e-code-review preflight-proposal <pr_number> --level low --base-sha <base_sha> --head-sha <head_sha> --worktree <isolated_worktree>
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Required inputs
|
|
12
|
-
|
|
13
|
-
| Input | Contract |
|
|
14
|
-
|---|---|
|
|
15
|
-
| `pr_number` | Resolved open pull-request number |
|
|
16
|
-
| `--level` | Resolved review level: `low`, `medium`, or `xhigh` |
|
|
17
|
-
| `--base-sha` | Full immutable base commit SHA |
|
|
18
|
-
| `--head-sha` | Full immutable head commit SHA |
|
|
19
|
-
| `--worktree` | Caller-supplied isolated worktree path |
|
|
20
|
-
|
|
21
|
-
## Proposal contract
|
|
22
|
-
|
|
23
|
-
1. Validate every required input before the first review command.
|
|
24
|
-
2. Run `git rev-parse HEAD` in the supplied worktree and require exact equality with the head SHA.
|
|
25
|
-
3. Gather changed paths and review scope from the exact `base_sha...head_sha` range. Use the resolved pull-request number for pull-request metadata.
|
|
26
|
-
4. Run the complete selected review and findings against the immutable range and worktree.
|
|
27
|
-
5. Keep every review edit and test inside the caller-supplied isolated worktree.
|
|
28
|
-
6. Create an immutable proposal identity. Use the existing commit SHA for committed proposals. For working-tree edits, use a deterministic diff hash over the baseline `HEAD` SHA, base SHA, head SHA, sorted normalized changed paths, status records, and file bytes.
|
|
29
|
-
7. Record every changed path, including tracked, untracked, renamed, and deleted paths.
|
|
30
|
-
8. Record exact tests and outcomes: each test command, exit code, and outcome.
|
|
31
|
-
9. Return selected-candidate-ready proposal evidence with the proposal ID, isolated worktree path, changed paths, findings, tests, and outcomes.
|
|
32
|
-
10. Keep commit, push, pull-request body, pull-request comment, pull-request review, pull-request update, merge, rebase, and Ready-state mutations disabled.
|
|
33
|
-
11. Return the proposal for downstream disposition. The downstream owner adds the proposal ID to its selected or dispositioned proposal collection. Reapplication uses exactly the selected records and their changed paths. Give each later finding a new proposal ID and evidence record.
|
|
34
|
-
|
|
35
|
-
## Review extension
|
|
36
|
-
|
|
37
|
-
The caller resolves the review level before invocation and always passes `--level`. Use this mapping:
|
|
38
|
-
|
|
39
|
-
| Caller selection | Resolved `--level` |
|
|
40
|
-
|---|---|
|
|
41
|
-
| Omitted override | `low` |
|
|
42
|
-
| `low` | `low` |
|
|
43
|
-
| `medium` | `medium` |
|
|
44
|
-
| `xhigh` | `xhigh` |
|
|
45
|
-
|
|
46
|
-
The `review_level` evidence mirrors the resolved `--level` value.
|
|
47
|
-
|
|
48
|
-
Run the selected level as `<review_level> --fix loop`. The selected level owns its normal finding and fix rules. Require `HEAD` to equal the supplied head SHA before each round.
|
|
49
|
-
|
|
50
|
-
Keep Gate 1, Gate 2, the bare code-rules gate, and exact required tests.
|
|
51
|
-
|
|
52
|
-
## Evidence record
|
|
53
|
-
|
|
54
|
-
```yaml
|
|
55
|
-
mode: preflight-proposal
|
|
56
|
-
pr_number: <resolved PR number>
|
|
57
|
-
review_level: low | medium | xhigh
|
|
58
|
-
base_sha: <immutable base SHA>
|
|
59
|
-
head_sha: <immutable head SHA>
|
|
60
|
-
proposal_id:
|
|
61
|
-
kind: commit-sha | diff-sha256
|
|
62
|
-
value: <immutable identity>
|
|
63
|
-
isolated_worktree: <caller-supplied path>
|
|
64
|
-
changed_paths:
|
|
65
|
-
- <normalized path>
|
|
66
|
-
findings:
|
|
67
|
-
- severity: blocker | high | medium | low | nit
|
|
68
|
-
verdict: CONFIRMED | PLAUSIBLE
|
|
69
|
-
outcome: fixed | no_change_needed | skipped
|
|
70
|
-
tests:
|
|
71
|
-
- command: <exact command>
|
|
72
|
-
exit_code: <integer>
|
|
73
|
-
outcome: <exact outcome>
|
|
74
|
-
downstream_selection: required
|
|
75
|
-
```
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
# Runner selection (medium review)
|
|
2
|
-
|
|
3
|
-
How `/e-code-review medium` (and loop) picks a harness runner for finder and
|
|
4
|
-
verify work. `SKILL.md` points here.
|
|
5
|
-
|
|
6
|
-
## What lives here
|
|
7
|
-
|
|
8
|
-
| Topic | Content |
|
|
9
|
-
|---|---|
|
|
10
|
-
| Goal | One skill surface, many runners (Grok, Codex, Claude headless, and others) |
|
|
11
|
-
| Today | `scripts/grok_code_review.py` is the Grok medium orchestration module |
|
|
12
|
-
| Target | A thin selector chooses a runner by availability and task flags |
|
|
13
|
-
| Out of scope | Reimplementing every harness inside this skill |
|
|
14
|
-
|
|
15
|
-
## Today
|
|
16
|
-
|
|
17
|
-
- Medium procedure: `reference/medium.md` (angles, verify, output fields).
|
|
18
|
-
- Grok orchestration API: `scripts/grok_code_review.py` (discovery, dedupe,
|
|
19
|
-
retain, head-drift).
|
|
20
|
-
- Constants: `scripts/e_code_review_scripts_constants/`.
|
|
21
|
-
|
|
22
|
-
## Target shape (tracked separately)
|
|
23
|
-
|
|
24
|
-
1. **Runner protocol.** Shared inputs (diff base, head, angles) and outputs
|
|
25
|
-
(candidates, verdicts, severities).
|
|
26
|
-
2. **Detection.** Which runners are installed or configured (PATH, skills,
|
|
27
|
-
account chain).
|
|
28
|
-
3. **Selection.** Pick one runner. Keep vendor choice out of `SKILL.md`
|
|
29
|
-
process steps.
|
|
30
|
-
4. **Adapters.** Thin wrappers: Grok (current module), Codex, Claude, and
|
|
31
|
-
others.
|
|
32
|
-
|
|
33
|
-
Keep implementation pull requests small: one concern each. Link this file from
|
|
34
|
-
the tracking issue.
|
|
35
|
-
|
|
36
|
-
## Related always-on docs
|
|
37
|
-
|
|
38
|
-
- Skill hub: `../SKILL.md` (levels, fix, loop).
|
|
39
|
-
- Preflight proposal: `preflight-proposal.md` (immutable range, local runner, proposal evidence).
|
|
40
|
-
- Medium procedure: `medium.md`.
|
package/.agents/skills/e-code-review/scripts/config/e_code_review_effort_constants/__init__.py
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
"""Constants for the e-code-review effort evaluation harness."""
|
|
2
|
-
|
|
3
|
-
from e_code_review_effort_constants.effort_constants import (
|
|
4
|
-
ALL_EFFORT_LEVELS,
|
|
5
|
-
ALL_EFFORT_RANK_BY_NAME,
|
|
6
|
-
ALL_FIXTURE_BANDS,
|
|
7
|
-
ALL_REQUIRED_ROW_KEYS,
|
|
8
|
-
ALL_SCORE_ROW_KEYS,
|
|
9
|
-
ALL_SKILL_EFFORT_FOR_EVALUATION_EFFORT,
|
|
10
|
-
ALL_SKILL_EFFORT_LEVELS,
|
|
11
|
-
COST_LATENCY_LEVER,
|
|
12
|
-
EVALUATION_EVIDENCE_FILENAME,
|
|
13
|
-
EVALUATION_SCHEMA_VERSION,
|
|
14
|
-
FIXTURES_DIRECTORY_NAME,
|
|
15
|
-
JSON_SUFFIX,
|
|
16
|
-
LATENCY_MS_ROW_KEY,
|
|
17
|
-
MINIMUM_QUALITY_HOLD_SCORE,
|
|
18
|
-
THINKING_ENABLED_DEFAULT,
|
|
19
|
-
VISIBLE_TOKENS_ROW_KEY,
|
|
20
|
-
WORKFLOW_FAMILY_E_CODE_REVIEW,
|
|
21
|
-
)
|
|
22
|
-
|
|
23
|
-
__all__ = [
|
|
24
|
-
"ALL_EFFORT_LEVELS",
|
|
25
|
-
"ALL_EFFORT_RANK_BY_NAME",
|
|
26
|
-
"ALL_FIXTURE_BANDS",
|
|
27
|
-
"ALL_REQUIRED_ROW_KEYS",
|
|
28
|
-
"ALL_SCORE_ROW_KEYS",
|
|
29
|
-
"ALL_SKILL_EFFORT_FOR_EVALUATION_EFFORT",
|
|
30
|
-
"ALL_SKILL_EFFORT_LEVELS",
|
|
31
|
-
"COST_LATENCY_LEVER",
|
|
32
|
-
"EVALUATION_EVIDENCE_FILENAME",
|
|
33
|
-
"EVALUATION_SCHEMA_VERSION",
|
|
34
|
-
"FIXTURES_DIRECTORY_NAME",
|
|
35
|
-
"JSON_SUFFIX",
|
|
36
|
-
"LATENCY_MS_ROW_KEY",
|
|
37
|
-
"MINIMUM_QUALITY_HOLD_SCORE",
|
|
38
|
-
"THINKING_ENABLED_DEFAULT",
|
|
39
|
-
"VISIBLE_TOKENS_ROW_KEY",
|
|
40
|
-
"WORKFLOW_FAMILY_E_CODE_REVIEW",
|
|
41
|
-
]
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
"""Named values for the Opus effort evaluation sweep."""
|
|
2
|
-
|
|
3
|
-
EVALUATION_SCHEMA_VERSION: str = "1"
|
|
4
|
-
THINKING_ENABLED_DEFAULT: bool = True
|
|
5
|
-
MINIMUM_QUALITY_HOLD_SCORE: float = 0.8
|
|
6
|
-
COST_LATENCY_LEVER: str = "effort"
|
|
7
|
-
ALL_EFFORT_LEVELS: tuple[str, ...] = ("low", "medium", "high", "xhigh", "max")
|
|
8
|
-
ALL_FIXTURE_BANDS: tuple[str, ...] = ("easy", "medium", "demanding")
|
|
9
|
-
ALL_SCORE_ROW_KEYS: tuple[str, ...] = (
|
|
10
|
-
"quality_score",
|
|
11
|
-
"finding_recall",
|
|
12
|
-
"finding_precision",
|
|
13
|
-
)
|
|
14
|
-
FIXTURES_DIRECTORY_NAME: str = "fixtures"
|
|
15
|
-
JSON_SUFFIX: str = ".json"
|
|
16
|
-
VISIBLE_TOKENS_ROW_KEY: str = "visible_tokens"
|
|
17
|
-
LATENCY_MS_ROW_KEY: str = "latency_ms"
|
|
18
|
-
ALL_REQUIRED_ROW_KEYS: tuple[str, ...] = (
|
|
19
|
-
"fixture_id",
|
|
20
|
-
"fixture_band",
|
|
21
|
-
"effort",
|
|
22
|
-
*ALL_SCORE_ROW_KEYS,
|
|
23
|
-
VISIBLE_TOKENS_ROW_KEY,
|
|
24
|
-
LATENCY_MS_ROW_KEY,
|
|
25
|
-
"thinking_enabled",
|
|
26
|
-
)
|
|
27
|
-
ALL_EFFORT_RANK_BY_NAME: dict[str, int] = {
|
|
28
|
-
each_effort: each_index
|
|
29
|
-
for each_index, each_effort in enumerate(ALL_EFFORT_LEVELS)
|
|
30
|
-
}
|
|
31
|
-
ALL_SKILL_EFFORT_LEVELS: tuple[str, ...] = ("low", "medium", "xhigh")
|
|
32
|
-
EVALUATION_EVIDENCE_FILENAME: str = "effort_defaults_evidence.json"
|
|
33
|
-
WORKFLOW_FAMILY_E_CODE_REVIEW: str = "e-code-review"
|
|
34
|
-
ALL_SKILL_EFFORT_FOR_EVALUATION_EFFORT: dict[str, str] = {
|
|
35
|
-
"low": "low",
|
|
36
|
-
"medium": "medium",
|
|
37
|
-
"high": "xhigh",
|
|
38
|
-
"xhigh": "xhigh",
|
|
39
|
-
"max": "xhigh",
|
|
40
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"""Constants package for e-code-review scripts."""
|