@mrciphersmith/keryx 0.3.120 → 0.3.122
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/dist/cli.js +9184 -6402
- package/dist/core.js +1702 -1311
- package/package.json +1 -1
- package/src/gdskills/bundled/install-manifest.json +2 -1
- package/src/gdskills/bundled/rules/core/session-plan-bridge.mdc +1 -1
- package/src/gdskills/bundled/skills/orchestration/feature-dev/SKILL.md +4 -4
- package/src/gdskills/bundled/skills/orchestration/flow-orchestrator/SKILL.md +9 -18
- package/src/gdskills/bundled/skills/orchestration/job-orchestrator/SKILL.detail.md +70 -0
- package/src/gdskills/bundled/skills/orchestration/job-orchestrator/SKILL.md +36 -73
- package/src/gdskills/bundled/skills/orchestration/task-implementer/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/orchestration/task-implementer/input-contract.schema.json +17 -2
- package/src/gdskills/bundled/skills/review/review-architecture/SKILL.md +6 -11
- package/src/gdskills/bundled/skills/review/review-backend/SKILL.md +6 -11
- package/src/gdskills/bundled/skills/review/review-clean-code/SKILL.md +6 -11
- package/src/gdskills/bundled/skills/review/review-core-boundaries/SKILL.md +5 -10
- package/src/gdskills/bundled/skills/review/review-flow-graph/SKILL.md +5 -10
- package/src/gdskills/bundled/skills/review/review-frontend/SKILL.md +6 -11
- package/src/gdskills/bundled/skills/review/review-frontend-conventions/SKILL.md +5 -10
- package/src/gdskills/bundled/skills/review/review-highload/SKILL.md +6 -11
- package/src/gdskills/bundled/skills/review/review-jev-comments/SKILL.md +4 -9
- package/src/gdskills/bundled/skills/review/review-jev-contract/SKILL.md +4 -9
- package/src/gdskills/bundled/skills/review/review-jev-docs/SKILL.md +4 -9
- package/src/gdskills/bundled/skills/review/review-jev-risk/SKILL.md +4 -9
- package/src/gdskills/bundled/skills/review/review-jev-rules/SKILL.md +4 -9
- package/src/gdskills/bundled/skills/review/review-jev-scenarios/SKILL.md +4 -9
- package/src/gdskills/bundled/skills/review/review-layout/SKILL.md +8 -9
- package/src/gdskills/bundled/skills/review/review-logic/SKILL.md +6 -11
- package/src/gdskills/bundled/skills/review/review-orchestrator/SKILL.detail.md +27 -3
- package/src/gdskills/bundled/skills/review/review-orchestrator/SKILL.md +38 -48
- package/src/gdskills/bundled/skills/review/review-orchestrator/reviewer-finding.schema.json +10 -1
- package/src/gdskills/bundled/skills/review/review-orchestrator/reviewer-input.schema.json +1 -1
- package/src/gdskills/bundled/skills/review/review-performance/SKILL.md +6 -11
- package/src/gdskills/bundled/skills/review/review-pr-contract/SKILL.md +2 -2
- package/src/gdskills/bundled/skills/review/review-pr-feedback/SKILL.md +8 -10
- package/src/gdskills/bundled/skills/review/review-premise/SKILL.md +180 -0
- package/src/gdskills/bundled/skills/review/review-regression/SKILL.md +3 -3
- package/src/gdskills/bundled/skills/review/review-security-code/SKILL.md +6 -11
- package/src/gdskills/bundled/skills/review/review-style/SKILL.md +6 -11
- package/src/gdskills/bundled/skills/review/review-testing-practices/SKILL.md +2 -2
- package/src/gdskills/contracts/review-finding.schema.json +77 -2
|
@@ -42,9 +42,9 @@ license: "MIT"
|
|
|
42
42
|
| Wave bytes | `--host keryx-shell` (60000: a child dies at 5 min) | `--host claude-code` (150000) | `--host codex` / `--host other` (150000) | its own |
|
|
43
43
|
|
|
44
44
|
- **Every host keeps the same files, per package** (`<package>` is the directory `keryx review start` created): slices in `<package>/slices/`, one reply per dispatch in `<package>/raw/<reviewer>.txt` (reviewer replies only), one driver per dispatch in `<package>/drivers/<reviewer>.json`, and `research.json` from `keryx review ledger build --package <package>` — never by hand. `retry-plan --package`, `verdict` and `ledger build` read `<package>/raw` by default; the shared `.metaproject/data/review/raw` holds other rounds' replies and is read only when named, so never write there.
|
|
45
|
-
- **The result is the file, never the spawn tool's output.** keryx shell cuts a child's summary at 16000 characters and Claude Code returns only the last message: parse `<package>/raw/<reviewer>.txt`. A missing file is no result (`BLOCKED`).
|
|
45
|
+
- **The result is the file, never the spawn tool's output.** keryx shell cuts a child's summary at 16000 characters and Claude Code returns only the last message: parse `<package>/raw/<reviewer>.txt`. A missing file is no result (`BLOCKED`). Token spend: keryx shell appends `KERYX_USAGE {"tokens_in":…,"tokens_out":…,"model":…,"by":"host"}` to that file itself; on another host, when your spawn tool's result reports the subagent's tokens, append that one line, with `"by":"host"`, to the file yourself (a dispatch without it is counted unknown, never 0; a line without the mark is counted as stated by the reviewer, not measured).
|
|
46
46
|
- **Caller token.** `keryx review start` prints `export KERYX_REVIEW_CALLER_TOKEN=…`; outside keryx shell export it on this session's keryx calls, or readiness item 10 reads "not observable on this host".
|
|
47
|
-
- **Operator decisions.** In keryx shell the operator answers a card: `review_confirm_plan`, `review_waive_readiness`, `review_waive_coverage`, `review_waive_mutation`, `review_override_reviewers`, `review_chunks_answer`, `review_publish`, `review_comments_reply`. Elsewhere give the operator the exact command to run in their own terminal — `keryx review confirm-plan --package <package>`, `keryx review complete <package> --waive <item> "<their words>"` or `--waive-coverage "<their words>"`, `keryx review waive-mutation --package <package> --reason "<why>"`, `keryx review override-reviewers --package <package> --reason "<why>"`, `keryx review chunks estimate --package <package> --answer yes --quote "<their words>"`, `keryx review publish <package>`, `keryx review comments reply … --final` — and wait. You never run `--mode automatic` or `--yes`, and never write an operator quote yourself; unattended, the item is Not run.
|
|
47
|
+
- **Operator decisions.** In keryx shell the operator answers a card: `review_confirm_plan`, `review_waive_readiness`, `review_waive_coverage`, `review_waive_mutation`, `review_override_reviewers`, `review_chunks_answer`, `review_publish`, `review_comments_reply`, `review_decide_premise`. Elsewhere give the operator the exact command to run in their own terminal — `keryx review confirm-plan --package <package>`, `keryx review complete <package> --waive <item> "<their words>"` or `--waive-coverage "<their words>"`, `keryx review waive-mutation --package <package> --reason "<why>"`, `keryx review override-reviewers --package <package> --reason "<why>"`, `keryx review chunks estimate --package <package> --answer yes --quote "<their words>"`, `keryx review publish <package>`, `keryx review comments reply … --final`, `keryx review decide-premise --package <package> --finding <id> --answer uphold|dismiss --reason "<why>"` — and wait. You never run `--mode automatic` or `--yes`, and never write an operator quote yourself; unattended, the item is Not run.
|
|
48
48
|
|
|
49
49
|
## Round plan — the order on every host
|
|
50
50
|
|
|
@@ -55,8 +55,8 @@ license: "MIT"
|
|
|
55
55
|
5. `keryx review required --mode all --scope .metaproject/data/review/scope.json --depth auto --package <package>`.
|
|
56
56
|
6. `keryx review estimate --package <package>`. Over threshold, the operator confirms (card `review_confirm_plan`, or `keryx review confirm-plan --package <package>` in their terminal); `dispatch-check` and `ledger build` refuse an unconfirmed plan, so never dispatch one. Unattended: report the estimate and stop with `STATUS: BLOCKED plan_over_threshold`.
|
|
57
57
|
7. Dispatch by slice roles: each role gets the slices that name it; a deep slice names every roster role its path gates allow, an `audit` one the whole core set. A major or worse on a light slice comes back from `review next` as an `escalated` dispatch: dispatch the core roles on it.
|
|
58
|
-
8. Verifier on the first blocker or major (Step 10). It runs no command itself: run `keryx review verify-run --package <package> --finding <id> -- <command>` and hand it the saved `research-evidence/verify-<id>-<n>.txt` as context.
|
|
59
|
-
9. `keryx review verdict <package>` to the operator, then the tail: mutation pass, `ledger build`, `ingest
|
|
58
|
+
8. Verifier on the first blocker or major (Step 10). It runs no command itself: run `keryx review verify-run --package <package> --finding <id> -- <command>` and hand it the saved `research-evidence/verify-<id>-<n>.txt` as context. After it (no verifier ran: after the last reviewer), Wave D: `review-premise` (Step 10b).
|
|
59
|
+
9. `keryx review verdict <package>` to the operator, then the tail: mutation pass, `ledger build`, `ingest` (with `--premises`), the operator's answer to each held finding (Wave D), `readiness`, `complete`.
|
|
60
60
|
|
|
61
61
|
## Clean context — the round starts empty
|
|
62
62
|
|
|
@@ -85,9 +85,10 @@ Review Orchestrator Progress:
|
|
|
85
85
|
- [ ] Step 9: Collect reviewer-finding schema results and handle NEEDS_CONTEXT
|
|
86
86
|
- [ ] Step 9b: `jev-triage` — advisory, annotate-only severity/duplicate/verify-order annotations over the consolidated findings (opt-in `review.jev.triage`)
|
|
87
87
|
- [ ] Step 10: Wave C — when blockers/majors exist, `--verify` is set, or the PR is high-risk, dispatch `review-verifier` on the first blocker/major without waiting for other reviewers, then once per later pass over the findings held at that point
|
|
88
|
+
- [ ] Step 10b: Wave D — after the last verifier pass (none ran: after the last reviewer), dispatch `review-premise` (deep tier) over the canonical findings of severity ≥ minor (delta round: only those without a carried premise); pass its claims with `review ingest --premises <file>`; once that ingest wrote `findings.json` (the tail), ask the operator about each held finding (see "Wave D")
|
|
88
89
|
- [ ] Step 11: Sort by severity, deduplicate, emit unified report
|
|
89
90
|
- [ ] Step 12: Emit the machine-readable `keryx:findings` block alongside the report
|
|
90
|
-
- [ ] Step 13: Report the stage counts: dropped by pre-filter, refuted by the verifier, retained
|
|
91
|
+
- [ ] Step 13: Report the stage counts: dropped by pre-filter, refuted by the verifier, downgraded and held by the premise judge, retained
|
|
91
92
|
- [ ] Step 14: Managed rounds only (not `lightweight`, which is report-only), after the final round, on an open pull request at the head you reviewed — answer every external comment once with `keryx review comments reply --final` (render with `--dry-run`; the post itself is the operator's: the `review_comments_reply` card in keryx shell, else they run it in their terminal; unattended: do not publish, hand the rendered body back) — never against a pull request the dispatch named as the caller's
|
|
92
93
|
```
|
|
93
94
|
|
|
@@ -101,22 +102,22 @@ It names a model only if you gave it your session (`--session-provider`/`--sessi
|
|
|
101
102
|
|
|
102
103
|
### Step 6a — the plan bridge
|
|
103
104
|
|
|
104
|
-
Publish this checklist with `plan_set` under the ids `step-0`…`step-14` once, here, when scope and dispatch are fixed (keryx shell already published it as `pending` at the start — update it with `plan_update` instead; another host uses its own plan tool, "Hosts"). Publish each of steps 0–5 that ran as `completed` and each that did not run as `skipped`; publish steps 6–14 as `pending` (`in_progress` for the one starting now). From then on move each item with `plan_update` as its step completes — see the `session-plan-bridge` rule. `completed` means the step's artifact exists: steps 8–10 become `completed` (in the plan and in the report) only after `keryx review ingest` has recorded their results, and a step whose reviewers were `BLOCKED` is `blocked`.
|
|
105
|
+
Publish this checklist with `plan_set` under the ids `step-0`…`step-14` and `step-10b` once, here, when scope and dispatch are fixed (keryx shell already published it as `pending` at the start — update it with `plan_update` instead; another host uses its own plan tool, "Hosts"). Publish each of steps 0–5 that ran as `completed` and each that did not run as `skipped`; publish steps 6–14 and 10b as `pending` (`in_progress` for the one starting now). From then on move each item with `plan_update` as its step completes — see the `session-plan-bridge` rule. `completed` means the step's artifact exists: steps 8–10 and 10b become `completed` (in the plan and in the report) only after `keryx review ingest` has recorded their results (10b: `--premises`), and a step whose reviewers were `BLOCKED` is `blocked`.
|
|
105
106
|
|
|
106
107
|
## How to spawn (Steps 8 and 10)
|
|
107
108
|
|
|
108
109
|
- One `Agent` call per reviewer, all calls of a wave in a single message, so the wave runs in parallel.
|
|
109
|
-
- Reviewers are read-only: they read the diff and the files and run no command. Only you (through `keryx review verify-run --timeout <seconds>`), the verifier and at most one testing reviewer run commands, inside a time budget. Each payload carries `allowed_tools` (`read-only` or `run-tests`) and `exec_budget_s`.
|
|
110
|
+
- Reviewers are read-only: they read the diff and the files and run no command, except the read-only history commands `git log`, `git blame` and `git show` (law 4; `review-premise` too) where the host gives a read-only child git. keryx shell does not: a `spawn_subagent` child has no shell and no git tool, so you run `git log -L <start>,<end>:<file>` and `git blame -L <start>,<end> <file>` for each deliberate-looking site a reviewer must judge and pass the output in `context_files`; with neither, the reviewer says the history was not read. Only you (through `keryx review verify-run --timeout <seconds>`), the verifier and at most one testing reviewer run other commands, inside a time budget. Each payload carries `allowed_tools` (`read-only` or `run-tests`) and `exec_budget_s`.
|
|
110
111
|
- Use the reviewer's exact `subagent_type`. If the runtime has no such type, use `general-purpose` and name the reviewer's `SKILL.md` path in the prompt. Neither available: that reviewer is `BLOCKED`.
|
|
111
112
|
- Prompts carry pointers, not pasted files — the diff, the SHAs, the PR, the schema paths — and never paraphrase a contract. On keryx shell the slices travel in `context_files` instead (below). Run `keryx review dispatch-check --payload <file> --manifest <package>/slices/manifest.json --package <package>` on every payload before a mass dispatch; it fails `REVIEWER_INPUT_PATH_MISSING` on a missing `skill_path` or `context_doc`.
|
|
112
113
|
- A reply is a result only if it starts with a `STATUS:` line and carries a `REVIEW_RESULT` block matching `reviewer-finding.schema.json`; anything else is `BLOCKED`. The one exception: a reply or dispatch error of `STATUS: RATE_LIMITED` is handled by the Rate limits rule under Control, never marked `BLOCKED`.
|
|
113
|
-
- The model comes from `keryx review tier` (Step 6). On `spawn_subagent` pass its tier as `model_tier` on every reviewer — `review-verifier` and simple reviewers `light`, normal `standard`, complex `deep
|
|
114
|
+
- The model comes from `keryx review tier` (Step 6). On `spawn_subagent` pass its tier as `model_tier` on every reviewer — `review-verifier` and simple reviewers `light`, normal `standard`, complex reviewers and `review-premise` `deep` (`keryx review tier --premise`); an omitted tier runs the child on your own model.
|
|
114
115
|
|
|
115
116
|
## Slices, waves and results — every host; keryx shell specifics marked
|
|
116
117
|
|
|
117
118
|
A reviewer starts in the project root and reads project files; a path outside the project root is unreadable to it. On keryx shell its `context_files` content reaches it wrapped as DATA, and slices and measurements travel only there (never pasted or retyped); elsewhere the prompt names the slice paths. `skill_path` and `pr_context` stay payload fields. The text reaches the reviewer in slices small enough to finish.
|
|
118
119
|
|
|
119
|
-
0. **Publish the plan before anything else (keryx shell).** Your first tool call is `plan_set` with `step-0`…`step-14` all `pending`. A shell turn that has open plan items is continued by the host; a turn that ends on a text reply is over, and a message saying the review "cannot be honestly completed" ends the run with nothing reviewed. Never end the turn while a step is `pending` or `in_progress`: mark it `blocked` only with a cause you cannot fix with a command, and otherwise keep working. Step 6a then updates this plan rather than creating it.
|
|
120
|
+
0. **Publish the plan before anything else (keryx shell).** Your first tool call is `plan_set` with `step-0`…`step-14` and `step-10b` all `pending`. A shell turn that has open plan items is continued by the host; a turn that ends on a text reply is over, and a message saying the review "cannot be honestly completed" ends the run with nothing reviewed. Never end the turn while a step is `pending` or `in_progress`: mark it `blocked` only with a cause you cannot fix with a command, and otherwise keep working. Step 6a then updates this plan rather than creating it.
|
|
120
121
|
1. **Slice first.** `keryx review slice --ref <base> --package <package> --host <host>` after `keryx review start`. It writes `<package>/slices/slice-NN.diff` files of at most 150000 bytes each and a `manifest.json` carrying a wave budget (`--wave-bytes`, never below the slice ceiling; default by `--host`: 60000 on keryx-shell, 150000 elsewhere): what ONE reviewer dispatch may total, so a role owning many slices is dispatched in slice waves that each fit the child deadline. On keryx shell with a large diff pass a small `--max-bytes` (for example 18000) and `--wave-bytes` (for example 54000) so no wave outruns a reviewer's five minutes; ledgers (csv, lockfiles, snapshots, generated files) are listed under `omissions` with a reason — list them in the report as not reviewed, never as clean.
|
|
121
122
|
2. **Slices travel by path; on keryx shell, only by `context_files`.** The slices sit under the project (`<package>/slices`). On keryx shell pass each reviewer its slice paths in `spawn_subagent`'s `context_files`: the host copies the text into that reviewer's task, so you never paste or retype a slice. Elsewhere name the slice paths in the prompt. Put the `slices` ids in its reviewer-input. A dispatch that names a git range but no slice leaves the reviewer with nothing to read — that is `BLOCKED`, not a review.
|
|
122
123
|
3. **Check before dispatch, every payload.** `keryx review dispatch-check --payload <file> --manifest <package>/slices/manifest.json --package <package>` for the wave; exit 1 means a payload names no slice, is over the wave ceiling (dispatch fewer slices, then the next wave), names a `skill_path` or `context_doc` that does not exist (`REVIEWER_INPUT_PATH_MISSING`), belongs to an unconfirmed over-threshold plan (`REVIEWER_INPUT_PLAN_UNCONFIRMED`), or breaks `reviewer-input.schema.json`. Fix it; do not dispatch around it.
|
|
@@ -128,11 +129,11 @@ A reviewer starts in the project root and reads project files; a path outside th
|
|
|
128
129
|
## Control
|
|
129
130
|
|
|
130
131
|
- **Profiles.** The default is read-only: one round, no edits. `--fix` hands the findings to `flow-orchestrator` or `task-implementer`; the orchestrator never edits code. Control returns to this main session after each hand-off, which loads this skill again (never the implementer, which would nest); each re-review counts toward the ceiling (it adds 1 to the count).
|
|
131
|
-
- **Waves.** Split by diff domain (`core` = logic, security, architecture; `domain` = frontend, backend, conventions; `support` = style, tests), in that order; A/B/C below keep their dependency order, except Wave C, which starts early and overlaps A and B (see Wave C). A full or `--all` round runs at most 10 reviewers per wave (`MAX_REVIEWERS_PER_WAVE_FULL`).
|
|
132
|
+
- **Waves.** Split by diff domain (`core` = logic, security, architecture; `domain` = frontend, backend, conventions; `support` = style, tests), in that order; A/B/C/D below keep their dependency order, except Wave C, which starts early and overlaps A and B (see Wave C); Wave D runs after the last verifier pass. A full or `--all` round runs at most 10 reviewers per wave (`MAX_REVIEWERS_PER_WAVE_FULL`).
|
|
132
133
|
- **Rate limits.** On a reviewer dispatch that fails with a rate-limit or overloaded error (reported as `STATUS: RATE_LIMITED`, a harness signal, not a schema status), halve the wave, requeue the rest and honour `retry-after`, at most 300 seconds (`MAX_RETRY_AFTER_SECONDS`). After at most two halvings (`MAX_RATE_HALVINGS`) stop with `STATUS: BLOCKED rate_limited`, naming the queue left.
|
|
133
|
-
- **Early verdict.** When every reviewer and the verifier are done, save every verifier pass to `research-evidence/verifications.json`, then run `keryx review verdict <package>` (it reads `<package>/raw`; the shared `.metaproject/data/review/raw` only when passed as `--raw`, which mixes in other rounds) and give the operator the verdict then; refuted findings are excluded only once `verifications.json` exists. The mutation pass, ledger and `keryx review complete` continue as the tail, and every managed round finishes them. The verdict is interim: the round is not done until `complete` (`SKILL.detail.md` § "Early verdict").
|
|
134
|
+
- **Early verdict.** When every reviewer and the verifier are done, save every verifier pass to `research-evidence/verifications.json`, then run `keryx review verdict <package>` (it reads `<package>/raw`; the shared `.metaproject/data/review/raw` only when passed as `--raw`, which mixes in other rounds) and give the operator the verdict then; refuted findings are excluded only once `verifications.json` exists, held ones only once Wave D's claims are saved to `research-evidence/premises.json`. A verdict given before Wave D ran is provisional, and you say so: it counts as open the findings the judge may still hold or lower. The mutation pass, ledger and `keryx review complete` continue as the tail, and every managed round finishes them. The verdict is interim: the round is not done until `complete` (`SKILL.detail.md` § "Early verdict").
|
|
134
135
|
- **Recovery.** After a timeout or crash: collect, validate, ingest, then dispatch only what is missing with `keryx review next --package <package>` (all reviewers at once). Never re-dispatch a wave whose results are on disk; after a second timeout of the same reviewer change the task (fewer slices, narrower focus), not only the diff size (`SKILL.detail.md` § "Recovery").
|
|
135
|
-
- **Done when** the consolidated report and the `keryx:findings` block are emitted and the stage counts and **Not run** are stated. A managed round (not `lightweight`, which is report-only) is also done only when every dispatched reviewer's result is recorded with `keryx review ingest` and `keryx review complete` has run. `completed` means `keryx review readiness` passed, or each failing item is waived by the operator: in keryx shell call `review_waive_readiness` (a card, never a terminal), then run `keryx review complete`; elsewhere the operator runs `keryx review complete <package> --waive <item> "<their words>"` in their terminal; unattended, record Not run; publishing to GitHub is held by the same checklist, and a not-ready package goes out only through `keryx review publish --partial` (in keryx shell: `review_publish` with `partial: true`).
|
|
136
|
+
- **Done when** the consolidated report and the `keryx:findings` block are emitted and the stage counts and **Not run** are stated. A managed round (not `lightweight`, which is report-only) is also done only when every dispatched reviewer's result is recorded with `keryx review ingest` and `keryx review complete` has run. `completed` means `keryx review readiness` passed, or each failing item but `premise-decisions` (answered per finding, never waived) is waived by the operator: in keryx shell call `review_waive_readiness` (a card, never a terminal), then run `keryx review complete`; elsewhere the operator runs `keryx review complete <package> --waive <item> "<their words>"` in their terminal; unattended, record Not run; publishing to GitHub is held by the same checklist, and a not-ready package goes out only through `keryx review publish --partial` (in keryx shell: `review_publish` with `partial: true`).
|
|
136
137
|
|
|
137
138
|
---
|
|
138
139
|
|
|
@@ -238,7 +239,7 @@ keryx review start --target <kind> --ref <ref>
|
|
|
238
239
|
keryx review ingest --report <path> [--flow <id>] --ref <ref>
|
|
239
240
|
[--verifications <file>] [--verification-mode off|annotate|filter]
|
|
240
241
|
[--scope <scope.json>] [--blast-radius <blast-radius.json>]
|
|
241
|
-
[--refuted <file>]
|
|
242
|
+
[--refuted <file>] [--premises <file>]
|
|
242
243
|
# --blast-radius is REQUIRED whenever this round dispatched a
|
|
243
244
|
# scope-B reviewer (review-regression). See below.
|
|
244
245
|
keryx review status <review-id-or-path>
|
|
@@ -290,7 +291,7 @@ overwritten by a later close; record a correction as a new round.
|
|
|
290
291
|
|
|
291
292
|
`review complete` on a PR-bound package refuses a merged PR or a moved head unless `report.md`'s first line names the reviewed SHA and says so; a package with no PR binding is unaffected.
|
|
292
293
|
`review complete` refuses a report with no `Evidence level:` line (`static only — did not run: <what>` or `ran — <what>`); a package ingested before the field existed only warns.
|
|
293
|
-
`review ingest`
|
|
294
|
+
`review ingest` keeps an internal finding whose `quote` is not at its `path` at the reviewed SHA (absent, or in several places) with no line, flagged `quote_unlocated`, instead of refusing the round (readiness item `quotes-located` lists it until it has a disposition); it still refuses, naming the finding, a quote it could not check at all (commit not in the checkout, no file named, or a size bound), and adds a `citation not found` line, never a deletion, to a rebuttal citing a rule or document that is not in the tree.
|
|
294
295
|
A finding may close as `narrowed` (research obligation `"status":"narrowed","remains":"<what remains>"`); it counts as closed only with that text, and the report keeps it under "Refuted and narrowed".
|
|
295
296
|
|
|
296
297
|
**Closing a fix round without dispositions leaves every finding reading `unknown`.** That is not "the reviewers were right"; it is "nobody wrote down what happened", and it is the single reason the precision figure cannot be read.
|
|
@@ -481,25 +482,7 @@ Read each run's verdict (`flaky` | `regression` | `infra`) into the report: `fla
|
|
|
481
482
|
|
|
482
483
|
## Everything written to GitHub is brief
|
|
483
484
|
|
|
484
|
-
|
|
485
|
-
replies, issue comments, and commit messages going to a PR.**
|
|
486
|
-
|
|
487
|
-
- Lead with the conclusion. No preamble, no restating the question, no apology,
|
|
488
|
-
no summary of the flow.
|
|
489
|
-
- Say what changed and where. **Link, do not paste.**
|
|
490
|
-
- The reasoning, the evidence, the rejected alternatives and the round history live
|
|
491
|
-
in the flow package — `journal.md`, `context.md`, the review artifacts — which is
|
|
492
|
-
durable, searchable, and costs a reader nothing to skip.
|
|
493
|
-
- A GitHub artifact that needs more than a short paragraph is a signal that the
|
|
494
|
-
detail belongs in the flow with a link out, **not** that the paragraph should
|
|
495
|
-
grow.
|
|
496
|
-
- No orchestrator-written PR comment or reply exceeds two sentences without
|
|
497
|
-
carrying a link to the artifact holding the detail. The reply pass enforces
|
|
498
|
-
this; for anything else you write outward, hold yourself to it.
|
|
499
|
-
|
|
500
|
-
This is deliberately asymmetric: **verbose in the flow, terse on GitHub.** The
|
|
501
|
-
flow is written for whoever resumes the work; GitHub is read by someone who did
|
|
502
|
-
not ask for our reasoning and is reading between other tasks.
|
|
485
|
+
PR bodies, comments, replies and commit messages lead with the conclusion, say what changed and where, and link rather than paste; verbose in the flow, terse on GitHub (`SKILL.detail.md` § "Everything written to GitHub is brief").
|
|
503
486
|
|
|
504
487
|
## Review Context Pack
|
|
505
488
|
|
|
@@ -699,7 +682,7 @@ record `model_assignment: adaptive` with the model you chose.
|
|
|
699
682
|
|
|
700
683
|
`keryx review start` (or `keryx review plan`) decides the round; you never pick a range. `<package>/round.json` says round N, the mode (`first`, `delta`, `fallback-first`), the source that found the previous round and the `range`; `<package>/prior_findings.json` holds the earlier findings. "Round 1 — no previous round found (sources tried …)" is a valid outcome: review as a first round and say which sources were tried.
|
|
701
684
|
|
|
702
|
-
- **`delta` round.** A FIX slice (`kind: fix`, a hunk that answers a prior finding) gets `review-logic`, `review-regression`, the authors of the findings attached to it and the verifier. Set `is_fix_round: true` and attach those findings as `prior_findings` on each of those reviewer inputs. A NEW slice (`kind: new`) is reviewed as round 1, with the roles its slice names. Code of `merge-base..head` that did not change since the previous round gets one cheap second look: SECOND-LOOK slices (`kind: second-look`, listed in `round.json` `secondLookHunks`) are read once per round by `review-logic` and `review-security-code` only, and their findings are ordinary findings. When round.json says "previous round weak: …" (the previous round did not complete, left uncovered slices, skipped required reviewers, had "Not run" lines, or reviewed a narrower scope) that code is `kind: new` instead and gets the full round-1 treatment. `review plan` prints "second-look: N slices / M dispatches". Carried findings keep their dispositions. An empty range (base equals head: a merged pull request read against its own target branch) is refused; pass the recorded base with `review start --base` / `review plan --ref`. A reviewer on a FIX slice returns `prior_dispositions: [{id, disposition}]` in its `REVIEW_RESULT`, one entry for every attached finding id.
|
|
685
|
+
- **`delta` round.** A FIX slice (`kind: fix`, a hunk that answers a prior finding) gets `review-logic`, `review-regression`, the authors of the findings attached to it, `review-security-code` when one of them is a security finding, the roles its own changed lines route by content (e.g. `review-security-code` for a fix that spawns a process or builds an argv), and the verifier. Set `is_fix_round: true` and attach those findings as `prior_findings` on each of those reviewer inputs. A NEW slice (`kind: new`) is reviewed as round 1, with the roles its slice names. Code of `merge-base..head` that did not change since the previous round gets one cheap second look: SECOND-LOOK slices (`kind: second-look`, listed in `round.json` `secondLookHunks`) are read once per round by `review-logic` and `review-security-code` only, and their findings are ordinary findings. When round.json says "previous round weak: …" (the previous round did not complete, left uncovered slices, skipped required reviewers, had "Not run" lines, or reviewed a narrower scope) that code is `kind: new` instead and gets the full round-1 treatment. `review plan` prints "second-look: N slices / M dispatches". Carried findings keep their dispositions. An empty range (base equals head: a merged pull request read against its own target branch) is refused; pass the recorded base with `review start --base` / `review plan --ref`. A reviewer on a FIX slice returns `prior_dispositions: [{id, disposition}]` in its `REVIEW_RESULT`, one entry for every attached finding id.
|
|
703
686
|
- **`fallback-first` round** (force-push or rebase: the previous head is not an ancestor). Review `merge-base..head` in full, with the prior findings attached.
|
|
704
687
|
- **Every attached prior finding leaves the round with a disposition** — `closed`, `open`, `partial`, `regressed` or `withdrawn` — one line each in the report before the new findings, checked against the code and not the commit message. A fix is new code: the report carries a `## Regressions the fixes introduced` section. A finding this round disproves is withdrawn at the top of the report with its evidence. Table, recorded shapes and rationale: `SKILL.detail.md` § "Fix rounds — dispositions, regressions, withdrawal".
|
|
705
688
|
- **Duplicates.** `keryx review ingest` merges duplicate findings; later waves receive `known_findings` and do not report them again.
|
|
@@ -899,7 +882,7 @@ Three bounds keep it from deleting coverage:
|
|
|
899
882
|
|
|
900
883
|
- **Only path-triggered reviewers.** A reviewer selected by an explicit flag, or
|
|
901
884
|
one whose scope is the whole change rather than a path set — `review-logic`,
|
|
902
|
-
`review-regression`, `review-verifier` — is never path-gated. One exception, for project reviewers only: a flag that more than one project reviewer carries is a **family flag** (the inventory lists it in that reviewer's `familyFlags`). It selects the whole family, and each member stays path-gated — `--<family>` over a diff touching one member's paths dispatches that member, not all of them.
|
|
885
|
+
`review-regression`, `review-verifier`, `review-premise` — is never path-gated. One exception, for project reviewers only: a flag that more than one project reviewer carries is a **family flag** (the inventory lists it in that reviewer's `familyFlags`). It selects the whole family, and each member stays path-gated — `--<family>` over a diff touching one member's paths dispatches that member, not all of them.
|
|
903
886
|
- **Scope A only.** Scope B is the blast radius; it is *supposed* to name files the
|
|
904
887
|
diff never touched.
|
|
905
888
|
- **Ambiguity includes.** If you cannot decide whether a path matches, dispatch.
|
|
@@ -1028,6 +1011,7 @@ Review Plan Preview must include an `Optional legacy/profile reviewers` group (e
|
|
|
1028
1011
|
| `--pr-contract` | `review-pr-contract` |
|
|
1029
1012
|
| `--all` | all reviewers above (including `review-clean-code`, `review-highload`, and project convention reviewers when local convention docs exist); never the legacy/profile reviewers, which stay flag-only |
|
|
1030
1013
|
| `--verify` | `review-verifier`, started on the first blocker or major and re-run for each later one (`SKILL.detail.md` § "Early verifier"); checks the findings by running something. Delete-only. |
|
|
1014
|
+
| (always, Wave D) | `review-premise` after the verifier, over the canonical findings of severity ≥ minor; judges whether each is a defect at all; lowers or holds, never adds. Not a fan-out flag |
|
|
1031
1015
|
| (auto) | detected from diff file extensions — see Auto-detection table |
|
|
1032
1016
|
|
|
1033
1017
|
Multiple flags may be combined: `review --backend --security` dispatches `review-logic` + `review-backend` + `review-architecture` + `review-security-code`; `review --frontend --frontend-conventions` dispatches the generic frontend set plus the local frontend conventions reviewer.
|
|
@@ -1080,6 +1064,7 @@ Dispatch selected reviewers in parallel when independent — this engine dispatc
|
|
|
1080
1064
|
1. Wave A - core correctness/risk reviewers: logic, architecture, security/highload when selected.
|
|
1081
1065
|
2. Wave B - domain reviewers: frontend/backend/testing/convention reviewers filtered to relevant files. `review-jev-rules` (flow 330), `review-jev-risk`/`review-jev-scenarios` (flow 332), `review-jev-docs`/`review-jev-comments` (flow 333), `review-jev-contract` (flow 335) also run here, CLI-engine not sub-agent, `"engine": "jev"` in `keryx review reviewers --json`, gated on their own opt-in and a resolvable Jev/OpenRouter credential — measured verdicts per reviewer (keep off by default, experimental, etc.) in `SKILL.detail.md` § "CLI-engine reviewers".
|
|
1082
1066
|
3. Wave C - **verification**: `review-verifier` over the findings, started on the first blocker/major while other reviewers still run and re-run for each later one (`SKILL.detail.md` § "Early verifier"), or when `--verify` is set or the PR is high-risk. Exception to the A, B, C order: Wave C overlaps A and B and gets the findings held when each pass starts; Step 9b's `verify_order` applies to the later passes; each verifier pass is its own run. See below.
|
|
1067
|
+
4. Wave D - **premise**: `review-premise` after the last verifier pass (see "Wave D" below).
|
|
1083
1068
|
|
|
1084
1069
|
**Execution belongs to both B and C, and they execute for opposite reasons.** Wave C runs a command to *decide the fate of a finding that exists*; it is delete-only and can produce nothing. Wave B runs commands to *make findings* — `review-testing-practices` deletes each gate the diff added and records whether the suite goes red, and `review-layout` measures rendered geometry in a real engine.
|
|
1085
1070
|
|
|
@@ -1135,6 +1120,14 @@ Dispatch rules:
|
|
|
1135
1120
|
rewritten finding, the merge discards that whole claim and records the attempt.
|
|
1136
1121
|
Do not "help" by applying it.
|
|
1137
1122
|
|
|
1123
|
+
### Wave D — the premise judge, after the verifier
|
|
1124
|
+
|
|
1125
|
+
A finding can reproduce and still not be a defect: one against a timeline pinned LTR on purpose, as platform practice advises, passed the verifier because the `dir="ltr"` really was there. `review-premise` asks the other question, on the deep tier and a clean context: intent, accepted practice, consistency, fix soundness.
|
|
1126
|
+
- Before dispatch, renumber any display id that another finding, carried or new, already has, in the saved reviewer results, so the judge, its claims and ingest all see the same ids. A new finding has no `global_id` yet (ingest mints `<reviewId>#<id>` after Wave D); ingest refuses two findings under one key, and a claim naming an id two findings share is rejected as `ambiguous-finding`.
|
|
1127
|
+
- Dispatch it once after the last verifier pass (no verifier ran: after the last reviewer), over the canonical findings of severity ≥ minor, each with its display `id`, the **real** `reviewer` and `source`, and, for a finding carried from an earlier round, its `global_id`. External (PR-comment, `source: external`) findings are included: they can be challenged, never downgraded. In a delta round only findings without a carried premise. On keryx shell the judge has no shell and no git tool: run `git log -L` and `git blame -L` for each cited site first and pass the output in `context_files`.
|
|
1128
|
+
- The judge's claims name the `id`, or a carried finding's `global_id`. Save its claims object unchanged to `research-evidence/premises.json` (the verdict reads it there) and pass that file with `keryx review ingest --premises <file>`; never apply verdicts by hand. The merge is delete-only: `upheld` changes nothing, `downgraded` lowers the severity, and a claim that adds, raises or rewrites is rejected and listed in `scope.md`.
|
|
1129
|
+
- `challenged` and `owner-decision` **hold** a finding: it is neither fixable nor clean — not an open blocker or major, never in a fix loop's `fix_context.review_feedback`, and it blocks until answered; the verdict lists it as awaiting the operator. **Asking about a held finding** (every skill that meets one points here): at the tail, after `ingest --premises` wrote `findings.json` (never during Wave D, before the ingest: the answer commands read `findings.json`), in keryx shell call the card `review_decide_premise`, which records the answer; elsewhere put its `question` and `options` to the operator with the host's question tool, then give them the exact command to run in their own terminal, `keryx review decide-premise --package <package> --finding <global_id> --answer uphold|dismiss --reason "<why>"`, and wait. Never run it yourself (it needs a terminal) and never write their reason. In a flow, journal the recorded answer. Readiness and the flow review gate fail while a held finding has no decision. Unattended: leave it held and report it.
|
|
1130
|
+
|
|
1138
1131
|
### `verification_mode`
|
|
1139
1132
|
|
|
1140
1133
|
`off` | `annotate` | `filter`. **Default `annotate`, and it stays `annotate` for
|
|
@@ -1203,6 +1196,7 @@ Each reviewer must return a `REVIEW_RESULT` object matching `.metaproject/skills
|
|
|
1203
1196
|
| Performance anti-patterns | NO | `review-performance` |
|
|
1204
1197
|
| Style / naming / import order | NO | `review-style` |
|
|
1205
1198
|
| Checking whether a reported finding is real | NO | `review-verifier` |
|
|
1199
|
+
| Judging whether a finding is a defect at all | NO | `review-premise` |
|
|
1206
1200
|
| Clean Code principles + SOLID at code level | NO | `review-clean-code` |
|
|
1207
1201
|
| Concurrency, resource pools, caching, queues, idempotency | NO | `review-highload` |
|
|
1208
1202
|
| Frontend repository conventions | NO | `review-frontend-conventions` |
|
|
@@ -1229,7 +1223,7 @@ Before consolidation, validate every reviewer result:
|
|
|
1229
1223
|
- Every blocker must include evidence and a concrete suggested fix.
|
|
1230
1224
|
- Findings without evidence are downgraded to `info` or returned to the reviewer for clarification.
|
|
1231
1225
|
- Duplicate findings are merged by `dedupe_key` or by `(file, quote, problem)`.
|
|
1232
|
-
- **A reply that is not a result is `BLOCKED`.** That covers an empty reply (`(subagent produced no text)`), a reply without a valid `REVIEW_RESULT` block, and a `spawn_subagent` output whose first line is `status: BudgetExhausted (…)` or `status: NoProgress …` — the reviewer was cut short, so whatever fragment it left is not its review. Re-dispatch it exactly once with a larger budget, telling it to return its report before the budget ends (and the same `cwd` when the round reviews a worktree). If that also fails, the pass is **not run**: list it under **Not run** with the reason, and never write its findings yourself — a review nobody ran reported as run is worse than a gap the operator can see.
|
|
1226
|
+
- **A reply that is not a result is `BLOCKED`.** That covers an empty reply (`(subagent produced no text)`), a reply without a valid `REVIEW_RESULT` block, and a `spawn_subagent` output whose first line is `status: BudgetExhausted (…)` or `status: NoProgress …` — the reviewer was cut short, so whatever fragment it left is not its review — and a `DONE` result whose `inputs_unreadable` lists a mandatory input it could not read. Re-dispatch it exactly once with a larger budget, telling it to return its report before the budget ends (and the same `cwd` when the round reviews a worktree). For unreadable inputs a larger budget changes nothing: first fix the path or payload that `inputs_unreadable` names, then re-dispatch once. If that also fails, the pass is **not run**: list it under **Not run** with the reason, and never write its findings yourself — a review nobody ran reported as run is worse than a gap the operator can see.
|
|
1233
1227
|
- **The verifier is held to the same rule.** A finding without an applied verifier verdict is `unverified`; the orchestrator never verifies one itself, and a verifier that returned nothing leaves every finding `unverified`, stated in the stage counts.
|
|
1234
1228
|
- If a reviewer exceeds `max_findings`, keep blockers/majors first and summarize lower severity findings.
|
|
1235
1229
|
|
|
@@ -1317,17 +1311,12 @@ inventing a fifth level to express it would put us back where we started.
|
|
|
1317
1311
|
|
|
1318
1312
|
### Shared laws (every reviewer)
|
|
1319
1313
|
|
|
1320
|
-
1. **A claim of runtime harm with no reproducible path is `info`.** If you cannot
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
3. **One finding per class, not one per occurrence.** When the same shape appears
|
|
1327
|
-
at several sites, report it once and list every site. Ten findings that are one
|
|
1328
|
-
finding hide the other nine problems.
|
|
1329
|
-
|
|
1330
|
-
`review-security-code` carries a fourth — every security finding states its attack
|
|
1314
|
+
1. **A claim of runtime harm with no reproducible path is `info`.** If you cannot name the input, call, or condition that reaches the code, you have an observation, not a finding. Report it as `info` and say what would settle it.
|
|
1315
|
+
2. **Never flag the theoretical.** The path you describe must exist in the code under review. Do not report a safe API because it could be misused, or a pattern because it is often wrong elsewhere.
|
|
1316
|
+
3. **One finding per class, not one per occurrence.** When the same shape appears at several sites, report it once and list every site. Ten findings that are one finding hide the other nine problems.
|
|
1317
|
+
4. **A deliberate choice is not a defect until its reason is read and shown wrong.** An explicit override, suppression or exemption, a comment or commit giving a reason, or a sibling doing the same is a decision: read its reason (the comment, `git log -L` or `git blame`, the sibling) before you report it, and report it only when you can show that reason wrong. A project rule is checked against accepted platform practice and its known exceptions before a deviation from it is reported.
|
|
1318
|
+
|
|
1319
|
+
`review-security-code` carries a fifth — every security finding states its attack
|
|
1331
1320
|
vector — which does not generalise and stays there.
|
|
1332
1321
|
|
|
1333
1322
|
## Finding Format
|
|
@@ -1470,7 +1459,7 @@ file and must include the wire-contract line.
|
|
|
1470
1459
|
|
|
1471
1460
|
## Stage counts
|
|
1472
1461
|
|
|
1473
|
-
Required in **How this review was run**, copied from `scope.md`, not re-counted by hand. State what each stage removed. Never state it as a precision improvement: no precision baseline exists to improve on. The line carries `verification_mode` (`off | annotate | filter`), confirmed / refuted / unverifiable / unverified, and retained.
|
|
1462
|
+
Required in **How this review was run**, copied from `scope.md`, not re-counted by hand. State what each stage removed. Never state it as a precision improvement: no precision baseline exists to improve on. The line carries `verification_mode` (`off | annotate | filter`), confirmed / refuted / unverifiable / unverified, the premise verdicts (upheld / downgraded / held), and retained.
|
|
1474
1463
|
|
|
1475
1464
|
`## Checked and cleared` is now **Verified clean**. Same rule: a hypothesis
|
|
1476
1465
|
that was tested and died, with the evidence, not a list of virtues. There is
|
|
@@ -1562,6 +1551,7 @@ When a prompt carries `JOB_NAME` and `CONTEXT_PATH`, read that context document
|
|
|
1562
1551
|
| "A strict re-read of the findings will sharpen them" | That pass existed and was removed: self-correction without new evidence measured 95.5 → 91.5 → 89.0 on GSM8K and 75.8 → 38.1 on CommonSenseQA. Run something instead |
|
|
1563
1552
|
| "Three reviewers agree, so the finding is verified" | Consensus is not evidence. 80+ agents unanimously endorsed a vulnerability that did not exist; one empirical test killed it |
|
|
1564
1553
|
| "The verifier suggested a higher severity, I'll apply it" | It cannot suggest one. A claim carrying a severity is discarded whole and the attempt is recorded |
|
|
1554
|
+
| "The verifier confirmed it, so the fixer gets it" | Confirmed means the fact reproduces, not that it is a defect. Wave D judges the premise; a held finding waits for the operator |
|
|
1565
1555
|
| "This finding has no `verification`, so it can be dropped" | Absent means nobody checked. All 83 recorded findings are in that state; none of them is thereby wrong |
|
|
1566
1556
|
| "Precision went up after the verifier landed" | There is no precision baseline to have gone up from. State stage counts: dropped, refuted, retained |
|
|
1567
1557
|
| "I'll widen the blast radius, this change looks risky" | It is bounded because review quality decays with context: F1 0.65 at round 2 → 0.29 at round 10. Widening makes the later rounds worse, not safer |
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
"minimum": 1
|
|
83
83
|
},
|
|
84
84
|
"quote": {
|
|
85
|
-
"description": "The code this finding is about, copied verbatim out of `file`. A few lines is enough — it is matched against the file at the round's head, exactly first
|
|
85
|
+
"description": "The code this finding is about, copied verbatim out of `file`. A few lines is enough — it is matched against the file at the round's head, exactly first, then with whitespace collapsed, then (a one-line quote of at least 12 characters) as an exact substring of exactly one line; a shorter fragment must be a whole line. A quote that appears in more than one place is recorded as `unlocatable` rather than anchored to the first hit, so quote enough to be unambiguous.",
|
|
86
86
|
"type": [
|
|
87
87
|
"string",
|
|
88
88
|
"null"
|
|
@@ -184,6 +184,15 @@
|
|
|
184
184
|
"type": "string"
|
|
185
185
|
}
|
|
186
186
|
},
|
|
187
|
+
"inputs_unreadable": {
|
|
188
|
+
"title": "Mandatory inputs the reviewer could not read",
|
|
189
|
+
"description": "Name each mandatory input of the dispatch the reviewer could not read: pr_context.json, this schema, a context file, the payload, the slice manifest. Empty or absent when it read them all. A DONE or DONE_WITH_CONCERNS result that names any is not a finished run for `ledger build` or `retry-plan`. Only this field is read for it, never the summary's wording.",
|
|
190
|
+
"type": "array",
|
|
191
|
+
"items": {
|
|
192
|
+
"type": "string",
|
|
193
|
+
"minLength": 1
|
|
194
|
+
}
|
|
195
|
+
},
|
|
187
196
|
"follow_ups": {
|
|
188
197
|
"title": "Follow-ups handed back to the parent",
|
|
189
198
|
"description": "Work the reviewer could not do itself and leaves to the parent. Each entry becomes a research obligation `<raw>:fu<N>` (N counts from 1, in this order; a `Parent follow-up:` line after the REVIEW_RESULT block is appended) with status `unresolved`. It closes only through a disposition (`finding`, `refuted`, `out-of-scope` or `narrowed` with a \"what remains\" text); until then the ledger is not reconciled and the report lists it as not verified.",
|
|
@@ -185,7 +185,7 @@
|
|
|
185
185
|
"type": "string",
|
|
186
186
|
"enum": ["read-only", "run-tests"],
|
|
187
187
|
"default": "read-only",
|
|
188
|
-
"description": "What the reviewer may do beyond reading. `read-only` (the default): read the diff and files, run no command. `run-tests`: at most one testing reviewer per round may run the tests, inside `exec_budget_s`. Verification commands go through the parent's `keryx review verify-run --timeout`."
|
|
188
|
+
"description": "What the reviewer may do beyond reading. `read-only` (the default): read the diff and files, and run no command, except the read-only history commands `git log`, `git blame` and `git show` (shared law 4; the premise judge too) where the host gives a read-only child git. On keryx shell a read-only child has no shell and no git tool: the parent passes `git log -L`/`git blame` output in `context_files`. `run-tests`: at most one testing reviewer per round may run the tests, inside `exec_budget_s`. Verification commands go through the parent's `keryx review verify-run --timeout`."
|
|
189
189
|
},
|
|
190
190
|
"exec_budget_s": {
|
|
191
191
|
"type": "integer",
|
|
@@ -21,7 +21,7 @@ license: "MIT"
|
|
|
21
21
|
|
|
22
22
|
## Purpose
|
|
23
23
|
|
|
24
|
-
Finds real, code-level performance problems introduced in the changed code of the current branch. Covers N+1 database queries, unnecessary React re-renders, missing memoization in hot paths, memory leaks, large bundle imports, synchronous blocking in async contexts, missing pagination, and redundant API calls. Its inputs are the reviewer payload only; session memory and earlier conversation are not inputs. It runs no command unless its payload's `allowed_tools` says `run-tests
|
|
24
|
+
Finds real, code-level performance problems introduced in the changed code of the current branch. Covers N+1 database queries, unnecessary React re-renders, missing memoization in hot paths, memory leaks, large bundle imports, synchronous blocking in async contexts, missing pagination, and redundant API calls. Its inputs are the reviewer payload only; session memory and earlier conversation are not inputs. It runs no command unless its payload's `allowed_tools` says `run-tests`, except the read-only `git log`, `git blame` and `git show` where its host gives a read-only child git (keryx shell does not: there the payload supplies the history).
|
|
25
25
|
|
|
26
26
|
This skill focuses on **measurable or high-likelihood bottlenecks** only. Premature optimization, hypothetical slowness, and style preferences are out of scope.
|
|
27
27
|
|
|
@@ -66,7 +66,7 @@ See shared script: `.metaproject/skills/gdskills/shared/git-merge-base.md`
|
|
|
66
66
|
|
|
67
67
|
Run the script from that file to determine `MERGE_BASE` (`BASE_SHA`) and `SCOPE` before proceeding.
|
|
68
68
|
|
|
69
|
-
**Supplied text first.** When the payload carries `slices`, `context_files`, `diff` or `file_contents`, review exactly that text
|
|
69
|
+
**Supplied text first.** When the payload carries `slices`, `context_files`, `diff` or `file_contents`, review exactly that text and never rebuild the diff. A choice's history (law 4) is read with `git log`, `git blame` and `git show` only where the host gives a read-only child git; on keryx shell a read-only child has no shell and no git tool, so read the `git log -L`/`git blame` excerpts the payload supplies, or say the history was not read. Only with none supplied, collect it:
|
|
70
70
|
```bash
|
|
71
71
|
git diff --name-status "${BASE_SHA}" && git diff "${BASE_SHA}" && git ls-files --others --exclude-standard
|
|
72
72
|
# explicit range: <FROM_SHA>..<TO_SHA> in place of "${BASE_SHA}"
|
|
@@ -196,15 +196,10 @@ Detectable from query patterns in changed code (not from DB schema directly):
|
|
|
196
196
|
|
|
197
197
|
### Shared laws (every reviewer)
|
|
198
198
|
|
|
199
|
-
1. **A claim of runtime harm with no reproducible path is `info`.** If you cannot
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
under review. Do not report a safe API because it could be misused, or a
|
|
204
|
-
pattern because it is often wrong elsewhere.
|
|
205
|
-
3. **One finding per class, not one per occurrence.** When the same shape appears
|
|
206
|
-
at several sites, report it once and list every site. Ten findings that are one
|
|
207
|
-
finding hide the other nine problems.
|
|
199
|
+
1. **A claim of runtime harm with no reproducible path is `info`.** If you cannot name the input, call, or condition that reaches the code, you have an observation, not a finding. Report it as `info` and say what would settle it.
|
|
200
|
+
2. **Never flag the theoretical.** The path you describe must exist in the code under review. Do not report a safe API because it could be misused, or a pattern because it is often wrong elsewhere.
|
|
201
|
+
3. **One finding per class, not one per occurrence.** When the same shape appears at several sites, report it once and list every site. Ten findings that are one finding hide the other nine problems.
|
|
202
|
+
4. **A deliberate choice is not a defect until its reason is read and shown wrong.** An explicit override, suppression or exemption, a comment or commit giving a reason, or a sibling doing the same is a decision: read its reason (the comment, `git log -L` or `git blame`, the sibling) before you report it, and report it only when you can show that reason wrong. A project rule is checked against accepted platform practice and its known exceptions before a deviation from it is reported.
|
|
208
203
|
|
|
209
204
|
Severity levels are defined once, in `review-orchestrator/SKILL.md` →
|
|
210
205
|
**Severity (canonical)**. This reviewer does not restate them: `blocker` is the
|
|
@@ -36,8 +36,7 @@ frontend PR missed a documentation gap that sat in plain view: the body left
|
|
|
36
36
|
the page that describes that table lives outside the diff. The box and the diff
|
|
37
37
|
disagreed, and no reviewer held both.
|
|
38
38
|
|
|
39
|
-
A finding here is a disagreement between two things you can quote: a line of
|
|
40
|
-
`pr-context.md` and a line of the diff (or of a document). Nothing else is filed.
|
|
39
|
+
A finding here is a disagreement between two things you can quote: a line of `pr-context.md` and a line of the diff (or of a document). Nothing else is filed.
|
|
41
40
|
|
|
42
41
|
---
|
|
43
42
|
|
|
@@ -149,6 +148,7 @@ finding ids prefixed `PC-`, then a short summary; `NEEDS_CONTEXT` rather than a
|
|
|
149
148
|
1. **A claim of runtime harm with no reproducible path is `info`.** If you cannot name the input, call, or condition that reaches the code, you have an observation, not a finding. Report it as `info` and say what would settle it.
|
|
150
149
|
2. **Never flag the theoretical.** The path you describe must exist in the code under review. Do not report a safe API because it could be misused, or a pattern because it is often wrong elsewhere.
|
|
151
150
|
3. **One finding per class, not one per occurrence.** When the same shape appears at several sites, report it once and list every site. Ten findings that are one finding hide the other nine problems.
|
|
151
|
+
4. **A deliberate choice is not a defect until its reason is read and shown wrong.** An explicit override, suppression or exemption, a comment or commit giving a reason, or a sibling doing the same is a decision: read its reason (the comment, `git log -L` or `git blame`, the sibling) before you report it, and report it only when you can show that reason wrong. A project rule is checked against accepted platform practice and its known exceptions before a deviation from it is reported.
|
|
152
152
|
|
|
153
153
|
Severity levels are defined once, in `review-orchestrator/SKILL.md` → **Severity (canonical)**. This reviewer does not restate them: `blocker` is the four merge-blocking shapes named there and nothing else, and the `major`/`minor` boundary is the trigger-and-outcome test.
|
|
154
154
|
|
|
@@ -347,16 +347,12 @@ Assign one verdict per comment:
|
|
|
347
347
|
|
|
348
348
|
Rules, and each one is a way this step goes wrong:
|
|
349
349
|
|
|
350
|
-
1. **A verdict carries evidence or it is `unverified`.** The file and line read,
|
|
351
|
-
the query run, the commit cited, the test executed. A verdict reached by
|
|
352
|
-
re-reading the comment is not a verdict on the code.
|
|
350
|
+
1. **A verdict carries evidence or it is `unverified`.** The file and line read, the query run, the commit cited, the test executed. A verdict reached by re-reading the comment is not a verdict on the code.
|
|
353
351
|
2. **`disagree` is a claim about the code, not about the reviewer.** It requires
|
|
354
352
|
the decision it rests on to exist somewhere a reader can reach — a wiki page,
|
|
355
353
|
a memory entry, an ADR, a test that pins the behaviour. "It is fine" is
|
|
356
354
|
`unverified`.
|
|
357
|
-
3. **Never lower a comment's severity to make it disappear.** Severity is set by
|
|
358
|
-
the collector; this step assigns a *verdict*, and a `minor` comment that is
|
|
359
|
-
`valid` is still fixed.
|
|
355
|
+
3. **Never lower a comment's severity to make it disappear.** Severity is set by the collector; this step assigns a *verdict*, and a `minor` comment that is `valid` is still fixed. The premise judge cannot lower it either (rule 7).
|
|
360
356
|
4. **`needs-clarification` is asked before `--fix` runs, not after.** State both
|
|
361
357
|
readings and what each would change. A guess here produces a fix nobody asked
|
|
362
358
|
for and a reply that answers the wrong question.
|
|
@@ -367,6 +363,7 @@ Rules, and each one is a way this step goes wrong:
|
|
|
367
363
|
6. **A `praise` comment takes no verdict.** It makes no claim about the code, so
|
|
368
364
|
there is nothing to establish. It is still answered in Step 10, because the
|
|
369
365
|
reply pass requires a decision for every comment it sees.
|
|
366
|
+
7. **A `valid` comment has its premise checked before it enters the plan.** Before Step 8, dispatch `review-premise` with `source: external-comment` over the `valid` and `valid-wider` comments of severity `minor` or above, each as one finding: `id` its collected `C-NNN`, `url` its URL, `reviewer` its author, `source: external`, the comment text and its `file:line` refs (review-premise, `source` row). An external finding is upheld, challenged or owner-decision, never downgraded. This skill has no review package, so no `ingest` or `decide-premise` runs: save the claims object unchanged beside the durable record, as `.metaproject/reviews/pr-comments/<owner>__<repo>__<n>.premise.json`, apply the merge's refusals by hand (the same `source` row lists them), and record each claim on the comment's Step 7 entry (**Premise**). A `challenged` or `owner-decision` comment is held: ask the operator its question with its options (`ask_user` in keryx shell, the host's question tool elsewhere) and record their answer, in their words, on that entry: it is the one record of it, which a resumed or `--fix` run reads, and the report's Stats count it. An upheld comment is planned and passed in `fix_context.review_feedback`, carrying `premise_verdict` and `premise_answer` as task-implementer's `FIX_CONTEXT` defines them; a dismissed one takes verdict `disagree`, citing that recorded answer as its decision (rule 2), and is answered in Step 10 with no code change. Never dismiss it yourself.
|
|
370
367
|
|
|
371
368
|
---
|
|
372
369
|
|
|
@@ -390,6 +387,7 @@ For each comment:
|
|
|
390
387
|
```typescript
|
|
391
388
|
// Corrected code example
|
|
392
389
|
```
|
|
390
|
+
- **Premise** (rule 7): upheld, or held with the judge's question and the operator's answer in their words
|
|
393
391
|
- **Plan item**: P-00N, or "none" with the reason
|
|
394
392
|
- **Confidence**: High | Medium | Low
|
|
395
393
|
- High: reviewer's intent is clear and the fix is straightforward
|
|
@@ -453,8 +451,8 @@ it into a fix the reviewer did not ask for.
|
|
|
453
451
|
|
|
454
452
|
1. `--fix` was passed explicitly.
|
|
455
453
|
2. Step 3 ran through the CLI and the durable record exists.
|
|
456
|
-
3. No comment is still `needs-clarification
|
|
457
|
-
`prompt-injection` finding.
|
|
454
|
+
3. No comment is still `needs-clarification` or held without the operator's answer
|
|
455
|
+
(rule 7), and none carries an unreviewed `prompt-injection` finding.
|
|
458
456
|
4. The working tree is clean and Task Manager is enabled
|
|
459
457
|
(`modules.tasks.enabled: true`).
|
|
460
458
|
5. The reviewed PR is open.
|
|
@@ -524,7 +522,7 @@ branch on purpose.
|
|
|
524
522
|
"operator_confirmed": { "confirmed_by": "<who>", "confirmed_at": "<iso8601>", "plan_digest": "<digest of the plan shown>" },
|
|
525
523
|
"constraints": [
|
|
526
524
|
"pr: open it as a draft, titled 'fix(review): address feedback on #<n>', body linking #<n> and listing which plan item answers which comment.",
|
|
527
|
-
"review: run review-orchestrator on every round, starting each round with `keryx review start` (or `keryx review plan`) on the new head: the round, its range and the prior findings come from `round.json`. No own range, no `--all` per round, no whole-branch re-review. The loop's exit threshold is the one your own PR review/fix loop defines; do not take it from this string.",
|
|
525
|
+
"review: run review-orchestrator on every round, starting each round with `keryx review start` (or `keryx review plan`) on the new head: the round, its range and the prior findings come from `round.json`. No own range, no `--all` per round, no whole-branch re-review. The loop's exit threshold is the one your own PR review/fix loop defines; do not take it from this string. Every plan item's comment was premise-checked in review-pr-feedback rule 7 and each held one answered by the operator (its Premise entry; claims in .metaproject/reviews/pr-comments/<owner>__<repo>__<n>.premise.json): do not run review-premise again before freeze.",
|
|
528
526
|
"review: the fix PR is its own conversation — collect and reply on IT as normal. The round MUST NOT run a reply pass against #<n>: a reply there writes the durable record, so the post-merge answer citing the merge SHA is skipped as already-handled and the reviewer is left holding a mid-loop answer that has since stopped being true.",
|
|
529
527
|
"attempt budget: at most <max_fix_rounds> review/fix attempts. This LOWERS your bound and never raises it; absent the value, your own bound stands. The `keryx review loop` repetition check applies either way. Do not raise anything to reach a clean round; escalate instead.",
|
|
530
528
|
"scope: the plan items only. A finding outside them is recorded as follow-up, not fixed in this flow."
|
|
@@ -812,7 +810,7 @@ Full markdown report structure:
|
|
|
812
810
|
|
|
813
811
|
## Stats
|
|
814
812
|
- blocker: N / major: N / minor: N / info: N / praise: N
|
|
815
|
-
- verdicts: valid N, already-fixed N, disagree N, out-of-scope N, unverified N
|
|
813
|
+
- verdicts: valid N, already-fixed N, disagree N, out-of-scope N, unverified N; premise: upheld N, held N (each answer is on its Step 7 **Premise** entry)
|
|
816
814
|
|
|
817
815
|
## By Author
|
|
818
816
|
### <reviewer-login> (N comments — REQUEST_CHANGES)
|