@mrciphersmith/keryx 0.3.111 → 0.3.113
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 +17 -3
- package/THIRD_PARTY_NOTICES.md +56 -0
- package/dist/cli.js +102938 -97144
- package/dist/core.js +6072 -4676
- package/package.json +3 -1
- package/src/gdgraph/affected-report.ts +14 -4
- package/src/gdgraph/build.ts +12 -9
- package/src/gdgraph/core-sources.ts +1 -0
- package/src/gdgraph/data-dir.ts +14 -0
- package/src/gdgraph/enrich.ts +5 -3
- package/src/gdgraph/query.ts +3 -2
- package/src/gdgraph/staleness.ts +8 -1
- package/src/gdgraph/wiki-layer.ts +9 -6
- package/src/gdskills/bundled/skills/orchestration/flow-orchestrator/SKILL.md +3 -3
- package/src/gdskills/bundled/skills/orchestration/job-orchestrator/SKILL.md +3 -3
- package/src/gdskills/bundled/skills/orchestration/job-orchestrator/orchestrator-prompt.md +2 -2
- package/src/gdskills/bundled/skills/orchestration/task-implementer/SKILL.md +4 -4
- package/src/gdskills/bundled/skills/planning/autodoc-orchestrator/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/planning/interviewer/SKILL.md +3 -3
- package/src/gdskills/bundled/skills/quality/api-truth/SKILL.md +2 -2
- package/src/gdskills/bundled/skills/quality/deprecation-path/SKILL.md +3 -3
- package/src/gdskills/bundled/skills/quality/fresh-eyes/SKILL.md +2 -2
- package/src/gdskills/bundled/skills/quality/perf-check/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/quality/root-cause/SKILL.md +2 -2
- package/src/gdskills/bundled/skills/review/review-architecture/SKILL.md +14 -15
- package/src/gdskills/bundled/skills/review/review-backend/SKILL.md +14 -14
- package/src/gdskills/bundled/skills/review/review-frontend/SKILL.md +13 -16
- package/src/gdskills/bundled/skills/review/review-logic/SKILL.md +14 -14
- package/src/gdskills/bundled/skills/review/review-orchestrator/SKILL.detail.md +42 -3
- package/src/gdskills/bundled/skills/review/review-orchestrator/SKILL.md +21 -19
- package/src/gdskills/bundled/skills/review/review-orchestrator/reviewer-finding.schema.json +16 -0
- package/src/gdskills/bundled/skills/review/review-orchestrator/reviewer-input.schema.json +47 -0
- package/src/gdskills/bundled/skills/review/review-orchestrator/templates/pr-comment-frontend.md +1 -1
- package/src/gdskills/bundled/skills/review/review-performance/SKILL.md +13 -13
- package/src/gdskills/bundled/skills/review/review-regression/SKILL.md +23 -25
- package/src/gdskills/bundled/skills/review/review-security-code/SKILL.md +13 -15
- package/src/gdskills/bundled/skills/review/review-testing-practices/SKILL.md +31 -57
|
@@ -341,20 +341,7 @@ STATUS: DONE | DONE_WITH_CONCERNS | NEEDS_CONTEXT | BLOCKED
|
|
|
341
341
|
|
|
342
342
|
## Job Context Awareness
|
|
343
343
|
|
|
344
|
-
When dispatched by `review-orchestrator` or `job-orchestrator`, the prompt MAY
|
|
345
|
-
|
|
346
|
-
```
|
|
347
|
-
JOB_NAME: <job-name>
|
|
348
|
-
CONTEXT_PATH: .metaproject/jobs/<job-name>/ai/context.md
|
|
349
|
-
```
|
|
350
|
-
|
|
351
|
-
If provided and the file exists, read the context document **before** the spec compliance gate.
|
|
352
|
-
Use it to:
|
|
353
|
-
- Understand intentional design decisions (do not flag correct library usage)
|
|
354
|
-
- Identify acceptance criteria if no `issue_url` is provided
|
|
355
|
-
- Calibrate severity for edge cases the team has explicitly accepted
|
|
356
|
-
|
|
357
|
-
If absent, proceed normally — context is optional and non-blocking.
|
|
344
|
+
When dispatched by `review-orchestrator` or `job-orchestrator`, the prompt MAY carry `JOB_NAME` and `CONTEXT_PATH: .metaproject/jobs/<job-name>/ai/context.md`. If given and the file exists, read it before you start; use it for intentional design decisions (do not flag correct library usage), acceptance criteria when there is no `issue_url`, and the severity of edge cases the team accepted. If absent, proceed normally: context is optional and non-blocking.
|
|
358
345
|
|
|
359
346
|
---
|
|
360
347
|
|
|
@@ -368,3 +355,16 @@ If absent, proceed normally — context is optional and non-blocking.
|
|
|
368
355
|
| "I'll mark everything blocker to be safe" | Overstated severity makes reports unactionable; calibrate per the severity guide |
|
|
369
356
|
| "Async performance is slow, so that's a logic bug" | Performance lives in `review-performance` unless incorrect ordering changes the result |
|
|
370
357
|
| "I didn't reproduce the bug so I won't report it" | Every blocker needs a scenario, not a repro — describe the failing code path |
|
|
358
|
+
|
|
359
|
+
<!-- keryx:layers-block:start -->
|
|
360
|
+
## Project layers: graph, tests, wiki, memory
|
|
361
|
+
|
|
362
|
+
Your payload may carry a `layers` block for your files: the files the graph says are affected, symbol neighbours, related tests, the wiki pages that describe the files and the memory entries for their module. It is bounded, and `truncated` names what was cut and the command that fetches the rest. When the diff alone does not settle a question, ask the project. Each command below is read-only and calls no model.
|
|
363
|
+
|
|
364
|
+
- `keryx gdgraph affected <file>`: who depends on the file. Use it before you call a change contained, and whenever a changed export, signature or behaviour may have callers outside your files.
|
|
365
|
+
- `keryx test related <file>`: the tests that cover the file. Use it before you say a behaviour is untested, and to judge whether a test would fail if the code broke.
|
|
366
|
+
- `keryx wiki ask "<q>"`: what the project wiki says a module is for and which rules bind it. Use it when the intent of the code is unclear and the diff does not state it.
|
|
367
|
+
- `keryx memory search "<q>"`: recorded lessons, decisions and known mistakes. Use it before you report a pattern the project may already have decided on, and when a failure looks like one it has seen.
|
|
368
|
+
|
|
369
|
+
In a review package, `keryx gdgraph affected <file> --data-dir <package>/layers/graph` reads the graph built at the PR head; the tracked graph may be from another commit. A finding still rests on the code you read: what a layer says is a lead, not evidence. If a layer is empty or a command fails, say so in the report instead of guessing.
|
|
370
|
+
<!-- keryx:layers-block:end -->
|
|
@@ -33,7 +33,7 @@ comma-separated list, `stack_requires` as a string, only keys directly under
|
|
|
33
33
|
has already applied it — use the fields, not the raw frontmatter.
|
|
34
34
|
|
|
35
35
|
A description saying another entry point dispatches it ("Dispatched by
|
|
36
|
-
|
|
36
|
+
acme-review …") is its author's routing note, not a restriction: this
|
|
37
37
|
orchestrator dispatches it through the fields above.
|
|
38
38
|
|
|
39
39
|
### Family flags — why a shared flag does not lift the path gate
|
|
@@ -441,8 +441,8 @@ flow (`flow-orchestrator` Phase 3), a pre-merge or pre-ship review, a
|
|
|
441
441
|
re-request after fixes. A gating round runs the composition the start questions
|
|
442
442
|
selected.
|
|
443
443
|
|
|
444
|
-
- **No dispatch tool, no review.** A host that cannot dispatch subagents —
|
|
445
|
-
|
|
444
|
+
- **No dispatch tool, no review.** A host that cannot dispatch subagents — no
|
|
445
|
+
spawn tool, or the depth budget spent — returns
|
|
446
446
|
`STATUS: BLOCKED` with reason `nested_dispatch_unavailable` and no verdict.
|
|
447
447
|
It does not review the diff alone and call that a round. Measured (flow 405):
|
|
448
448
|
a single-agent round on a 150-line frontend PR wrote "did not dispatch any
|
|
@@ -689,3 +689,42 @@ Use it to understand:
|
|
|
689
689
|
- Architectural decisions already agreed upon, and acceptance criteria driving the Stage 1 spec compliance gate
|
|
690
690
|
|
|
691
691
|
If absent, proceed normally — context is optional and non-blocking.
|
|
692
|
+
|
|
693
|
+
## The mutation pass — `keryx review mutate`
|
|
694
|
+
|
|
695
|
+
Attended, the pass is not optional once mutants were proposed. The testing reviewer writes
|
|
696
|
+
each proposed mutant to `<review-dir>/research-evidence/mutants.json`:
|
|
697
|
+
`{ "mutants": [{ "id", "file", "anchor", "replacement" }] }`. `anchor` is exact text that
|
|
698
|
+
occurs once in `file`; `"runnable": false` at the top level says the suite cannot run here.
|
|
699
|
+
|
|
700
|
+
Run `keryx review mutate --test "<the nearest suite command>" --package <review-dir>`. It
|
|
701
|
+
applies each mutant in a scratch copy of the worktree (never in the worktree), refuses to
|
|
702
|
+
start when the baseline is red, and writes the table to `research-evidence/mutation-<n>.md`
|
|
703
|
+
and `.json`. A mutant is `killed` (the suite went red), `survived` (nothing pins that
|
|
704
|
+
behaviour), `timeout`, or `invalid` (anchor missing or not unique, file outside the copy).
|
|
705
|
+
A survivor is evidence for the finding that names it.
|
|
706
|
+
|
|
707
|
+
`keryx review complete` refuses while proposed mutants are unrun, unless
|
|
708
|
+
`dispatch.mutationWaiver = { operatorQuote, reason }` carries the operator's own words.
|
|
709
|
+
`keryx review run --autonomous` is unchanged: it records `Not run: mutation pass` as before.
|
|
710
|
+
|
|
711
|
+
### Severity audit — `keryx review severity-audit`
|
|
712
|
+
|
|
713
|
+
A reviewer that argues a finding from a mutant writes `mutant:<id>` in the finding's `evidence`.
|
|
714
|
+
After the mutation pass run `keryx review severity-audit --package <review-dir>`: a cited mutant
|
|
715
|
+
that survived on a file the review changed raises a minor finding to major and records
|
|
716
|
+
`severity_audit {from, to, evidence: "mutation-<n>.json#<id>"}`. A finding that cites a mutant no
|
|
717
|
+
run executed stays minor (a major is capped at minor) and gets the label `unproven`. The audit
|
|
718
|
+
never deletes a finding and never touches a blocker; it is a separate pass from the verifier,
|
|
719
|
+
which can only delete. `--dry-run` prints the changes without writing `findings.json`.
|
|
720
|
+
|
|
721
|
+
### Pull request context — `keryx review context-collect`
|
|
722
|
+
|
|
723
|
+
A pull-request review starts with `keryx review context-collect --repo <o/r> --pr <n> --package <review-dir>`.
|
|
724
|
+
It writes `pr-context.json` and `pr-context.md` into the package: every review comment in full (the
|
|
725
|
+
800-character cut applies only to a finding's `problem`), the round-1 intent (kept when a later round
|
|
726
|
+
collects a new head), the CI status (`--checks <file>` or `gh pr checks`; `unknown` when neither is
|
|
727
|
+
available) and the backend pins the pull request names (refs on lines that talk about the backend).
|
|
728
|
+
Set `pr_context` in every reviewer payload to the `.md` path; reviewers read it before the diff.
|
|
729
|
+
`keryx review dispatch-check --payload <file> --pr-context` refuses a payload without it
|
|
730
|
+
(`REVIEWER_INPUT_NO_PR_CONTEXT`).
|
|
@@ -24,9 +24,9 @@ license: "MIT"
|
|
|
24
24
|
|
|
25
25
|
## Preflight — before Step 0, in this order
|
|
26
26
|
|
|
27
|
-
1. **Can it spawn?** The round needs
|
|
27
|
+
1. **Can it spawn?** The round needs a subagent-spawn tool (`Agent`, `spawn_subagent` or the host's equivalent) and depth budget left: Claude Code nests subagents at most 3 deep, and at the limit `Agent` is withheld. If it cannot spawn, the whole output is this line, with no tool calls and no review of your own:
|
|
28
28
|
`STATUS: BLOCKED nested_dispatch_unavailable — run this skill in the main session`
|
|
29
|
-
2. **Is a round needed?** A diff
|
|
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
31
|
|
|
32
32
|
## Workflow
|
|
@@ -74,7 +74,7 @@ Publish this checklist with `plan_set` under the ids `step-0`…`step-14` once,
|
|
|
74
74
|
- One `Agent` call per reviewer, all calls of a wave in a single message, so the wave runs in parallel.
|
|
75
75
|
- 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
76
|
- Prompts carry pointers, not pasted files — the diff, the SHAs, the PR, the schema paths — and never paraphrase a contract.
|
|
77
|
-
- 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`.
|
|
77
|
+
- 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
78
|
- 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
79
|
|
|
80
80
|
## Shell host (keryx shell, or any host with no file-reading subagent) — mandatory
|
|
@@ -85,15 +85,15 @@ A reviewer on this host cannot open a path: its file tool reads inside its worki
|
|
|
85
85
|
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
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
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. 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`. 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`.
|
|
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`. 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
89
|
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
90
|
|
|
91
91
|
## Control
|
|
92
92
|
|
|
93
93
|
- **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).
|
|
94
94
|
- **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`).
|
|
95
|
-
- **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
|
|
96
|
-
- **Done when**
|
|
95
|
+
- **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.
|
|
96
|
+
- **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.
|
|
97
97
|
|
|
98
98
|
---
|
|
99
99
|
|
|
@@ -401,8 +401,8 @@ question at the end answers the wrong question late.
|
|
|
401
401
|
human or a bot has already reviewed pull request `#A`, and someone wants those
|
|
402
402
|
comments interpreted, checked against the code, fixed and answered. Under its
|
|
403
403
|
`--fix` mode it dispatches `flow-orchestrator`, which opens a **second** pull
|
|
404
|
-
request `#B` carrying the fix, based on `#A`'s own head branch, and
|
|
405
|
-
**this** orchestrator on every round against `#B`. `review-pr-feedback` is present only when installed — it is in the `full` profile only. When it is absent no caller of this kind exists, so the default below holds and this orchestrator owns the reply; do not hand a request to it, say it is not installed and name the install command (`SKILL.detail.md`, "Skills present only when installed").
|
|
404
|
+
request `#B` carrying the fix, based on `#A`'s own head branch, and runs
|
|
405
|
+
**this** orchestrator inline, in the main session, on every round against `#B`. `review-pr-feedback` is present only when installed — it is in the `full` profile only. When it is absent no caller of this kind exists, so the default below holds and this orchestrator owns the reply; do not hand a request to it, say it is not installed and name the install command (`SKILL.detail.md`, "Skills present only when installed").
|
|
406
406
|
|
|
407
407
|
`#B` is its own conversation. Collect and reply on it exactly as always: someone
|
|
408
408
|
reviewing the fix deserves an answer from the run that made the fix, and its
|
|
@@ -516,7 +516,7 @@ the SHA:
|
|
|
516
516
|
|
|
517
517
|
```yaml
|
|
518
518
|
cross_repo:
|
|
519
|
-
- repo:
|
|
519
|
+
- repo: acme-backend
|
|
520
520
|
state: merged
|
|
521
521
|
sha: f5219d5d4
|
|
522
522
|
merge_order: independent
|
|
@@ -792,13 +792,11 @@ and those are different questions — only the first has ever been asked here.
|
|
|
792
792
|
A deep round dispatches under **both**. Scope B is computed, never browsed:
|
|
793
793
|
|
|
794
794
|
```bash
|
|
795
|
-
keryx review blast-radius --ref "${BASE_SHA}" --json > blast-radius.json # KEEP THIS FILE
|
|
796
|
-
keryx review blast-radius --ref "${BASE_SHA}" --brief # what a scope-B reviewer is told
|
|
795
|
+
keryx review blast-radius --ref "${BASE_SHA}" --package "${PKG}" --json > blast-radius.json # KEEP THIS FILE
|
|
796
|
+
keryx review blast-radius --ref "${BASE_SHA}" --package "${PKG}" --brief # what a scope-B reviewer is told
|
|
797
797
|
```
|
|
798
798
|
|
|
799
|
-
**KEEP THIS FILE
|
|
800
|
-
scope-B finding arrives without it — pass it back as
|
|
801
|
-
`review ingest ... --blast-radius blast-radius.json`.
|
|
799
|
+
**KEEP THIS FILE**: the ingest at Step 12 is **refused** for a scope-B finding without it — pass it as `review ingest ... --blast-radius blast-radius.json`.
|
|
802
800
|
|
|
803
801
|
Scope B is bounded and computed: distance ≤ 2 from every changed file, at most 40 files, closest
|
|
804
802
|
first. Do not pick the files or widen the set. Record it with `--out "<review-package>/blast-radius.md"`,
|
|
@@ -813,9 +811,11 @@ names the caller that breaks.
|
|
|
813
811
|
Recompute scope B on rounds 2..N only when the changed-file set moved, and always on the final round:
|
|
814
812
|
|
|
815
813
|
```bash
|
|
816
|
-
keryx review blast-radius --ref "${BASE_SHA}" --previous blast-radius.json [--final]
|
|
814
|
+
keryx review blast-radius --ref "${BASE_SHA}" --package "${PKG}" --previous blast-radius.json [--final]
|
|
817
815
|
```
|
|
818
816
|
|
|
817
|
+
`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.
|
|
818
|
+
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.
|
|
819
819
|
The measurements, the rule table and the recompute table: `SKILL.detail.md` § "Scope B — bounds, rejections and recompute".
|
|
820
820
|
|
|
821
821
|
### Path Mode
|
|
@@ -824,13 +824,15 @@ When a path or target is named, collect the candidate files:
|
|
|
824
824
|
|
|
825
825
|
```bash
|
|
826
826
|
# If a directory path is given:
|
|
827
|
-
keryx ctx rg --files -g '*.{ts,tsx,js,jsx}' <path> | sort
|
|
827
|
+
keryx ctx run --raw -- rg --files -g '*.{ts,tsx,js,jsx}' <path> | sort
|
|
828
828
|
|
|
829
829
|
# If a module name is given (e.g. "UserStore", "pipelines module"):
|
|
830
|
-
keryx ctx rg --files -g '*<name>*.{ts,tsx}'
|
|
830
|
+
keryx ctx run --raw -- rg --files -g '*<name>*.{ts,tsx}' | sort
|
|
831
831
|
# Also check common locations: src/stores/, src/modules/, src/components/
|
|
832
832
|
```
|
|
833
833
|
|
|
834
|
+
`--raw` returns plain paths, one per line, and the whole list. The summarized form (`keryx ctx rg --files`) prints header lines among the paths and cuts the list at 120 entries, so a round built on it silently covers a part of the scope. Only path lines are file entries.
|
|
835
|
+
|
|
834
836
|
Then put the list through the same exclusions before reading anything:
|
|
835
837
|
|
|
836
838
|
```bash
|
|
@@ -1102,7 +1104,7 @@ whoever reads the merge commit a year later reads the body. When `review.jev.con
|
|
|
1102
1104
|
|
|
1103
1105
|
**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.
|
|
1104
1106
|
|
|
1105
|
-
**The reviewer set is not yours to shrink.** Run `keryx review required --mode all|diff --scope <scope.json>` (`all` for `--all`
|
|
1107
|
+
**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).
|
|
1106
1108
|
|
|
1107
1109
|
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:
|
|
1108
1110
|
|
|
@@ -1124,7 +1126,7 @@ finding class is unreachable for the entire round, and no amount of verification
|
|
|
1124
1126
|
downstream recovers it. When a testing reviewer returns without a mutation table,
|
|
1125
1127
|
treat it the way you would treat a reviewer that returned without findings *and*
|
|
1126
1128
|
without evidence: ask once, then record that the pass did not run. Unattended: record
|
|
1127
|
-
`Not run: mutation pass` without asking.
|
|
1129
|
+
`Not run: mutation pass` without asking. Attended: run `keryx review mutate` ([The mutation pass](SKILL.detail.md#the-mutation-pass-keryx-review-mutate)).
|
|
1128
1130
|
|
|
1129
1131
|
### Wave C — verification, and what it replaced
|
|
1130
1132
|
|
|
@@ -184,6 +184,22 @@
|
|
|
184
184
|
"type": "string"
|
|
185
185
|
}
|
|
186
186
|
},
|
|
187
|
+
"slices": {
|
|
188
|
+
"title": "Slices this result covered",
|
|
189
|
+
"description": "The ids of the dispatched slices the reviewer read. An entry is an id string, or an object with an `id`, an optional `coverage` note and an optional `status`. `keryx review retry-plan` and `ledger build` read both. An object counts as covered only when its `status` is absent or one of DONE, COMPLETE, COMPLETED, COVERED, OK (any case); any other status (NOT_READ, INCOMPLETE, SKIPPED, PARTIAL, …) leaves the slice uncovered and is named in the plan reason or the ledger gap. An entry with no id counts for nothing.",
|
|
190
|
+
"type": "array",
|
|
191
|
+
"items": {
|
|
192
|
+
"type": ["string", "object"],
|
|
193
|
+
"minLength": 1,
|
|
194
|
+
"required": ["id"],
|
|
195
|
+
"properties": {
|
|
196
|
+
"id": { "type": "string", "minLength": 1 },
|
|
197
|
+
"coverage": { "type": "string" },
|
|
198
|
+
"status": { "type": "string" }
|
|
199
|
+
},
|
|
200
|
+
"additionalProperties": true
|
|
201
|
+
}
|
|
202
|
+
},
|
|
187
203
|
"stats": {
|
|
188
204
|
"type": "object",
|
|
189
205
|
"required": [
|
|
@@ -160,6 +160,13 @@
|
|
|
160
160
|
"null"
|
|
161
161
|
]
|
|
162
162
|
},
|
|
163
|
+
"pr_context": {
|
|
164
|
+
"type": [
|
|
165
|
+
"string",
|
|
166
|
+
"null"
|
|
167
|
+
],
|
|
168
|
+
"description": "Path of the `pr-context.md` that `keryx review context-collect` wrote into the review package: every review comment in full, the round-1 intent, the CI status and the backend pins the pull request names. Required of a pull-request review by `keryx review dispatch-check --pr-context <package>`; a reviewer reads it before the diff."
|
|
169
|
+
},
|
|
163
170
|
"round": {
|
|
164
171
|
"type": "integer",
|
|
165
172
|
"minimum": 1,
|
|
@@ -216,6 +223,46 @@
|
|
|
216
223
|
"additionalProperties": true
|
|
217
224
|
}
|
|
218
225
|
},
|
|
226
|
+
"layers": {
|
|
227
|
+
"type": "object",
|
|
228
|
+
"description": "The bounded layers block for this reviewer's files, built from the package's own graph, the working-copy wiki and the memory (`keryx review layers block --package <dir> --files <a,b>`). Optional. `truncated` names what was cut and the command that fetches the rest.",
|
|
229
|
+
"required": ["version", "files", "affected", "truncated"],
|
|
230
|
+
"properties": {
|
|
231
|
+
"version": { "const": 1 },
|
|
232
|
+
"files": { "type": "array", "items": { "type": "string" } },
|
|
233
|
+
"prHead": { "type": ["string", "null"] },
|
|
234
|
+
"graphCommit": { "type": ["string", "null"] },
|
|
235
|
+
"maxBytes": { "type": "integer", "minimum": 1 },
|
|
236
|
+
"affected": {
|
|
237
|
+
"type": "object",
|
|
238
|
+
"required": ["depth", "files"],
|
|
239
|
+
"properties": {
|
|
240
|
+
"depth": { "enum": [1, 2] },
|
|
241
|
+
"files": { "type": "array", "items": { "type": "string" } }
|
|
242
|
+
},
|
|
243
|
+
"additionalProperties": false
|
|
244
|
+
},
|
|
245
|
+
"symbols": { "type": "array", "items": { "type": "object" } },
|
|
246
|
+
"relatedTests": { "type": "array", "items": { "type": "string" } },
|
|
247
|
+
"wiki": { "type": "array", "items": { "type": "object" } },
|
|
248
|
+
"memory": { "type": "array", "items": { "type": "object" } },
|
|
249
|
+
"truncated": {
|
|
250
|
+
"type": "array",
|
|
251
|
+
"items": {
|
|
252
|
+
"type": "object",
|
|
253
|
+
"required": ["section", "shown", "total", "command"],
|
|
254
|
+
"properties": {
|
|
255
|
+
"section": { "enum": ["files", "affected", "symbols", "relatedTests", "wiki", "memory"] },
|
|
256
|
+
"shown": { "type": "integer", "minimum": 0 },
|
|
257
|
+
"total": { "type": "integer", "minimum": 0 },
|
|
258
|
+
"command": { "type": "string" }
|
|
259
|
+
},
|
|
260
|
+
"additionalProperties": false
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
},
|
|
264
|
+
"additionalProperties": false
|
|
265
|
+
},
|
|
219
266
|
"metaproject": {
|
|
220
267
|
"type": "object",
|
|
221
268
|
"description": "Shared project context, the same context `keryx flow init` already collects for an implementation flow. The review pipeline collected none of it for eleven rounds, which is why a recorded lesson naming the exact recurring failure never reached a reviewer.",
|
package/src/gdskills/bundled/skills/review/review-orchestrator/templates/pr-comment-frontend.md
CHANGED
|
@@ -16,7 +16,7 @@ React / MobX
|
|
|
16
16
|
- Disposers run on unmount; an async callback checks them before writing.
|
|
17
17
|
- State that outlives the view lives in the store, not in `useState`.
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
Acme conventions (skip a line the repository has no rule for)
|
|
20
20
|
|
|
21
21
|
- `t()` only in render, no `defaultValue`.
|
|
22
22
|
- Arabic plurals and FSI/PDI isolates where the catalog has them.
|
|
@@ -339,21 +339,21 @@ Stop and re-read these rules if you are thinking:
|
|
|
339
339
|
|
|
340
340
|
## Job Context Awareness
|
|
341
341
|
|
|
342
|
-
When dispatched by `
|
|
342
|
+
When dispatched by `review-orchestrator` or `job-orchestrator`, the prompt MAY carry `JOB_NAME` and `CONTEXT_PATH: .metaproject/jobs/<job-name>/ai/context.md`. If given and the file exists, read it before you start; use it for intentional design decisions (do not flag correct library usage), acceptance criteria when there is no `issue_url`, and the severity of edge cases the team accepted. If absent, proceed normally: context is optional and non-blocking.
|
|
343
343
|
|
|
344
|
-
|
|
345
|
-
JOB_NAME: <job-name>
|
|
346
|
-
CONTEXT_PATH: <JOBS_ROOT>/<job-name>/ai/context.md
|
|
347
|
-
```
|
|
344
|
+
## Orchestrated Review Contract
|
|
348
345
|
|
|
349
|
-
|
|
350
|
-
- Understand expected dataset sizes and traffic patterns documented for the project
|
|
351
|
-
- Identify ORM and caching strategies already in place (avoid flagging already-cached paths)
|
|
352
|
-
- Understand which MobX patterns and React memo conventions the project follows
|
|
353
|
-
- Avoid flagging intentional trade-offs (e.g., a known small dataset where pagination is explicitly deferred)
|
|
346
|
+
When dispatched by `review-orchestrator`, follow the provided `reviewer-input.schema.json` payload. Return a `REVIEW_RESULT` object compatible with `.metaproject/skills/gdskills/review/review-orchestrator/reviewer-finding.schema.json`, then a concise markdown summary. Keep findings evidence-based, include concrete `suggested_fix` for every blocker/major, and return `NEEDS_CONTEXT` instead of guessing when required context is missing.
|
|
354
347
|
|
|
355
|
-
|
|
348
|
+
<!-- keryx:layers-block:start -->
|
|
349
|
+
## Project layers: graph, tests, wiki, memory
|
|
356
350
|
|
|
357
|
-
|
|
351
|
+
Your payload may carry a `layers` block for your files: the files the graph says are affected, symbol neighbours, related tests, the wiki pages that describe the files and the memory entries for their module. It is bounded, and `truncated` names what was cut and the command that fetches the rest. When the diff alone does not settle a question, ask the project. Each command below is read-only and calls no model.
|
|
358
352
|
|
|
359
|
-
|
|
353
|
+
- `keryx gdgraph affected <file>`: who depends on the file. Use it before you call a change contained, and whenever a changed export, signature or behaviour may have callers outside your files.
|
|
354
|
+
- `keryx test related <file>`: the tests that cover the file. Use it before you say a behaviour is untested, and to judge whether a test would fail if the code broke.
|
|
355
|
+
- `keryx wiki ask "<q>"`: what the project wiki says a module is for and which rules bind it. Use it when the intent of the code is unclear and the diff does not state it.
|
|
356
|
+
- `keryx memory search "<q>"`: recorded lessons, decisions and known mistakes. Use it before you report a pattern the project may already have decided on, and when a failure looks like one it has seen.
|
|
357
|
+
|
|
358
|
+
In a review package, `keryx gdgraph affected <file> --data-dir <package>/layers/graph` reads the graph built at the PR head; the tracked graph may be from another commit. A finding still rests on the code you read: what a layer says is a lead, not evidence. If a layer is empty or a command fails, say so in the report instead of guessing.
|
|
359
|
+
<!-- keryx:layers-block:end -->
|
|
@@ -168,20 +168,11 @@ Severity comes from **Severity (canonical)** in `review-orchestrator/SKILL.md`;
|
|
|
168
168
|
|
|
169
169
|
### Shared laws (every reviewer)
|
|
170
170
|
|
|
171
|
-
1. **A claim of runtime harm with no reproducible path is `info`.** If you cannot
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
pattern because it is often wrong elsewhere.
|
|
177
|
-
3. **One finding per class, not one per occurrence.** When the same shape appears
|
|
178
|
-
at several sites, report it once and list every site. Ten findings that are one
|
|
179
|
-
finding hide the other nine problems.
|
|
180
|
-
|
|
181
|
-
Severity levels are defined once, in `review-orchestrator/SKILL.md` →
|
|
182
|
-
**Severity (canonical)**. This reviewer does not restate them: `blocker` is the
|
|
183
|
-
four merge-blocking shapes named there and nothing else, and the `major`/`minor`
|
|
184
|
-
boundary is the trigger-and-outcome test.
|
|
171
|
+
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.
|
|
172
|
+
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.
|
|
173
|
+
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.
|
|
174
|
+
|
|
175
|
+
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.
|
|
185
176
|
|
|
186
177
|
---
|
|
187
178
|
|
|
@@ -203,14 +194,21 @@ boundary is the trigger-and-outcome test.
|
|
|
203
194
|
|
|
204
195
|
Report done only once all of these hold:
|
|
205
196
|
|
|
206
|
-
- Every finding is anchored inside the computed set or the changed set, at the
|
|
207
|
-
|
|
208
|
-
- Every finding
|
|
209
|
-
|
|
210
|
-
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
197
|
+
- Every finding is anchored inside the computed set or the changed set, at the code that **breaks** rather than the code that changed.
|
|
198
|
+
- Every finding is `major` or above, and every `major` names the changed file, module or symbol whose behaviour moved — the anchor alone does not carry it.
|
|
199
|
+
- Every finding carries `class_scope` whose `sites` are the callers that break and whose `enumeration_method` is the walk over the blast-radius set that produced them.
|
|
200
|
+
- The summary states whether the cap dropped files, and whether the radius could answer the question at all for the shape of this change.
|
|
201
|
+
- Nothing that is merely an observation about pre-existing code is filed here; it is either raised under scope A or not at all.
|
|
202
|
+
|
|
203
|
+
<!-- keryx:layers-block:start -->
|
|
204
|
+
## Project layers: graph, tests, wiki, memory
|
|
205
|
+
|
|
206
|
+
Your payload may carry a `layers` block for your files: the files the graph says are affected, symbol neighbours, related tests, the wiki pages that describe the files and the memory entries for their module. It is bounded, and `truncated` names what was cut and the command that fetches the rest. When the diff alone does not settle a question, ask the project. Each command below is read-only and calls no model.
|
|
207
|
+
|
|
208
|
+
- `keryx gdgraph affected <file>`: who depends on the file. Use it before you call a change contained, and whenever a changed export, signature or behaviour may have callers outside your files.
|
|
209
|
+
- `keryx test related <file>`: the tests that cover the file. Use it before you say a behaviour is untested, and to judge whether a test would fail if the code broke.
|
|
210
|
+
- `keryx wiki ask "<q>"`: what the project wiki says a module is for and which rules bind it. Use it when the intent of the code is unclear and the diff does not state it.
|
|
211
|
+
- `keryx memory search "<q>"`: recorded lessons, decisions and known mistakes. Use it before you report a pattern the project may already have decided on, and when a failure looks like one it has seen.
|
|
212
|
+
|
|
213
|
+
In a review package, `keryx gdgraph affected <file> --data-dir <package>/layers/graph` reads the graph built at the PR head; the tracked graph may be from another commit. A finding still rests on the code you read: what a layer says is a lead, not evidence. If a layer is empty or a command fails, say so in the report instead of guessing.
|
|
214
|
+
<!-- keryx:layers-block:end -->
|
|
@@ -342,21 +342,7 @@ Stop and re-read these rules if you are thinking:
|
|
|
342
342
|
|
|
343
343
|
## Job Context Awareness
|
|
344
344
|
|
|
345
|
-
When dispatched by `
|
|
346
|
-
|
|
347
|
-
```
|
|
348
|
-
JOB_NAME: <job-name>
|
|
349
|
-
CONTEXT_PATH: <JOBS_ROOT>/<job-name>/ai/context.md
|
|
350
|
-
```
|
|
351
|
-
|
|
352
|
-
If provided and the file exists, read the context document before starting the review. Use it to:
|
|
353
|
-
- Understand which auth framework is in use (custom JWT, Passport, Keycloak, etc.)
|
|
354
|
-
- Identify intentional public endpoints that are documented as unauthenticated by design
|
|
355
|
-
- Understand which validation library and pipe configuration the project uses
|
|
356
|
-
- Avoid flagging intentional architectural security decisions as findings
|
|
357
|
-
|
|
358
|
-
If the file does not exist or is not provided, proceed normally — context is optional and non-blocking.
|
|
359
|
-
|
|
345
|
+
When dispatched by `review-orchestrator` or `job-orchestrator`, the prompt MAY carry `JOB_NAME` and `CONTEXT_PATH: .metaproject/jobs/<job-name>/ai/context.md`. If given and the file exists, read it before you start; use it for intentional design decisions (do not flag correct library usage), acceptance criteria when there is no `issue_url`, and the severity of edge cases the team accepted. If absent, proceed normally: context is optional and non-blocking.
|
|
360
346
|
|
|
361
347
|
## Orchestrated Review Contract
|
|
362
348
|
|
|
@@ -364,3 +350,15 @@ When dispatched by `review-orchestrator`, follow the provided `reviewer-input.sc
|
|
|
364
350
|
|
|
365
351
|
---
|
|
366
352
|
|
|
353
|
+
<!-- keryx:layers-block:start -->
|
|
354
|
+
## Project layers: graph, tests, wiki, memory
|
|
355
|
+
|
|
356
|
+
Your payload may carry a `layers` block for your files: the files the graph says are affected, symbol neighbours, related tests, the wiki pages that describe the files and the memory entries for their module. It is bounded, and `truncated` names what was cut and the command that fetches the rest. When the diff alone does not settle a question, ask the project. Each command below is read-only and calls no model.
|
|
357
|
+
|
|
358
|
+
- `keryx gdgraph affected <file>`: who depends on the file. Use it before you call a change contained, and whenever a changed export, signature or behaviour may have callers outside your files.
|
|
359
|
+
- `keryx test related <file>`: the tests that cover the file. Use it before you say a behaviour is untested, and to judge whether a test would fail if the code broke.
|
|
360
|
+
- `keryx wiki ask "<q>"`: what the project wiki says a module is for and which rules bind it. Use it when the intent of the code is unclear and the diff does not state it.
|
|
361
|
+
- `keryx memory search "<q>"`: recorded lessons, decisions and known mistakes. Use it before you report a pattern the project may already have decided on, and when a failure looks like one it has seen.
|
|
362
|
+
|
|
363
|
+
In a review package, `keryx gdgraph affected <file> --data-dir <package>/layers/graph` reads the graph built at the PR head; the tracked graph may be from another commit. A finding still rests on the code you read: what a layer says is a lead, not evidence. If a layer is empty or a command fails, say so in the report instead of guessing.
|
|
364
|
+
<!-- keryx:layers-block:end -->
|