@mrciphersmith/keryx 0.3.112 → 0.3.114
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 +21 -3
- package/THIRD_PARTY_NOTICES.md +56 -0
- package/dist/cli.js +95320 -90301
- package/dist/core.js +5528 -4330
- 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 +3 -3
- package/src/gdskills/bundled/skills/review/review-orchestrator/SKILL.md +27 -25
- 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 +53 -0
- package/src/gdskills/bundled/skills/review/review-orchestrator/templates/pr-comment-frontend.md +1 -1
- package/src/gdskills/bundled/skills/review/review-orchestrator/templates/review-report.md +22 -0
- 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
|
|
@@ -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
|
|
|
@@ -207,8 +207,7 @@ keryx review complete <review-id-or-path>
|
|
|
207
207
|
[--finding <id> --disposition <state> --evidence <ref>]...
|
|
208
208
|
```
|
|
209
209
|
|
|
210
|
-
**An unrecognised option is refused, not ignored** — a misspelled flag exits
|
|
211
|
-
non-zero rather than printing `status: closed` and writing nothing at all.
|
|
210
|
+
**An unrecognised option is refused, not ignored** — a misspelled flag exits non-zero rather than printing `status: closed` and writing nothing at all.
|
|
212
211
|
|
|
213
212
|
`--verifications` takes what `review-verifier` returned. `--scope` takes the
|
|
214
213
|
whole `--json` output of `keryx review scope`, so the package records what the
|
|
@@ -234,9 +233,7 @@ Two channels, and both work:
|
|
|
234
233
|
it: it is copied into the package it screened and removed from the slot, so a
|
|
235
234
|
later round cannot be screened against a set nobody recomputed.
|
|
236
235
|
|
|
237
|
-
Do **not** write the record inside the package directory before the ingest. A
|
|
238
|
-
round that names no `--review-id` has not allocated that directory yet, and
|
|
239
|
-
creating it makes the ingest take the next free name instead.
|
|
236
|
+
Do **not** write the record inside the package directory before the ingest. A round that names no `--review-id` has not allocated that directory yet, and creating it makes the ingest take the next free name instead.
|
|
240
237
|
|
|
241
238
|
`--refuted` takes the findings this round **raised and then dismissed**, in the
|
|
242
239
|
same finding shape, each carrying `disposition: {state, evidence}` with one of
|
|
@@ -252,9 +249,12 @@ Everything except `unknown` must cite where the outcome is written down — the
|
|
|
252
249
|
commit, the test, the decision. A recorded state and its citation cannot be
|
|
253
250
|
overwritten by a later close; record a correction as a new round.
|
|
254
251
|
|
|
255
|
-
|
|
256
|
-
`
|
|
257
|
-
|
|
252
|
+
`review complete` on a PR-bound package refuses a merged PR or a moved head unless `report.md`'s first line names the reviewed SHA and says so; a package with no PR binding is unaffected.
|
|
253
|
+
`review complete` refuses a report with no `Evidence level:` line (`static only — did not run: <what>` or `ran — <what>`); a package ingested before the field existed only warns.
|
|
254
|
+
`review ingest` refuses an internal finding whose `quote` is not at its `path` at the reviewed SHA, and adds a `citation not found` line, never a deletion, to a rebuttal citing a rule or document that is not in the tree.
|
|
255
|
+
A finding may close as `narrowed` (research obligation `"status":"narrowed","remains":"<what remains>"`); it counts as closed only with that text, and the report keeps it under "Refuted and narrowed".
|
|
256
|
+
|
|
257
|
+
**Closing a fix round without dispositions leaves every finding reading `unknown`.** That is not "the reviewers were right"; it is "nobody wrote down what happened", and it is the single reason the precision figure cannot be read.
|
|
258
258
|
|
|
259
259
|
Managed modes:
|
|
260
260
|
|
|
@@ -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
|
|
@@ -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": [
|
|
@@ -223,6 +223,59 @@
|
|
|
223
223
|
"additionalProperties": true
|
|
224
224
|
}
|
|
225
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
|
+
"unavailable": {
|
|
264
|
+
"type": "array",
|
|
265
|
+
"description": "Sections that could not be read, with the reason. An empty section that is not listed here was read and held nothing.",
|
|
266
|
+
"items": {
|
|
267
|
+
"type": "object",
|
|
268
|
+
"required": ["section", "reason"],
|
|
269
|
+
"properties": {
|
|
270
|
+
"section": { "enum": ["affected", "wiki", "memory"] },
|
|
271
|
+
"reason": { "type": "string" }
|
|
272
|
+
},
|
|
273
|
+
"additionalProperties": false
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
},
|
|
277
|
+
"additionalProperties": false
|
|
278
|
+
},
|
|
226
279
|
"metaproject": {
|
|
227
280
|
"type": "object",
|
|
228
281
|
"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.
|
|
@@ -34,8 +34,10 @@ what a reader must act on; everything else is folded.
|
|
|
34
34
|
|
|
35
35
|
```markdown
|
|
36
36
|
<!-- slot:pre-verdict -->
|
|
37
|
+
<only when the PR merged or its head moved: "Reviewed `<sha>` — the PR has since merged / moved on to `<new sha>`." as the very first line>
|
|
37
38
|
**Changes requested — 1 Blocker, 2 Major, 4 Minor, 1 question.** <what holds, and where the risk is — one sentence.>
|
|
38
39
|
Reviewed `<head>` against `<base>` · round N · <files> files, +<add>/−<del> · CI <green | red: check names>.
|
|
40
|
+
Evidence level: <static only — did not run: tests, build | ran — the commands that ran>
|
|
39
41
|
<!-- slot:after-verdict -->
|
|
40
42
|
|
|
41
43
|
### Prior findings (fix rounds only)
|
|
@@ -43,6 +45,7 @@ Reviewed `<head>` against `<base>` · round N · <files> files, +<add>/−<del>
|
|
|
43
45
|
### Major
|
|
44
46
|
### Minor
|
|
45
47
|
### Questions
|
|
48
|
+
### Refuted and narrowed (only when a finding was dismissed or narrowed)
|
|
46
49
|
|
|
47
50
|
<details><summary><b>Pre-existing (not blocking)</b></summary> … </details>
|
|
48
51
|
<details><summary><b>Scope</b></summary> … </details> (only when a pr-process note exists)
|
|
@@ -68,6 +71,25 @@ author answer, rendered under Questions, not as a finding.
|
|
|
68
71
|
The second line is the context line: head, base, round, size, CI. If head moved
|
|
69
72
|
during the round, add `· unchecked: <commits>`.
|
|
70
73
|
|
|
74
|
+
The third line is the **evidence level** and is required: `Evidence level: static
|
|
75
|
+
only — did not run: <what>` when nothing was executed, or `Evidence level: ran —
|
|
76
|
+
<what ran>`. `keryx review complete` refuses a report without it.
|
|
77
|
+
|
|
78
|
+
When the PR was merged or its head moved after the review, the report's first line
|
|
79
|
+
says so and names the reviewed SHA, or `keryx review complete` refuses.
|
|
80
|
+
|
|
81
|
+
### Refuted and narrowed
|
|
82
|
+
|
|
83
|
+
One line per finding that did not stand as reported, kept with its evidence so a
|
|
84
|
+
reader sees what was claimed and why it was set aside:
|
|
85
|
+
|
|
86
|
+
```markdown
|
|
87
|
+
- **F-007. Dismissed** — <the author's rebuttal, quoted>. <citation not found: …> where the cited rule is not in the tree.
|
|
88
|
+
- **F-009. Narrowed** — <what the finding claimed>. **Remains:** <what is still open>. Evidence: <what was run>.
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
A narrowed finding counts as closed only with its "Remains" text.
|
|
92
|
+
|
|
71
93
|
## One finding
|
|
72
94
|
|
|
73
95
|
Blocker and Major as a paragraph, visible:
|
|
@@ -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 -->
|