@mrciphersmith/keryx 0.3.83 → 0.3.85
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 +2567 -2302
- package/dist/core.js +1140 -1029
- package/package.json +1 -1
- package/src/gdskills/bundled/rules/core/model-selection.mdc +6 -0
- package/src/gdskills/bundled/skills/orchestration/flow-orchestrator/SKILL.md +4 -4
- package/src/gdskills/bundled/skills/review/review-orchestrator/SKILL.detail.md +135 -0
- package/src/gdskills/bundled/skills/review/review-orchestrator/SKILL.md +34 -34
- package/src/gdskills/bundled/skills/review/review-orchestrator/review-context.schema.json +57 -0
- package/src/gdskills/bundled/skills/review/review-orchestrator/templates/review-report.md +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrciphersmith/keryx",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.85",
|
|
4
4
|
"description": "Version-controlled project context for AI coding agents: code graph, architecture wiki, project memory, relevant tests, quality signals, and task flows.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"publishConfig": {
|
|
@@ -326,6 +326,12 @@ recording them is one copy rather than four decisions.
|
|
|
326
326
|
remove.
|
|
327
327
|
- **Do not ask the operator which model to use per dispatch.** Asking every time
|
|
328
328
|
is what made adaptive selection impossible.
|
|
329
|
+
- **An interactive review round shows the computed plan once.** It is the third
|
|
330
|
+
start question of `review-orchestrator` (`model_strategy: ask`, the
|
|
331
|
+
interactive default): the complexity the round's signals give, each role's tier
|
|
332
|
+
and the model it resolves to here. The operator accepts it, takes every role to
|
|
333
|
+
`deep`, or sets it — for that round. An unattended round dispatches the
|
|
334
|
+
computed plan without asking (`adaptive`).
|
|
329
335
|
- Never write a concrete model name into a skill, a rule, a dispatch template, or
|
|
330
336
|
the resolution code.
|
|
331
337
|
- Take the candidate set from runtime detection. Never from a literal list of
|
|
@@ -433,14 +433,14 @@ Before accepting implementation:
|
|
|
433
433
|
1. Run focused tests for touched scope.
|
|
434
434
|
2. Run `code-verifier`.
|
|
435
435
|
3. Run `keryx health run` when Code Health is enabled.
|
|
436
|
-
4. Check the bounds, then run `review-orchestrator` with relevant domains
|
|
437
|
-
|
|
436
|
+
4. Check the bounds, then run `review-orchestrator` with relevant domains — in this session,
|
|
437
|
+
never handed whole to one subagent: one without a dispatch tool returns `STATUS: BLOCKED`.
|
|
438
438
|
```bash
|
|
439
439
|
keryx review budget --spent <usd-so-far> --outstanding <subagents you already have in flight>
|
|
440
440
|
```
|
|
441
|
-
|
|
442
441
|
A non-zero exit means the spend ceiling (3 USD by default) has been reached:
|
|
443
|
-
**stop and ask the user** rather than dispatching another fan-out.
|
|
442
|
+
**stop and ask the user** rather than dispatching another fan-out — never shrink the fan-out to fit.
|
|
443
|
+
Dispatch prompts point at sources (files, SHAs, the PR) and never paraphrase a contract.
|
|
444
444
|
|
|
445
445
|
`--outstanding` is the part that matters here. `review-orchestrator`
|
|
446
446
|
dispatches reviewers in parallel and runs *nested* under this skill, and
|
|
@@ -368,3 +368,138 @@ inside) the findings they annotate — same separation the finding schema
|
|
|
368
368
|
itself draws between a reviewer's claim (`severity`, `problem`, …) and what
|
|
369
369
|
became of it (`disposition`), which a reviewer never states and this pass
|
|
370
370
|
does not either.
|
|
371
|
+
|
|
372
|
+
## Start questions (Step 5) — once per round, after the context pack
|
|
373
|
+
|
|
374
|
+
The round asks its operator three questions, once, in one interaction, after
|
|
375
|
+
Step 1 (context pack) and Step 3 (scope) — never before them: the counterpart
|
|
376
|
+
question cannot be answered well until the context pack has looked for the
|
|
377
|
+
other side. On Claude Code that is one `AskUserQuestion` call carrying the
|
|
378
|
+
three questions; on any other host, the lettered prompt below. An unattended
|
|
379
|
+
round (job pipeline, trigger, schedule) asks nothing, applies the defaults and
|
|
380
|
+
records them under `### How this review was run`.
|
|
381
|
+
|
|
382
|
+
1. **Reviewers** — default `--all`: every reviewer the engine detects plus every
|
|
383
|
+
project and convention reviewer its gates admit. Narrowing is an explicit
|
|
384
|
+
choice (tests only, one domain, a custom list). Flags the caller passed
|
|
385
|
+
answer this question and skip it. Convention reviewers are part of this
|
|
386
|
+
question; the job setting `convention_reviewers` still answers it in a
|
|
387
|
+
`job-orchestrator` pipeline.
|
|
388
|
+
2. **Counterpart** — the other side of every contract the diff consumes or
|
|
389
|
+
mirrors: the backend for a frontend change, the frontend and other consumers
|
|
390
|
+
for a backend change. Before asking, the context pack looks for it:
|
|
391
|
+
endpoints, DTOs and rules the diff calls or mirrors, a paired PR
|
|
392
|
+
(`gh pr list --repo <counterpart> --search <branch-or-feature>`), the
|
|
393
|
+
producer at a freshly fetched SHA. The question shows what was found —
|
|
394
|
+
"no link found" included — and one checkbox, **verify the counterpart**, ON
|
|
395
|
+
by default even when nothing was found. Verification is not limited to a
|
|
396
|
+
paired PR: the other side's contracts and logic are re-read at a pinned SHA
|
|
397
|
+
every round. When the round cannot locate that code itself (repository,
|
|
398
|
+
handler, validator), it asks the operator where it is; it never records
|
|
399
|
+
`state: unavailable` on its own. Skipping verification takes a reason, and
|
|
400
|
+
the reason goes in the report.
|
|
401
|
+
3. **Models** — the complexity the round already holds signals for (changed
|
|
402
|
+
files and lines, the risk class from Depth floor below, domains, scope B),
|
|
403
|
+
the per-role tier `keryx review tier` prints for each planned dispatch, and
|
|
404
|
+
the model each tier resolves to on this host. Choices: accept the plan (the
|
|
405
|
+
default), all `deep`, or custom. The plan is shown once per round, never per
|
|
406
|
+
dispatch (`rules/core/model-selection.mdc`). Skills, rules and this file name
|
|
407
|
+
tiers only; model ids appear in the rendered question and the report.
|
|
408
|
+
|
|
409
|
+
```text
|
|
410
|
+
Context: <PR or branch>, <N> files / <N> lines, <domains>; risk: <class>
|
|
411
|
+
|
|
412
|
+
1) Reviewers A) --all (default) B) tests only C) <domain> only D) choose
|
|
413
|
+
2) Counterpart found: <endpoints, rules, paired PR — or "no link found">
|
|
414
|
+
A) verify <backend|frontend> (default) B) skip — give a reason
|
|
415
|
+
3) Models complexity: <low|medium|high>; <role>: <tier> → <model>, …
|
|
416
|
+
A) accept (default) B) all deep C) custom
|
|
417
|
+
|
|
418
|
+
> answers (default: 1A 2A 3A)
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
## Depth floor — a gating round does not degrade
|
|
422
|
+
|
|
423
|
+
A round is **gating** when its verdict lets a change move: the review step of a
|
|
424
|
+
flow (`flow-orchestrator` Phase 3), a pre-merge or pre-ship review, a
|
|
425
|
+
re-request after fixes. A gating round runs the composition the start questions
|
|
426
|
+
selected.
|
|
427
|
+
|
|
428
|
+
- **No dispatch tool, no review.** A host that cannot dispatch subagents — this
|
|
429
|
+
engine running inside a subagent is the usual case — returns
|
|
430
|
+
`STATUS: BLOCKED` with reason `nested_dispatch_unavailable` and no verdict.
|
|
431
|
+
It does not review the diff alone and call that a round. Measured (flow 405):
|
|
432
|
+
a single-agent round on a 150-line frontend PR wrote "did not dispatch any
|
|
433
|
+
sub-reviewers", approved it with two cosmetic minors, and the next human round
|
|
434
|
+
filed six real findings, every one reachable from the diff and the backend at
|
|
435
|
+
a pinned SHA.
|
|
436
|
+
- **Size never lowers depth below the risk class.** The budget table sizes the
|
|
437
|
+
context, not the depth.
|
|
438
|
+
- **High-risk includes a client-side mirror of a server rule** — validation,
|
|
439
|
+
limits, permissions, uniqueness, reserved names — beside the triggers the main
|
|
440
|
+
file lists.
|
|
441
|
+
|
|
442
|
+
## Counterpart verification — the contract is enumerated, not summarised
|
|
443
|
+
|
|
444
|
+
For an **input rule** the diff mirrors or depends on (what the server accepts
|
|
445
|
+
for a name, a value, a role), the `cross_repo` entry records the producer's
|
|
446
|
+
complete check set in `checks` and how that set was found in
|
|
447
|
+
`enumeration_method` (`review-context.schema.json`):
|
|
448
|
+
|
|
449
|
+
- every check the producer runs on that input: validators, restriction
|
|
450
|
+
utilities, uniqueness queries, reserved-name registries, and the storage bound
|
|
451
|
+
(column width, index, a downstream identifier);
|
|
452
|
+
- for each check: its `source` (`file:line` at the pinned SHA), whether it is
|
|
453
|
+
case-sensitive, and the `paths` it runs on (create, update, rename, copy,
|
|
454
|
+
import, move, …).
|
|
455
|
+
|
|
456
|
+
Put these rules in every reviewer dispatch:
|
|
457
|
+
|
|
458
|
+
- **The facts are a starting point, not a boundary.** A reviewer may read the
|
|
459
|
+
producer itself and file what the entry missed.
|
|
460
|
+
- **"The producer has no limit" is a question, not a fact.** Find what bounds
|
|
461
|
+
the value — that is where an over-long or unexpected value fails, usually as a
|
|
462
|
+
server error.
|
|
463
|
+
- **Build the surfaces × checks matrix**: every surface that sends the input
|
|
464
|
+
against every check, each cell `same`, `missing`, `stricter` or `looser`.
|
|
465
|
+
`missing` is a refusal the user meets late; `stricter` blocks legal input; a
|
|
466
|
+
check the producer lacks but storage enforces is a producer defect — filed as
|
|
467
|
+
pre-existing, or fixed by a paired change.
|
|
468
|
+
- **Every refusal the producer can return is shown where the user can act on
|
|
469
|
+
it** — next to the field, not as a generic toast.
|
|
470
|
+
|
|
471
|
+
## Round obligations — always on, never asked
|
|
472
|
+
|
|
473
|
+
These apply to every round without a question:
|
|
474
|
+
|
|
475
|
+
1. **Enumerate before concluding.** Every caller and surface of a changed value
|
|
476
|
+
is found with `keryx ctx rg` or gdgraph, and the query is recorded — never
|
|
477
|
+
taken from the diff's own list.
|
|
478
|
+
2. **Quantified claims are checked.** "Every", "all", "only" and "never" in the
|
|
479
|
+
PR body or the commits are compared with that enumeration; an over-claim is a
|
|
480
|
+
`minor` finding, the same class as the description-versus-diff rule.
|
|
481
|
+
3. **A verified-clean line names its sites.** Each line of the `Verified clean`
|
|
482
|
+
lane names the files, sites or commands it rests on; "the frontend does the
|
|
483
|
+
same" without them is not verified.
|
|
484
|
+
4. **A pre-existing defect gets a disposition.** Every pre-existing defect the
|
|
485
|
+
round finds in the contract the change touches is recorded with one: fixed in
|
|
486
|
+
the change (small, same contract), named out of scope in the PR body, or a
|
|
487
|
+
recommended issue. Found and dropped is the failure this rule exists for.
|
|
488
|
+
5. **Red on the parent, per test.** Every added test fails with the parent
|
|
489
|
+
commit's production files restored; the run is the evidence.
|
|
490
|
+
6. **A threaded value is pinned per site.** A parameter, key or prop passed at
|
|
491
|
+
several render sites is asserted at each site, or centralised so there is
|
|
492
|
+
one.
|
|
493
|
+
7. **One rule, one implementation.** The same check implemented twice is a
|
|
494
|
+
finding, even while both copies agree.
|
|
495
|
+
8. **"Do not re-raise" needs a record.** A dispatch may exclude an item only by
|
|
496
|
+
citing the PR comment, issue or decision that settled it — never a whole
|
|
497
|
+
surface ("X has no test; covered elsewhere").
|
|
498
|
+
|
|
499
|
+
### Runtime research-completion ledger
|
|
500
|
+
|
|
501
|
+
New managed packages carry `research.json`, initially pending. Before closing a round, enumerate unresolved observations from raw reviewers and the changed-file/consumer census, assign stable obligation IDs, and investigate them. Run the probe or inspect the relevant source and assertions: merely proposing a check does not resolve it. An unexecuted probe is not a verified claim.
|
|
502
|
+
|
|
503
|
+
Supply the ledger using `keryx review ingest --research <ledger.json>` alongside the report and findings. Format: `version: 1`, `scopeReviewed: true`, `rawReconciled: true`, `obligations: [...]`. Each obligation requires `id`, `source`, `question`, `status`, `evidence`, `reason`. Status `finding` additionally requires `finding` pointing to exactly one canonical finding ID or global ID. Other terminal statuses are `refuted` and `out-of-scope`, both requiring evidence and reason. Preserve distinct scenarios when deduplicating. Assert census/reconciliation flags only after performing those checks; an empty obligations array is valid only if the actual census found no open observations.
|
|
504
|
+
|
|
505
|
+
Open, deferred and unverifiable obligations block completion. If context, runtime or budget prevents resolution, retain the obligation and report incomplete; do not relabel it refuted or out-of-scope. Completion and the flow gate re-read the ledger even when the manifest says closed. Legacy packages without this artifact remain compatible, not proven complete. This gate validates the declared ledger, not the truth or exhaustiveness of its census; independent source/raw audits remain necessary.
|
|
@@ -18,15 +18,11 @@ metadata:
|
|
|
18
18
|
compatible_harnesses: "cursor,codex,zed,opencode,claude"
|
|
19
19
|
license: "MIT"
|
|
20
20
|
---
|
|
21
|
-
|
|
22
21
|
# Review Orchestrator
|
|
23
|
-
|
|
24
22
|
Entry point for the entire review domain. This skill is a thin router: it detects scope,
|
|
25
23
|
dispatches specialized reviewers in parallel, then consolidates their findings into one
|
|
26
24
|
unified report sorted by severity. It does not perform any review logic itself.
|
|
27
|
-
|
|
28
25
|
---
|
|
29
|
-
|
|
30
26
|
## Workflow
|
|
31
27
|
|
|
32
28
|
```
|
|
@@ -38,7 +34,7 @@ Review Orchestrator Progress:
|
|
|
38
34
|
- [ ] Step 3: Build the bounded scope with `keryx review scope` — never by hand
|
|
39
35
|
- [ ] 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
|
|
40
36
|
- [ ] Step 4: Parse flags / auto-detect domain from scope
|
|
41
|
-
- [ ] Step 5:
|
|
37
|
+
- [ ] Step 5: Start questions, once, after Steps 1 and 3 — reviewers (default `--all`), counterpart verification (default on), model plan; unattended takes the defaults (SKILL.detail.md § "Start questions"; legacy/profile reviewers stay flag-only)
|
|
42
38
|
- [ ] 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"
|
|
43
39
|
- [ ] Step 6: Plan sub-agent dispatch and token budgets, and compute each dispatch's model with `keryx review tier` — never by hand
|
|
44
40
|
- [ ] Step 7: Stage 1 gate - spec compliance check (if issue/task provided)
|
|
@@ -144,7 +140,7 @@ which of its inputs were recovered and which were never written down.
|
|
|
144
140
|
| `context_doc` | string | no | Path to job context document (e.g., `.metaproject/jobs/<job>/ai/context.md`). |
|
|
145
141
|
| `context_mode` | string | no | `none`, `light`, or `full`. Default: `light` for PR review, `none` for small path reviews. `full` may call `context-collector` before dispatch. |
|
|
146
142
|
| `token_budget` | object | no | Optional budget controls: `{total, per_reviewer, diff_max_chars, file_max_chars}`. |
|
|
147
|
-
| `model_strategy` | string | no | `ask` or `adaptive`. Default: `adaptive
|
|
143
|
+
| `model_strategy` | string | no | `ask` or `adaptive`. Default: `ask` in an interactive round (shown once as Start question 3), `adaptive` unattended; the model per dispatch is computed by `keryx review tier`, never chosen by hand (see Step 6). |
|
|
148
144
|
| `managed_review` | object | no | Optional managed review mode: `{mode, target, target_ref, flow_id, reviewers}` where mode is `lightweight`, `attach-review`, `review-flow`, or `ingest`. |
|
|
149
145
|
| `verification_mode` | string | no | `off`, `annotate`, or `filter`. Default `annotate` — verdicts are recorded and nothing is removed. See Wave C. |
|
|
150
146
|
| `pr_comments` | object | no | `{enabled, max_replies_total, max_sentences_per_reply}`. Defaults: enabled when a PR exists, `30`, `2`. Collect every round, reply once at the end. See External PR comments. |
|
|
@@ -522,9 +518,9 @@ The rule that follows for reviewers, and that belongs in the dispatch prompt:
|
|
|
522
518
|
> producer disproves, and a defect missed because the producer's actual default was
|
|
523
519
|
> assumed rather than read.
|
|
524
520
|
|
|
525
|
-
If the
|
|
526
|
-
|
|
527
|
-
|
|
521
|
+
If you cannot locate the producer, ask the operator where it is (Start question 2); record `state: unavailable` only when it cannot be read, and leave the dependent findings at `info`.
|
|
522
|
+
An unavailable producer is a result. Assuming one is not. An input rule records the producer's full check set and is verified every round,
|
|
523
|
+
paired PR or not — SKILL.detail.md § "Counterpart verification".
|
|
528
524
|
|
|
529
525
|
A finding whose evidence lives in the producer sets `repo` on the finding itself.
|
|
530
526
|
`file` and `line` alone name a path in the repository under review, so without
|
|
@@ -600,8 +596,8 @@ Context modes:
|
|
|
600
596
|
- `full`: for large/high-risk PRs or user request. Invoke `context-collector` first, then pass the resulting context path and summary to reviewers.
|
|
601
597
|
|
|
602
598
|
High-risk triggers for `full` recommendation:
|
|
603
|
-
- Auth, permissions, API contracts, migrations, shared core, state management, graph/flow, security, performance-critical paths.
|
|
604
|
-
- More than 20 changed source files or more than 2,000 changed lines.
|
|
599
|
+
- 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.
|
|
600
|
+
- 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").
|
|
605
601
|
- Missing or ambiguous linked requirements.
|
|
606
602
|
|
|
607
603
|
If `full` context would be useful but was not explicitly requested, ask once:
|
|
@@ -655,8 +651,8 @@ whether it is computed:
|
|
|
655
651
|
|
|
656
652
|
| `model_strategy` | Behavior |
|
|
657
653
|
|---|---|
|
|
658
|
-
| `ask` | Present the `keryx review tier` model plan once before dispatch. |
|
|
659
|
-
| `adaptive` (default) | Dispatch on the computed model directly; record the chosen model per reviewer in the final report metadata. |
|
|
654
|
+
| `ask` (default, interactive) | Present the `keryx review tier` model plan once before dispatch — Start question 3; the operator may accept it, take all `deep`, or set it. |
|
|
655
|
+
| `adaptive` (default, unattended) | Dispatch on the computed model directly; record the chosen model per reviewer in the final report metadata. |
|
|
660
656
|
|
|
661
657
|
Rules:
|
|
662
658
|
- Never write a model id into a dispatch by hand — paste the `model` block `keryx review tier` printed.
|
|
@@ -1052,30 +1048,30 @@ what to do with it: `SKILL.detail.md` beside this file, section "Project-local
|
|
|
1052
1048
|
reviewers". A description saying another entry point dispatches it is its
|
|
1053
1049
|
author's routing note, not a restriction.
|
|
1054
1050
|
|
|
1055
|
-
###
|
|
1051
|
+
### Start questions (Step 5)
|
|
1056
1052
|
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
`--flow-graph`, or `--all`, ask before dispatch:
|
|
1053
|
+
Ask once, after the context pack (Step 1) and the scope (Step 3), in one interaction — one
|
|
1054
|
+
`AskUserQuestion` call on Claude Code, the lettered prompt in SKILL.detail.md elsewhere:
|
|
1060
1055
|
|
|
1061
|
-
|
|
1062
|
-
|
|
1056
|
+
1. **Reviewers** — default `--all`; detected convention reviewers are included. Narrowing
|
|
1057
|
+
(tests only, one domain, custom) is the operator's explicit choice. Passed flags answer it.
|
|
1058
|
+
Legacy/profile reviewers stay flag-only and are never prompted.
|
|
1059
|
+
2. **Counterpart** — show what the context pack found for the other side of the contract
|
|
1060
|
+
(endpoints, mirrored rules, a paired PR, or "no link found") and a checkbox to verify it,
|
|
1061
|
+
ON by default even with no link. If the round cannot locate that code, it asks where it is.
|
|
1062
|
+
Verification is not limited to a paired PR: contracts and logic are re-read every round.
|
|
1063
|
+
3. **Models** — complexity, the per-role tier from `keryx review tier`, the model each tier
|
|
1064
|
+
resolves to on this host; accept (default), all `deep`, or custom. Once per round.
|
|
1063
1065
|
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1066
|
+
Unattended rounds ask nothing: `--all`, counterpart verified, computed models — recorded in
|
|
1067
|
+
`### How this review was run`. In a `job-orchestrator` pipeline the job setting
|
|
1068
|
+
`convention_reviewers` still answers question 1 (unresolved: include all detected reviewers
|
|
1069
|
+
and record that choice in the review scope).
|
|
1067
1070
|
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
- review-flow-graph: <why detected, or omit if not detected>
|
|
1073
|
-
```
|
|
1074
|
-
|
|
1075
|
-
If the user chooses B, list only detected reviewers and ask for names to include/exclude.
|
|
1076
|
-
If the user does not answer and the review is part of an automated `job-orchestrator` pipeline,
|
|
1077
|
-
use the job setting `convention_reviewers` (default: `"ask"`; if still unresolved, include all
|
|
1078
|
-
detected reviewers and record that choice in the review scope).
|
|
1071
|
+
A gating round runs what these answers selected; a host that cannot dispatch subagents
|
|
1072
|
+
returns `STATUS: BLOCKED` (`nested_dispatch_unavailable`) instead of reviewing alone. Every
|
|
1073
|
+
round also carries the always-on obligations — SKILL.detail.md § "Depth floor",
|
|
1074
|
+
§ "Counterpart verification", § "Round obligations".
|
|
1079
1075
|
|
|
1080
1076
|
### Reviewer selection with Jev (`jev-select`) — advisory, before dispatch (Step 5c)
|
|
1081
1077
|
|
|
@@ -1185,7 +1181,11 @@ whoever reads the merge commit a year later reads the body. When `review.jev.con
|
|
|
1185
1181
|
|
|
1186
1182
|
## Dispatching Reviewers
|
|
1187
1183
|
|
|
1188
|
-
Dispatch selected
|
|
1184
|
+
**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.
|
|
1185
|
+
|
|
1186
|
+
New managed packages declare `reviewerDispatch: "research.json"`. Alongside the research ledger, provide `dispatch: { version: 1, 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).
|
|
1187
|
+
|
|
1188
|
+
Dispatch selected reviewers in parallel when independent — this engine dispatches them itself; a host without a dispatch tool returns `STATUS: BLOCKED` (`nested_dispatch_unavailable`) and never reviews alone. Use waves when token budget is tight or when one reviewer needs another result:
|
|
1189
1189
|
|
|
1190
1190
|
1. Wave A - core correctness/risk reviewers: logic, architecture, security/highload when selected.
|
|
1191
1191
|
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".
|
|
@@ -205,6 +205,51 @@
|
|
|
205
205
|
"null"
|
|
206
206
|
],
|
|
207
207
|
"description": "The last round the producer was re-read. An entry with `state: open` that was pinned in round 1 and never revalidated is stale by round 3: a parallel pull request is precisely the thing that moves between rounds."
|
|
208
|
+
},
|
|
209
|
+
"checks": {
|
|
210
|
+
"type": "array",
|
|
211
|
+
"minItems": 1,
|
|
212
|
+
"description": "For an input rule the diff mirrors or depends on (what the producer accepts for a name, a value, a role): the producer's COMPLETE check set, not a summary of it. Flow 405: a dispatch that carried only the producer's regex let two rounds approve a change that missed a case-sensitive prefix check, a case-sensitive uniqueness check and a column-width bound. The set is a starting point for reviewers, never a boundary.",
|
|
213
|
+
"items": {
|
|
214
|
+
"type": "object",
|
|
215
|
+
"required": [
|
|
216
|
+
"check",
|
|
217
|
+
"source",
|
|
218
|
+
"paths"
|
|
219
|
+
],
|
|
220
|
+
"properties": {
|
|
221
|
+
"check": {
|
|
222
|
+
"type": "string",
|
|
223
|
+
"minLength": 1,
|
|
224
|
+
"description": "What the producer refuses, in one line — including a storage bound such as a column width."
|
|
225
|
+
},
|
|
226
|
+
"source": {
|
|
227
|
+
"type": "string",
|
|
228
|
+
"minLength": 1,
|
|
229
|
+
"description": "`file:line` at the pinned ref."
|
|
230
|
+
},
|
|
231
|
+
"case_sensitive": {
|
|
232
|
+
"type": [
|
|
233
|
+
"boolean",
|
|
234
|
+
"null"
|
|
235
|
+
]
|
|
236
|
+
},
|
|
237
|
+
"paths": {
|
|
238
|
+
"type": "array",
|
|
239
|
+
"minItems": 1,
|
|
240
|
+
"items": {
|
|
241
|
+
"type": "string"
|
|
242
|
+
},
|
|
243
|
+
"description": "The producer paths this check runs on — create, update, rename, copy, import, move, …"
|
|
244
|
+
}
|
|
245
|
+
},
|
|
246
|
+
"additionalProperties": true
|
|
247
|
+
}
|
|
248
|
+
},
|
|
249
|
+
"enumeration_method": {
|
|
250
|
+
"type": "string",
|
|
251
|
+
"minLength": 1,
|
|
252
|
+
"description": "How `checks` was found to be complete — the producer entry points read and the searches run. Required whenever `checks` is present."
|
|
208
253
|
}
|
|
209
254
|
},
|
|
210
255
|
"allOf": [
|
|
@@ -241,6 +286,18 @@
|
|
|
241
286
|
"pr"
|
|
242
287
|
]
|
|
243
288
|
}
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
"if": {
|
|
292
|
+
"required": [
|
|
293
|
+
"checks"
|
|
294
|
+
]
|
|
295
|
+
},
|
|
296
|
+
"then": {
|
|
297
|
+
"required": [
|
|
298
|
+
"enumeration_method"
|
|
299
|
+
]
|
|
300
|
+
}
|
|
244
301
|
}
|
|
245
302
|
],
|
|
246
303
|
"additionalProperties": true
|
|
@@ -160,7 +160,7 @@ a tool, skill or model is unavailable; use `none` only when the run proves none.
|
|
|
160
160
|
- **Subagents:** <dispatched subagents, their reviewer roles and actual models; or none when confirmed, otherwise not recorded>.
|
|
161
161
|
- **Fallback:** <reviewer> via `general-purpose` because <native agent type unavailable | no bundled agent>. Or `none`.
|
|
162
162
|
- **Not run:** <reviewer> — <short reason>. Or `none`.
|
|
163
|
-
- **Selection:** <
|
|
163
|
+
- **Selection:** <explicit flags | start questions: reviewers <`--all` | narrowed to …>, counterpart <verified at <sha> | skipped: reason>, models <accepted | all deep | custom> | defaults (unattended)>
|
|
164
164
|
- **Verification:** <mode>. Confirmed N, refuted N, unverifiable N, unverified N. Removed N (always 0 outside `filter`).
|
|
165
165
|
- **Stage counts:** pre-filter dropped <files>/<blocks>/<lines> (or `not recorded`). Retained N.
|
|
166
166
|
- **Context:** <job/context path, or none>
|