@mrciphersmith/keryx 0.3.116 → 0.3.118
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/README.md +1 -1
- package/dist/cli.js +5098 -2892
- package/dist/core.js +718 -9
- package/package.json +1 -1
- package/src/gdskills/bundled/skills/review/review-architecture/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/review/review-backend/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/review/review-clean-code/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/review/review-core-boundaries/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/review/review-flow-graph/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/review/review-frontend/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/review/review-frontend-conventions/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/review/review-highload/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/review/review-jev-comments/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/review/review-jev-contract/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/review/review-jev-docs/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/review/review-jev-risk/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/review/review-jev-rules/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/review/review-jev-scenarios/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/review/review-layout/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/review/review-logic/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/review/review-orchestrator/SKILL.detail.md +95 -10
- package/src/gdskills/bundled/skills/review/review-orchestrator/SKILL.md +37 -37
- package/src/gdskills/bundled/skills/review/review-performance/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/review/review-pr-contract/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/review/review-pr-feedback/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/review/review-regression/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/review/review-security-code/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/review/review-style/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/review/review-testing-practices/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/review/review-verifier/SKILL.md +1 -1
|
@@ -28,6 +28,15 @@ license: "MIT"
|
|
|
28
28
|
`STATUS: BLOCKED nested_dispatch_unavailable — run this skill in the main session`
|
|
29
29
|
2. **Is a round needed?** List the files with `git diff --name-status --no-renames <base>...HEAD`, so a rename shows both paths. A diff where EVERY file is prose or machine-written data ends here with one line, `round not needed: <reason>`, and no reviewer. Prose is exactly: README or CHANGELOG at any depth; CONTRIBUTING, LICENSE, SECURITY or CODE_OF_CONDUCT at the top level; and under `docs/`, `.metaproject/wiki`, `.metaproject/reviews` or a flow's `journal.md`, a file with extension md, rst or adoc whose name holds a lowercase letter (an all-uppercase name such as AGENT or WARP is steering by convention). Machine-written data is a file under `coverage/` or `__generated__/` with extension lcov, info or map only; json, txt, html and md there are code. Steering is code wherever it sits, `docs/` included: a directory (singular or plural) named agent, skill, command, rule, prompt, instruction, persona, steering or hook, any path segment starting with a dot (`.claude`, `.cursorrules`, `.mcp.json`), a file name starting with SKILL, AGENT, CLAUDE, GEMINI, QWEN, CODEX, WARP, CRUSH, JULES, KNOWLEDGE, GUIDELINES, CONVENTIONS or copilot-instructions, ending in .local, .override, .instructions, .prompt, .agent or .chatmode before the extension, or containing prompt, instruction or system. A flow's `description.md`, `acceptance-criteria.md` and `tasks/` are gate inputs, so they are code. Every other file counts as code too, including lockfiles, committed `dist/` output, CI, auth, migrations, config JSON, and any path with `..`, a backslash, a leading `./` or `//`. `classifyRoundNeed` in `src/review/round-need.ts` is the tested reference of this rule; the host executes this text, and nothing in the CLI calls the function yet. `--all`, an explicit reviewer list or a gating round forces a round.
|
|
30
30
|
3. **Round ceiling.** 5 rounds (`REVIEW_ROUND_CAP`) over the same `merge-base..HEAD`. Past it: interactive, ask the operator; unattended, `STATUS: BLOCKED round_cap`.
|
|
31
|
+
4. **PR state, shown before dispatch.** On a PR target read its state (merged, approved, CI) and tell the operator the risk that it merges before the round ends: a verdict ready at minute 55 and held to minute 119 lost the race to the merge. Depth and the estimate need the package and the slice manifest, so they come later: after `review scope`, `review start` and `review slice`, before the first reviewer starts (Step 6; `SKILL.detail.md` § "Preflight 4").
|
|
32
|
+
|
|
33
|
+
## Clean context — the round starts empty
|
|
34
|
+
|
|
35
|
+
Context comes only from your own context stages: scope, the Review Context Pack, the memory stage and the layers. Your session memory, the auto-memory index (`MEMORY.md`), remembered feedback and the earlier conversation are not inputs: do not read, quote or apply them.
|
|
36
|
+
- **Accepted exceptions, the only three:** `prior_findings` of an earlier round of the same package; review-notes and learning that reach you through the memory stage; a reviewer's own `memory_search`.
|
|
37
|
+
- **One memory read.** Run the stage query once and record it with `keryx review start … --memory-query "<query>"`. keryx writes `<package>/tool-calls/orchestrator.jsonl` itself from the moment the package starts: never create, edit or append to it. Readiness item 10, `memory-outside-stage`, blocks `review complete` and `review publish` on any other memory call; only `--waive memory-outside-stage "<operator quote>"` from a terminal lifts it. Detail: `SKILL.detail.md` § "Clean context".
|
|
38
|
+
- **Open question.** Look in this skill and `SKILL.detail.md` first. If the answer is not there, ask the user: one `AskUserQuestion` interactively; unattended, the whole output is `STATUS: BLOCKED question — <the question>`. Never answer from memory or a guess.
|
|
39
|
+
- **Named limit.** keryx cannot stop a runtime that loads the agent's memory before this skill starts, and reads of personal memory outside `keryx memory` are not visible to the log. The guarantee is instruction plus detection, not isolation.
|
|
31
40
|
|
|
32
41
|
## Workflow
|
|
33
42
|
|
|
@@ -38,26 +47,23 @@ Review Orchestrator Progress:
|
|
|
38
47
|
- [ ] Step 1: Build Review Context Pack — PR metadata AND the PR's own description, scope, rules, context_doc summary, accepted memory, and the cross-repo contracts the diff consumes (prose step: no `keryx review` command builds it; do it, tick it, move on)
|
|
39
48
|
- [ ] Step 2: Detect review mode (diff mode vs. path mode)
|
|
40
49
|
- [ ] Step 3: Build the bounded scope with `keryx review scope` — never by hand
|
|
41
|
-
- [ ] Step 3b: On a deep round, compute scope B with `keryx review blast-radius` — never by browsing — and KEEP the `--json` file; `review ingest --blast-radius <file>` is refused without it
|
|
50
|
+
- [ ] Step 3b: On a deep round, compute scope B with `keryx review blast-radius` — never by browsing — and KEEP the `--json` file; `review ingest --blast-radius <file>` is refused without it. When it says "Cut blast radius", the dropped files are not read yet: run the waves (`keryx review chunks plan`, `chunks estimate`, `chunks next`/`record`, `chunks merge`) — in an unattended run without asking, up to the 25-pass ceiling
|
|
42
51
|
- [ ] Step 4: Parse flags / auto-detect domain from scope
|
|
43
|
-
- [ ] Step 5: Start questions, once, after Steps 1 and 3 — reviewers (default `--all`), counterpart verification (default on), model plan; unattended — and an `auto` or `trust` shell session, which has no operator at the keyboard — takes the defaults (SKILL.detail.md § "Start questions"; legacy/profile reviewers stay flag-only)
|
|
52
|
+
- [ ] Step 5: Start questions, once, after Steps 1 and 3 — reviewers (default: the set `keryx review required --depth auto` prints; `--all` only when the operator asks), counterpart verification (default on), model plan; unattended — and an `auto` or `trust` shell session, which has no operator at the keyboard — takes the defaults (SKILL.detail.md § "Start questions"; legacy/profile reviewers stay flag-only)
|
|
44
53
|
- [ ] Step 5c: When `review.jev.select` is on, run `keryx review jev-select` over the finalized candidate set and drop its `skip` decisions from Wave A/B — see "Reviewer selection with Jev"
|
|
45
|
-
- [ ] Step 6: Plan sub-agent dispatch and token budgets; compute each dispatch's model with `keryx review tier` (6a: publish this plan)
|
|
54
|
+
- [ ] Step 6: Plan sub-agent dispatch and token budgets; compute each dispatch's model with `keryx review tier`; after `review scope`, `review start` and `review slice`, and before the first reviewer starts, run `keryx review required --mode all --scope .metaproject/data/review/scope.json --depth auto [--package <review-dir>]` (auto needs the file list AND a line count, which `--scope` gives; without both the round is full) and `keryx review estimate --package <review-dir> [--manifest <slices/manifest.json>]`, and show the operator depth, estimate and merge risk (6a: publish this plan)
|
|
46
55
|
- [ ] Step 7: Stage 1 gate - spec compliance check (if issue/task provided)
|
|
47
56
|
- [ ] Step 8: Dispatch selected reviewers in parallel with the reviewer-input schema — see "How to spawn"
|
|
48
57
|
- [ ] Step 9: Collect reviewer-finding schema results and handle NEEDS_CONTEXT
|
|
49
58
|
- [ ] Step 9b: `jev-triage` — advisory, annotate-only severity/duplicate/verify-order annotations over the consolidated findings (opt-in `review.jev.triage`)
|
|
50
|
-
- [ ] Step 10: Wave C — when blockers/majors exist, `--verify` is set, or the PR is high-risk, dispatch `review-verifier` over the
|
|
59
|
+
- [ ] 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
|
|
51
60
|
- [ ] Step 11: Sort by severity, deduplicate, emit unified report
|
|
52
61
|
- [ ] Step 12: Emit the machine-readable `keryx:findings` block alongside the report
|
|
53
62
|
- [ ] Step 13: Report the stage counts: dropped by pre-filter, refuted by the verifier, retained
|
|
54
63
|
- [ ] 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` and get the user's explicit approval first; unattended: do not publish, hand the rendered body back) — never against a pull request the dispatch named as the caller's
|
|
55
64
|
```
|
|
56
65
|
|
|
57
|
-
Step 0 runs on **every** round. Step 14 runs **once**, after the last one. They are
|
|
58
|
-
two commands for that reason: a caller that already runs collection per round
|
|
59
|
-
would carry the posting along with it, and the reviewer would get six replies to
|
|
60
|
-
one comment.
|
|
66
|
+
Step 0 runs on **every** round. Step 14 runs **once**, after the last one. They are two commands for that reason: a caller that already runs collection per round would carry the posting along with it, and the reviewer would get six replies to one comment.
|
|
61
67
|
|
|
62
68
|
### Step 6 — the model is computed, not chosen
|
|
63
69
|
|
|
@@ -73,19 +79,19 @@ Publish this checklist with `plan_set` under the ids `step-0`…`step-14` once,
|
|
|
73
79
|
|
|
74
80
|
- One `Agent` call per reviewer, all calls of a wave in a single message, so the wave runs in parallel.
|
|
75
81
|
- 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`.
|
|
76
|
-
- Prompts carry pointers, not pasted files — the diff, the SHAs, the PR, the schema paths — and never paraphrase a contract.
|
|
82
|
+
- Prompts carry pointers, not pasted files — the diff, the SHAs, the PR, the schema paths — and never paraphrase a contract. On a shell host the rule below replaces this one. Run `keryx review dispatch-check --payload <file> --manifest <dir>/manifest.json` on every payload before a mass dispatch; it fails `REVIEWER_INPUT_PATH_MISSING` on a missing `skill_path` or `context_doc`.
|
|
77
83
|
- 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`.
|
|
78
84
|
- 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`; an omitted tier runs the child on your own model.
|
|
79
85
|
|
|
80
86
|
## Shell host (keryx shell, or any host with no file-reading subagent) — mandatory
|
|
81
87
|
|
|
82
|
-
A reviewer on this host
|
|
88
|
+
A reviewer on this host starts in the project root and can read project files, but a path outside the project root is unreadable to it, and `context_files` content reaches it wrapped as DATA. The one rule: slices and measurements travel only in `spawn_subagent`'s `context_files` (never pasted or retyped); `skill_path` and `pr_context` stay payload fields. The text reaches the reviewer in slices small enough to finish.
|
|
83
89
|
|
|
84
90
|
0. **Publish the plan before anything else.** 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.
|
|
85
91
|
1. **Slice first.** `keryx review slice --ref <base> --out <dir>` after `keryx review scope`. It writes `slice-NN.diff` files of at most 150000 bytes each and a `manifest.json` carrying a wave budget (`--wave-bytes`, default 60000 and never below the slice ceiling): what ONE reviewer dispatch may total, so a role owning many slices is dispatched in slice waves that each fit the child deadline. On 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.
|
|
86
|
-
2. **Slices travel by `context_files`.** Write the slices under the project (the default `--out`, `.metaproject/data/review/slices`, already is) and 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. Put the `slices` ids in its reviewer-input. A dispatch that names a git range but no slice and no `context_files` leaves the reviewer with nothing to read — that is `BLOCKED`, not a review.
|
|
87
|
-
3. **Check before dispatch.** `keryx review dispatch-check --payload <file> --manifest <dir>/manifest.json` for the wave; exit 1 means a payload names no slice, is over the wave ceiling (dispatch fewer slices, then the next wave), or breaks `reviewer-input.schema.json`. Fix it; do not dispatch around it.
|
|
88
|
-
4. **One batch.** Dispatch the whole wave — up to 10 reviewers — in one message, not one at a time. Give each reviewer `max_rounds` of at least 40 (the default); a reviewer that spends its rounds reading the skill and the schema returns nothing. **Incomplete means the next wave while it makes progress, Not run when it stalls.** Every reviewer result lists the `slices` it covered, in its `REVIEW_RESULT` object, as ids (`"slices": ["slice-01", "slice-02"]`); an object with an `id` and an optional `coverage` note (`{"id": "slice-01", "coverage": "read in full"}`) is read the same way. An object with a `status` counts only when it is DONE, COMPLETE, COVERED or OK (any case); a slice marked NOT_READ, INCOMPLETE, SKIPPED or PARTIAL is not covered, so give a slice you did not read no `status` of that kind and leave it out. An entry with no id counts for nothing. **One driver file per dispatch.** Write `drivers/<reviewer>.json` next to `raw/` with `{"reviewer": "<name>", "slices": [<ids dispatched>], "result": "raw/<reviewer>.txt", "definition": "<path of the reviewer's SKILL.md>"}`: `ledger build` takes the reviewer's rule file from `definition` (a `skill_path` there, or inside a `payload` object, is read too) and the slices it was handed from `slices`. Only reviewer replies belong in `raw/`; a verification payload or a note filed there is reported as set aside and left in place, but it still costs a step. On `INCOMPLETE`, `BLOCKED` or `NEEDS_CONTEXT` (never accepted as a finished scope), and on a `DONE` that left slices open, `keryx review retry-plan --manifest <dir>/manifest.json --result <raw/reviewer.txt>` decides and hands out the next wave of only the slices still uncovered (`--next-wave` plans one without a result). A result that covered a new slice spends no attempt; two results in a row with nothing new, or six failed rounds, print the `- **Not run:** …` line to paste into the report, and a result with nothing new first has its open slices cut in half. Dispatch each wave, save its reply, and run `retry-plan` again until it says `accepted
|
|
92
|
+
2. **Slices travel by `context_files`, and only by `context_files`.** Write the slices under the project (the default `--out`, `.metaproject/data/review/slices`, already is) and 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. Put the `slices` ids in its reviewer-input. A dispatch that names a git range but no slice and no `context_files` leaves the reviewer with nothing to read — that is `BLOCKED`, not a review.
|
|
93
|
+
3. **Check before dispatch, every payload.** `keryx review dispatch-check --payload <file> --manifest <dir>/manifest.json` 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`), or breaks `reviewer-input.schema.json`. Fix it; do not dispatch around it.
|
|
94
|
+
4. **One batch.** Dispatch the whole wave — up to 10 reviewers — in one message, not one at a time. Give each reviewer `max_rounds` of at least 40 (the default); a reviewer that spends its rounds reading the skill and the schema returns nothing. **Incomplete means the next wave while it makes progress, Not run when it stalls.** Every reviewer result lists the `slices` it covered, in its `REVIEW_RESULT` object, as ids (`"slices": ["slice-01", "slice-02"]`); an object with an `id` and an optional `coverage` note (`{"id": "slice-01", "coverage": "read in full"}`) is read the same way. An object with a `status` counts only when it is DONE, COMPLETE, COVERED or OK (any case); a slice marked NOT_READ, INCOMPLETE, SKIPPED or PARTIAL is not covered, so give a slice you did not read no `status` of that kind and leave it out. An entry with no id counts for nothing. **One driver file per dispatch.** Write `drivers/<reviewer>.json` next to `raw/` with `{"reviewer": "<name>", "slices": [<ids dispatched>], "result": "raw/<reviewer>.txt", "definition": "<path of the reviewer's SKILL.md>"}`: `ledger build` takes the reviewer's rule file from `definition` (a `skill_path` there, or inside a `payload` object, is read too) and the slices it was handed from `slices`. Only reviewer replies belong in `raw/`; a verification payload or a note filed there is reported as set aside and left in place, but it still costs a step. On `INCOMPLETE`, `BLOCKED` or `NEEDS_CONTEXT` (never accepted as a finished scope), and on a `DONE` that left slices open, `keryx review retry-plan --manifest <dir>/manifest.json --result <raw/reviewer.txt>` decides and hands out the next wave of only the slices still uncovered (`--next-wave` plans one without a result). A result that covered a new slice spends no attempt; two results in a row with nothing new, or six failed rounds, print the `- **Not run:** …` line to paste into the report, and a result with nothing new first has its open slices cut in half. Dispatch each wave, save its reply, and run `retry-plan` again until it says `accepted`; after a crash or timeout run `keryx review retry-plan --manifest <slices>/manifest.json --package <input-dir> --reviewer <id> --next-wave` first, which collects late results from `<input-dir>/raw/` (per reviewer) and never re-hands a finished slice. Only the operator can accept a smaller set than that, with their own quote. An unfinished reviewer is never counted as a clean pass. **Persist every result.** Pass each reviewer `save_result_to: .metaproject/data/review/raw/<reviewer>.txt`: the host writes its full final text there, so `review complete` has raw evidence even after the transcript is cut. Build `research.json` with `keryx review ledger build <input-dir> --package <review-dir>` — never by hand: it reads the saved results, `scope-files.json` and the retry state, marks a reviewer complete only when its result is finished and its payloads cover the scope, and prints each gap with the exact next command and the waves left (a `retry-plan --next-wave` call, or a `--dispositions` entry for a raw finding). Run `keryx review ingest --research <review-dir>/research.json` once it prints READY (exit 0). A refused `review complete` names what is missing: fix that with a command and run it again; it is never `blocked`. `--head` wants a SHA (`git rev-parse HEAD`), not `HEAD`.
|
|
89
95
|
5. **Never print a scope or a slice.** The tool output of one call is cut at about 20 KB and `keryx review scope` of a large PR prints hundreds of KB. Run it as `keryx review scope --ref <base> --json > .metaproject/data/review/scope.json` and read the counts from the file (`keryx ctx read`, or `jq`); take `<base>` from `git symbolic-ref refs/remotes/origin/HEAD`, not a guessed `origin/main`. Create `.metaproject/data/review/` first (`mkdir -p`) — a missing directory is a command to run, not a blocker. **Machine artifacts by direct write.** Save slices, payloads and results by redirection or `keryx ctx run --raw -- <command>`; the summarized form of `keryx ctx run` drops the bytes a later step parses.
|
|
90
96
|
6. **Write mutants whole.** A testing reviewer's `mutant_candidates` cover every changed branch, code downstream of the diff included. Write them to `research-evidence/mutants.json` unchanged; you may not narrow them, and a candidate no pass has run still blocks the coverage gate (`SKILL.detail.md`, mutation pass).
|
|
91
97
|
7. **Measure before `review-layout`.** Run the browser measurements (Playwright/Storybook) yourself and pass them as `context_files` in its first dispatch; they count as evidence when the command and viewport are named. A second `NEEDS_CONTEXT` from one role is Not run (`layout: no engine`), not another refill (`SKILL.detail.md`).
|
|
@@ -93,9 +99,11 @@ A reviewer on this host cannot open a path: its file tool reads inside its worki
|
|
|
93
99
|
## Control
|
|
94
100
|
|
|
95
101
|
- **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).
|
|
96
|
-
- **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. A full or `--all` round runs at most 10 reviewers per wave (`MAX_REVIEWERS_PER_WAVE_FULL`).
|
|
102
|
+
- **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`).
|
|
97
103
|
- **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.
|
|
98
|
-
- **
|
|
104
|
+
- **Early verdict.** When every reviewer and the verifier are done, save every verifier pass to `research-evidence/verifications.json`, then run `keryx review verdict <id|path> --raw .metaproject/data/review/raw` (the raw dir this round uses; the default is `<package>/raw`) 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").
|
|
105
|
+
- **Recovery.** After a timeout or crash: collect, validate, ingest, then dispatch only what is missing with `keryx review retry-plan --manifest <slices>/manifest.json --package <input-dir> --reviewer <id> --next-wave` (it prints `collected late: N`). 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").
|
|
106
|
+
- **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 a terminal (`keryx review complete --waive <item> "<their words>"`); publishing to GitHub is held by the same checklist, and a not-ready package goes out only through `keryx review publish --partial`.
|
|
99
107
|
|
|
100
108
|
---
|
|
101
109
|
|
|
@@ -610,12 +618,6 @@ Two rules, both load-bearing:
|
|
|
610
618
|
whose recorded scope does not intersect the changed files or modules are noise
|
|
611
619
|
that costs budget in every reviewer prompt.
|
|
612
620
|
|
|
613
|
-
Why this is required rather than advisory: `keryx flow init` already collects
|
|
614
|
-
memory automatically for an implementation flow, and the review pipeline
|
|
615
|
-
collected none for eleven rounds across flows 127 and 128. A recorded lesson
|
|
616
|
-
naming the exact failure those rounds kept repeating existed the whole time and
|
|
617
|
-
never reached a reviewer.
|
|
618
|
-
|
|
619
621
|
Context modes:
|
|
620
622
|
- `none`: no additional context collection; use only diff/path and local rules.
|
|
621
623
|
- `light`: default for PR review. Read existing `context_doc`, local `AGENTS.md`/`CLAUDE.md`, and matching rule files. Do not browse external docs.
|
|
@@ -623,7 +625,7 @@ Context modes:
|
|
|
623
625
|
|
|
624
626
|
High-risk triggers for `full` recommendation:
|
|
625
627
|
- Auth, permissions, API contracts, a client-side mirror of a server rule (validation, limit, permission, uniqueness, reserved names), migrations, shared core, state management, graph/flow, security, performance-critical paths.
|
|
626
|
-
- More than 20 changed source files or more than 2,000 changed lines. Size never lowers depth below the risk class (SKILL.detail.md § "Depth floor").
|
|
628
|
+
- More than 20 changed source files or more than 2,000 changed lines. Size never lowers depth below the risk class; outside it the light round is the default and `full` stays available (SKILL.detail.md § "Depth floor").
|
|
627
629
|
- Missing or ambiguous linked requirements.
|
|
628
630
|
|
|
629
631
|
If `full` context would be useful but was not explicitly requested, ask once:
|
|
@@ -817,7 +819,7 @@ keryx review blast-radius --ref "${BASE_SHA}" --package "${PKG}" --previous blas
|
|
|
817
819
|
```
|
|
818
820
|
|
|
819
821
|
`PKG` is the review package, created by `keryx review start` before dispatch; `--package` makes scope B read the graph built at the PR head. Give each reviewer `keryx review layers block --package "${PKG}" --files <its slice files> --json` as the payload's `layers` field.
|
|
820
|
-
When `dropped` is non-empty, run `keryx review chunks plan|estimate|next|record|merge --package "${PKG}"` until `next` has none left. `review complete` refuses while a file is uncovered; `--waive-coverage "<operator quote>"` takes the operator's own words only, never yours.
|
|
822
|
+
When `dropped` is non-empty, run `keryx review chunks plan|estimate|next|record|merge --package "${PKG}"` until `next` has none left. `review complete` refuses while a file is uncovered; `--waive-coverage "<operator quote>"` takes the operator's own words only, never yours. Pass `review_wave: {"package": "${PKG}", "pass": "<chunk id>"}` on every `spawn_subagent` of a chunk pass (`"pass": "round"` for the round's own reviewers): each wave counts its own 32 children and one turn opens at most 25 waves; a wave the package does not record is ignored and counts against the turn's 32.
|
|
821
823
|
The measurements, the rule table and the recompute table: `SKILL.detail.md` § "Scope B — bounds, rejections and recompute".
|
|
822
824
|
|
|
823
825
|
### Path Mode
|
|
@@ -977,7 +979,7 @@ author's routing note, not a restriction.
|
|
|
977
979
|
Ask once, after the context pack (Step 1) and the scope (Step 3), in one interaction — one
|
|
978
980
|
`AskUserQuestion` call on Claude Code, the lettered prompt in SKILL.detail.md elsewhere:
|
|
979
981
|
|
|
980
|
-
1. **Reviewers** — default `--all
|
|
982
|
+
1. **Reviewers** — default the set `keryx review required --depth auto` prints (light or full); `--all` only when the operator asks; detected convention reviewers are included. Narrowing
|
|
981
983
|
(tests only, one domain, custom) is the operator's explicit choice. Passed flags answer it.
|
|
982
984
|
Legacy/profile reviewers stay flag-only and are never prompted.
|
|
983
985
|
2. **Counterpart** — show what the context pack found for the other side of the contract
|
|
@@ -987,7 +989,7 @@ Ask once, after the context pack (Step 1) and the scope (Step 3), in one interac
|
|
|
987
989
|
3. **Models** — complexity, the per-role tier from `keryx review tier`, the model each tier
|
|
988
990
|
resolves to on this host; accept (default), all `deep`, or custom. Once per round.
|
|
989
991
|
|
|
990
|
-
Unattended rounds ask nothing:
|
|
992
|
+
Unattended rounds ask nothing: the `required --depth auto` set, counterpart verified, computed models — recorded in
|
|
991
993
|
`### How this review was run`. In a `job-orchestrator` pipeline the job setting
|
|
992
994
|
`convention_reviewers` still answers question 1 (unresolved: include all detected reviewers
|
|
993
995
|
and record that choice in the review scope).
|
|
@@ -1062,7 +1064,7 @@ Skipped reviewers:
|
|
|
1062
1064
|
| `--layout` | `review-layout` |
|
|
1063
1065
|
| `--pr-contract` | `review-pr-contract` |
|
|
1064
1066
|
| `--all` | all reviewers above (including `review-clean-code`, `review-highload`, applicable legacy/profile reviewers, and project convention reviewers when local convention docs exist) |
|
|
1065
|
-
| `--verify` | `review-verifier`,
|
|
1067
|
+
| `--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. |
|
|
1066
1068
|
| (auto) | detected from diff file extensions — see Auto-detection table |
|
|
1067
1069
|
|
|
1068
1070
|
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.
|
|
@@ -1108,14 +1110,13 @@ whoever reads the merge commit a year later reads the body. When `review.jev.con
|
|
|
1108
1110
|
|
|
1109
1111
|
**Dispatch integrity is a completion prerequisite.** Use one distinct execution per selected reviewer role; do not combine multiple roles in one child or count sections of one response as independent runs. When budgets are tight, use sequential waves, not role batching. Resolve every project-rule anchor before dispatch; missing rules require context recovery or a blocked result, never silently skipped checks. A read-only pass cannot discharge executable obligations: dispatch a capable execution pass and retain its evidence. Partial scope and NEEDS_CONTEXT remain incomplete until rerun over the outstanding scope.
|
|
1110
1112
|
|
|
1111
|
-
**The reviewer set is not yours to shrink.** Run `keryx review required --mode all|diff --scope <scope.json>` (`all` for a pull request, for `--all` and for no narrowing flag; `diff` only when the operator named a narrower mode — pass their words as `--operator-quote` and record them as `dispatch.operatorQuote`, without which the dispatch is refused), dispatch every reviewer it prints, and declare `mode` in `dispatch`; pass the same `--scope` to `keryx review start|ingest` so the package keeps the file list. Closure refuses a smaller set unless `dispatch.override = { operatorQuote, reason }` carries the operator's own words. New managed packages declare `reviewerDispatch: "research.json"`. Alongside the research ledger, provide `dispatch: { version: 1, mode: "all"|"diff", selected: [...], unresolvedRules: [], runs: [...] }`. Preserve the actual computed reviewer inventory. Each run has `reviewer`, unique `executionId`, `status: "complete"`, `scopeComplete: true`, `rawEvidence`, nonempty `ruleEvidence`, and boolean `executionRequired`. Required execution needs nonempty `executionEvidence` (command/output references); a source-only scope requires `executionReason`. Do not fabricate IDs or mark truncated responses complete. Runtime validates these declarations at closure and the flow gate, not their truth: independently audit evidence and inventory before freezing. Legacy artifact absence is compatibility, not proof of a correct launch. Research closure is mandatory: see [Runtime research-completion ledger](SKILL.detail.md#runtime-research-completion-ledger).
|
|
1113
|
+
**The reviewer set is not yours to shrink.** Run `keryx review required --mode all|diff --scope <scope.json>` (`all` for a pull request, for `--all` and for no narrowing flag; `diff` only when the operator named a narrower mode — pass their words as `--operator-quote` and record them as `dispatch.operatorQuote`, without which the dispatch is refused), dispatch every reviewer it prints (`--depth auto` is the default and the only way to a light round: it needs the file list and a line count, `--scope` gives both; `--all`, gating and `--depth full` force full; see `SKILL.detail.md` § "Depth floor"), and declare `mode` in `dispatch`; pass the same `--scope` to `keryx review start|ingest` so the package keeps the file list. Closure refuses a smaller set unless `dispatch.override = { operatorQuote, reason }` carries the operator's own words. New managed packages declare `reviewerDispatch: "research.json"`. Alongside the research ledger, provide `dispatch: { version: 1, mode: "all"|"diff", selected: [...], unresolvedRules: [], runs: [...] }`. Preserve the actual computed reviewer inventory. Each run has `reviewer`, unique `executionId`, `status: "complete"`, `scopeComplete: true`, `rawEvidence`, nonempty `ruleEvidence`, and boolean `executionRequired`. Required execution needs nonempty `executionEvidence` (command/output references); a source-only scope requires `executionReason`. Do not fabricate IDs or mark truncated responses complete. Runtime validates these declarations at closure and the flow gate, not their truth: independently audit evidence and inventory before freezing. Legacy artifact absence is compatibility, not proof of a correct launch. Research closure is mandatory: see [Runtime research-completion ledger](SKILL.detail.md#runtime-research-completion-ledger).
|
|
1112
1114
|
|
|
1113
1115
|
Dispatch selected reviewers in parallel when independent — this engine dispatches them itself (see "How to spawn"); a host without a dispatch tool returns `STATUS: BLOCKED` (`nested_dispatch_unavailable`) and never reviews alone — Preflight 1. Waves follow the diff domains in "Control" and keep their dependency order:
|
|
1114
1116
|
|
|
1115
1117
|
1. Wave A - core correctness/risk reviewers: logic, architecture, security/highload when selected.
|
|
1116
1118
|
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".
|
|
1117
|
-
3. Wave C - **verification**: `review-verifier` over the
|
|
1118
|
-
exist, `--verify` is set, or the PR is high-risk. See below.
|
|
1119
|
+
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.
|
|
1119
1120
|
|
|
1120
1121
|
**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.
|
|
1121
1122
|
|
|
@@ -1151,7 +1152,7 @@ would be claim order.
|
|
|
1151
1152
|
|
|
1152
1153
|
Dispatch rules:
|
|
1153
1154
|
|
|
1154
|
-
- Pass the consolidated
|
|
1155
|
+
- Pass the findings held when this pass starts (the whole consolidated set on the last pass), each carrying `global_id` and the **real**
|
|
1155
1156
|
originating `reviewer`. A finding whose `reviewer` is the orchestrator cannot be
|
|
1156
1157
|
routed away from its author, so the never-self-verify rule silently stops
|
|
1157
1158
|
applying — that field was hardcoded to `review-orchestrator` on all 83 recorded
|
|
@@ -1164,6 +1165,7 @@ Dispatch rules:
|
|
|
1164
1165
|
all the same actor. Do not try to route around it by respelling the name — the
|
|
1165
1166
|
comparison deliberately over-matches, because a refused claim only ever costs a
|
|
1166
1167
|
verdict while a missed self-verification costs the finding.
|
|
1168
|
+
- Start it on the first blocker or major and re-run it for later ones; it stays delete-only.
|
|
1167
1169
|
- The verifier returns `verification-claim.schema.json`. Merge it with
|
|
1168
1170
|
`keryx review ingest --verifications <file>`; do not apply verdicts by hand.
|
|
1169
1171
|
- **The verifier can only delete.** If it returns a severity, a new finding, or a
|
|
@@ -1328,6 +1330,9 @@ someone who did not write it — and has not read the code — reaches the same
|
|
|
1328
1330
|
answer: look for the trigger and the outcome. Present → `major`. Absent, but a
|
|
1329
1331
|
concrete maintenance cost is named → `minor`. Neither → `info`.
|
|
1330
1332
|
|
|
1333
|
+
A surviving mutant shows a missing assertion, not wrong behaviour: a test gap in code the
|
|
1334
|
+
suite exercises is `minor`; `severity-audit` raises it only when no mutant in that file was killed.
|
|
1335
|
+
|
|
1331
1336
|
Two consequences, both previously decided differently in different files:
|
|
1332
1337
|
|
|
1333
1338
|
- A finding that **claims** runtime harm and cannot name the trigger is `info`,
|
|
@@ -1339,11 +1344,8 @@ Two consequences, both previously decided differently in different files:
|
|
|
1339
1344
|
that puts a style reviewer's unproven concern there.
|
|
1340
1345
|
- **And never of how crisply the finding is worded.** An outcome that costs a
|
|
1341
1346
|
user, a caller or persisted state nothing is `minor` however precisely its
|
|
1342
|
-
trigger is named
|
|
1343
|
-
|
|
1344
|
-
while a real defect stated tersely reads as `info`. That is not academic — the
|
|
1345
|
-
findings cap truncates by severity, so the well-written typo would survive and
|
|
1346
|
-
the terse real defect would be cut.
|
|
1347
|
+
trigger is named; otherwise a cosmetic nit stated as "trigger X produces output Y"
|
|
1348
|
+
reads as `major` and survives the findings cap while a terse real defect is cut.
|
|
1347
1349
|
|
|
1348
1350
|
The boundary this rubric does **not** draw is `major` against `major`. Two
|
|
1349
1351
|
findings that both name a trigger and an outcome are the same severity even when
|
|
@@ -1591,7 +1593,6 @@ When a prompt carries `JOB_NAME` and `CONTEXT_PATH`, read that context document
|
|
|
1591
1593
|
| "I'll just run all reviewers for safety" | Over-reviews waste time; auto-detect for relevant scope |
|
|
1592
1594
|
| "Spec compliance can wait until after quality review" | Stage 1 gate exists because unimplemented requirements invalidate quality work |
|
|
1593
1595
|
| "I'll deduplicate findings manually in my head" | Always normalize to [F-NNN] format before consolidation to avoid losing findings |
|
|
1594
|
-
| "Minor findings from one reviewer cancel out the major from another" | Each finding stands independently; severity is per-finding, not averaged |
|
|
1595
1596
|
| "The reviewer's own severity table said blocker" | There are no reviewer tables. One rubric, in **Severity (canonical)** above; a reviewer that ships one is the defect this replaced |
|
|
1596
1597
|
| "It's a security/architecture finding, so it's a blocker" | Severity is the demonstrated outcome, not the domain that found it. `blocker` is exactly the four shapes |
|
|
1597
1598
|
| "It will definitely break something eventually, so blocker" | Name the trigger and the outcome. Named → `major`. Unnamed → `info`. "Eventually" is neither |
|
|
@@ -1610,6 +1611,5 @@ When a prompt carries `JOB_NAME` and `CONTEXT_PATH`, read that context document
|
|
|
1610
1611
|
| "Steps 8–10 are done, I'll tick them now and ingest later" | `completed` means the ingest record exists. A plan that runs ahead of the artifacts is how an unrun review looked finished |
|
|
1611
1612
|
| "The user said publish, so I can post the comment" | That chose whether, not what. Show the rendered body and get approval of it before any GitHub write |
|
|
1612
1613
|
| "I cannot spawn reviewers, so I will review it myself" | A review nobody dispatched is not the review the report names. Output the Preflight 1 `BLOCKED` line and stop |
|
|
1613
|
-
| "No flags means no reviewers" | No flags → run auto-detection; never produce an empty review |
|
|
1614
1614
|
| "User named a module so I'll use diff mode" | Named module/component/store → path mode; diff mode is only for branch changes |
|
|
1615
1615
|
| "Path mode should only show lines I'd flag in diff mode" | Path mode reviews the entire file — all findings apply, not just added lines |
|
|
@@ -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.
|
|
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.
|
|
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
|
|
|
@@ -27,7 +27,7 @@ license: "MIT"
|
|
|
27
27
|
|
|
28
28
|
# Review — PR Contract
|
|
29
29
|
|
|
30
|
-
Reviewer for what the pull request says about itself.
|
|
30
|
+
Reviewer for what the pull request says about itself. Its inputs are the reviewer payload only; session memory and earlier conversation are not inputs.
|
|
31
31
|
|
|
32
32
|
This lane exists because nobody else reads the PR body. `review-logic` reads the code,
|
|
33
33
|
`review-testing-practices` reads the tests, and a retrospective review of a merged
|
|
@@ -31,7 +31,7 @@ license: "MIT"
|
|
|
31
31
|
Analyzes GitHub PR review comments from human reviewers or bots, checks each one
|
|
32
32
|
against the code as it stands, and turns the surviving ones into an ordered fix
|
|
33
33
|
plan. This skill does **not** review code itself — it interprets what others said,
|
|
34
|
-
and it verifies whether what they said is still true.
|
|
34
|
+
and it verifies whether what they said is still true. Its inputs are the reviewer payload only; session memory and earlier conversation are not inputs.
|
|
35
35
|
|
|
36
36
|
With `--fix` it also **executes** that plan: the work runs as a managed flow, on a
|
|
37
37
|
branch cut from the reviewed PR's own branch, behind its own draft PR, through a
|
|
@@ -22,7 +22,7 @@ license: "MIT"
|
|
|
22
22
|
# Review: Regression
|
|
23
23
|
|
|
24
24
|
You are reviewing **scope B** of a deep round. The files you are given are not
|
|
25
|
-
under review. They are under **regression check**.
|
|
25
|
+
under review. They are under **regression check**. Its inputs are the reviewer payload only; session memory and earlier conversation are not inputs.
|
|
26
26
|
|
|
27
27
|
## The one question
|
|
28
28
|
|
|
@@ -23,7 +23,7 @@ license: "MIT"
|
|
|
23
23
|
|
|
24
24
|
## Purpose
|
|
25
25
|
|
|
26
|
-
Finds exploitable security vulnerabilities introduced in the changed code of the current branch. Covers injection, auth/authz gaps, IDOR, secrets, insecure crypto, CSRF, path traversal, and framework-specific patterns (NestJS, React). Produces findings with explicit attack vectors and concrete fixes.
|
|
26
|
+
Finds exploitable security vulnerabilities introduced in the changed code of the current branch. Covers injection, auth/authz gaps, IDOR, secrets, insecure crypto, CSRF, path traversal, and framework-specific patterns (NestJS, React). Produces findings with explicit attack vectors and concrete fixes. Its inputs are the reviewer payload only; session memory and earlier conversation are not inputs.
|
|
27
27
|
|
|
28
28
|
This skill covers **code-level security only**. It does NOT audit npm/bun dependency trees, Docker configurations, or deployment surfaces — use `security-audit` for those.
|
|
29
29
|
|
|
@@ -25,7 +25,7 @@ license: "MIT"
|
|
|
25
25
|
|
|
26
26
|
Focused style reviewer. Covers naming conventions, dead code, readability, DRY violations,
|
|
27
27
|
import organization, comment quality, file length, cyclomatic complexity, and console noise.
|
|
28
|
-
Never touches logic correctness, architecture, security, or performance.
|
|
28
|
+
Never touches logic correctness, architecture, security, or performance. Its inputs are the reviewer payload only; session memory and earlier conversation are not inputs.
|
|
29
29
|
|
|
30
30
|
---
|
|
31
31
|
|
|
@@ -29,7 +29,7 @@ license: "MIT"
|
|
|
29
29
|
# Review — Testing Practices
|
|
30
30
|
|
|
31
31
|
Reviewer for local testing discipline. Read project test guides first when present, then apply
|
|
32
|
-
the neutral baseline below.
|
|
32
|
+
the neutral baseline below. Its inputs are the reviewer payload only; session memory and earlier conversation are not inputs.
|
|
33
33
|
|
|
34
34
|
---
|
|
35
35
|
|
|
@@ -26,7 +26,7 @@ license: "MIT"
|
|
|
26
26
|
|
|
27
27
|
Wave C. Reads the findings the domain reviewers produced and tries to **make each
|
|
28
28
|
one fail on purpose**. Emits one verdict per finding it checked. It removes; it
|
|
29
|
-
never adds and never sharpens.
|
|
29
|
+
never adds and never sharpens. Its inputs are the reviewer payload only; session memory and earlier conversation are not inputs.
|
|
30
30
|
|
|
31
31
|
---
|
|
32
32
|
|