@mrciphersmith/keryx 0.3.118 → 0.3.120

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.
Files changed (34) hide show
  1. package/dist/cli.js +104554 -96795
  2. package/dist/core.js +1767 -1061
  3. package/package.json +1 -1
  4. package/src/gdgraph/service.ts +4 -0
  5. package/src/gdgraph/symbol-reach.ts +1069 -0
  6. package/src/gdskills/bundled/skills/orchestration/feature-dev/SKILL.md +1 -1
  7. package/src/gdskills/bundled/skills/orchestration/flow-orchestrator/SKILL.md +37 -40
  8. package/src/gdskills/bundled/skills/orchestration/job-orchestrator/SKILL.md +6 -6
  9. package/src/gdskills/bundled/skills/orchestration/job-orchestrator/orchestrator-prompt.md +1 -1
  10. package/src/gdskills/bundled/skills/orchestration/task-implementer/SKILL.md +12 -18
  11. package/src/gdskills/bundled/skills/orchestration/task-implementer/input-contract.schema.json +8 -0
  12. package/src/gdskills/bundled/skills/orchestration/task-implementer/output-contract.schema.json +19 -0
  13. package/src/gdskills/bundled/skills/platform/scheduled-tasks/SKILL.md +2 -2
  14. package/src/gdskills/bundled/skills/review/review-architecture/SKILL.md +1 -1
  15. package/src/gdskills/bundled/skills/review/review-backend/SKILL.md +1 -1
  16. package/src/gdskills/bundled/skills/review/review-clean-code/SKILL.md +1 -1
  17. package/src/gdskills/bundled/skills/review/review-core-boundaries/SKILL.md +1 -1
  18. package/src/gdskills/bundled/skills/review/review-flow-graph/SKILL.md +1 -1
  19. package/src/gdskills/bundled/skills/review/review-frontend/SKILL.md +3 -7
  20. package/src/gdskills/bundled/skills/review/review-frontend-conventions/SKILL.md +4 -6
  21. package/src/gdskills/bundled/skills/review/review-highload/SKILL.md +1 -1
  22. package/src/gdskills/bundled/skills/review/review-logic/SKILL.md +2 -2
  23. package/src/gdskills/bundled/skills/review/review-orchestrator/SKILL.detail.md +82 -17
  24. package/src/gdskills/bundled/skills/review/review-orchestrator/SKILL.md +78 -111
  25. package/src/gdskills/bundled/skills/review/review-orchestrator/reviewer-finding.schema.json +13 -0
  26. package/src/gdskills/bundled/skills/review/review-orchestrator/reviewer-input.schema.json +38 -0
  27. package/src/gdskills/bundled/skills/review/review-performance/SKILL.md +1 -1
  28. package/src/gdskills/bundled/skills/review/review-pr-feedback/SKILL.md +1 -1
  29. package/src/gdskills/bundled/skills/review/review-regression/SKILL.md +2 -2
  30. package/src/gdskills/bundled/skills/review/review-security-code/SKILL.md +1 -1
  31. package/src/gdskills/bundled/skills/review/review-style/SKILL.md +1 -1
  32. package/src/gdskills/bundled/skills/review/review-testing-practices/SKILL.md +1 -1
  33. package/src/gdskills/bundled/skills/review/review-verifier/SKILL.md +3 -3
  34. package/src/gdskills/contracts/review-finding.schema.json +25 -0
@@ -173,8 +173,8 @@ When one is absent:
173
173
 
174
174
  - **A legacy reviewer a flag asked for** is not dispatched and not replaced.
175
175
  Record it in `Skipped reviewers` with reason `not-installed` and the command
176
- below. `--legacy-profiles` and `--all` dispatch the legacy reviewers that are
177
- installed and record the others the same way. Leave an absent reviewer out of
176
+ below. `--legacy-profiles` dispatches the legacy reviewers that are
177
+ installed and records the others the same way; `--all` never selects them. Leave an absent reviewer out of
178
178
  the `Optional legacy/profile reviewers` preview: offering a flag that cannot
179
179
  run is worse than not offering it.
180
180
  - **`review-pr-feedback`** changes nothing about a round. No caller can declare
@@ -383,7 +383,7 @@ A review must be reproducible from its package: the same inputs give the same co
383
383
 
384
384
  **One memory read, and the log.** The stage query is `keryx memory search "<changed modules and the concepts they touch>" --status accepted`, once. Pass the same text to `keryx review start … --memory-query "<query>"` so the manifest's `cleanContext` block holds it next to the start time. keryx writes the orchestrator log, `<package>/tool-calls/orchestrator.jsonl`, on its own: `keryx review start` and `keryx review attach` mark the package active, and every `keryx memory` command and every MCP memory tool (`memory_search`, `memory_handoff`, `memory_propose`) appends one line naming its caller. You do not write that file and must not edit it; a hand-written line is a forgery the readiness item cannot tell apart from a record. A call by a `spawn_subagent` child is recorded under the child's reviewer id and is not judged by item 10. A call from a host that names no caller is recorded as `unattributed`: it warns in the item's detail line and never blocks. Reviewer logs stay in their own files.
385
385
 
386
- Item 10, `memory-outside-stage`, reads that log. Outside the stage is: a memory search with a different query, a search without `--status accepted`, any other memory command or MCP memory tool, and a stage call stamped before the round started. The same query repeated is the stage. Repair is to rerun from a session whose only memory read is the stage; only `keryx review complete <package> --waive memory-outside-stage "<operator quote>"` from a terminal lifts it. With no orchestrator log the item passes and its evidence says it could not see your reads; with a log that holds no memory call it passes and says so. Only calls that go through keryx are visible: a read through a tool keryx does not wrap is not in the log.
386
+ Item 10, `memory-outside-stage`, reads that log. Outside the stage is: a memory search with a different query, a search without `--status accepted`, any other memory command or MCP memory tool, and a stage call stamped before the round started. The same query repeated is the stage. Repair is to rerun from a session whose only memory read is the stage; only the operator's waiver lifts it: in keryx shell call `review_waive_readiness` (the operator answers a card, never a terminal), then run `keryx review complete <package>`; outside keryx shell `keryx review complete <package> --waive memory-outside-stage "<operator quote>"` in a terminal; unattended, record Not run. With no orchestrator log the item passes and its evidence says it could not see your reads; with a log that holds no memory call it passes and says so. Outside keryx shell, `keryx review start` prints a caller token (`export KERYX_REVIEW_CALLER_TOKEN=…`): export it on this session's keryx calls so they are attributed to you; without it the item reads "not observable on this host" rather than a clean pass. Only calls that go through keryx are visible: a read through a tool keryx does not wrap is not in the log.
387
387
 
388
388
  **Open questions.** One general rule, replacing per-fork wording: the answer is in this skill or `SKILL.detail.md`, or it is the user's. Interactive: one `AskUserQuestion`. Unattended: the whole output is one line, `STATUS: BLOCKED question — <the question>`, and you stop. A guess and a recollection are both wrong answers.
389
389
 
@@ -430,7 +430,7 @@ records them under `### How this review was run`.
430
430
  ```text
431
431
  Context: <PR or branch>, <N> files / <N> lines, <domains>; risk: <class>
432
432
 
433
- 1) Reviewers A) --all (default) B) tests only C) <domain> only D) choose
433
+ 1) Reviewers A) the `required --depth auto` set (default) B) --all C) tests only D) <domain> only E) choose
434
434
  2) Counterpart found: <endpoints, rules, paired PR — or "no link found">
435
435
  A) verify <backend|frontend> (default) B) skip — give a reason
436
436
  3) Models complexity: <low|medium|high>; <role>: <tier> → <model>, …
@@ -462,10 +462,12 @@ flow (`flow-orchestrator` Phase 3), a pre-merge or pre-ship review, a
462
462
  re-request after fixes. A gating round runs the composition the start questions
463
463
  selected.
464
464
 
465
- - **No dispatch tool, no review.** A host that cannot dispatch subagents — no
466
- spawn tool, or the depth budget spent — returns
467
- `STATUS: BLOCKED` with reason `nested_dispatch_unavailable` and no verdict.
468
- It does not review the diff alone and call that a round. Measured (flow 405):
465
+ - **No dispatch tool, no review.** A host with no spawn tool hands the round to
466
+ the autonomous runner (`keryx review run --autonomous --target pr --ref <pull
467
+ request URL>`, or `--target branch --ref <base> [--head <commit>]`), which
468
+ spawns the reviewers itself; a nested session whose depth budget is spent
469
+ returns `STATUS: BLOCKED` with reason `nested_dispatch_unavailable` and no
470
+ verdict. Neither reviews the diff alone and calls that a round. Measured (flow 405):
469
471
  a single-agent round on a 150-line frontend PR wrote "did not dispatch any
470
472
  sub-reviewers", approved it with two cosmetic minors, and the next human round
471
473
  filed six real findings, every one reachable from the diff and the backend at
@@ -649,10 +651,10 @@ certifies the flow is the one that checked the least.
649
651
 
650
652
  ## Readiness — the checklist behind `completed` and behind publishing
651
653
 
652
- `keryx review readiness <review-id-or-path> [--json]` reads the package and prints nine items, READY or NOT READY, each with the evidence and the command that repairs it. It writes nothing, and exits non-zero when the verdict is NOT READY. Only item 9 reaches GitHub (the PR's own file list); the TUI and `review status` read the package alone.
654
+ `keryx review readiness <review-id-or-path> [--json]` reads the package and prints ten items, READY or NOT READY, each with the evidence and the command that repairs it. It writes nothing, and exits non-zero when the verdict is NOT READY. Only item 9 reaches GitHub (the PR's own file list); the TUI and `review status` read the package alone.
653
655
 
654
656
  1. `files-covered` — every changed file is in a wave or carries a recorded waiver.
655
- 2. `blast-radius` — no file the blast radius cut is left unreviewed. A cut radius writes `chunks.json`; run `keryx review chunks plan`, `estimate`, `next`/`record`, `merge`. In an unattended run every wave runs without a question, up to the 25-pass ceiling; in an interactive run the operator is asked once.
657
+ 2. `blast-radius` — no file the blast radius cut is left unreviewed. A cut radius writes `chunks.json`; run `keryx review chunks plan`, `estimate`, `next`/`record`, `merge`. In an unattended run every wave runs without a question, up to the 25-pass ceiling; in an interactive run the operator is asked once: in keryx shell call `review_chunks_answer` (a card, never a terminal); elsewhere the operator runs `keryx review chunks estimate --package <dir> --answer yes --quote "<their words>"` in their terminal; unattended, record Not run.
656
658
  3. `reviewers` — every planned reviewer was dispatched and its result ingested.
657
659
  4. `verifier` — the verifier checked every finding it should, or the report says how many it did not.
658
660
  5. `ledger` — the ledger is READY.
@@ -660,8 +662,9 @@ certifies the flow is the one that checked the least.
660
662
  7. `head` — the report's head is the PR head.
661
663
  8. `report-names` — pending mutation candidates and parity warnings are named in the report.
662
664
  9. `pr-files` — the changed-file count equals the PR's own file list. A recount more than 3x the recorded scope is refused: it came from the wrong base. Recount with `keryx review blast-radius --package <ref> --changed <the PR's files>`.
665
+ 10. `memory-outside-stage` — the orchestrator read memory only in its memory stage ("Clean context" above). Outside keryx shell it reads "not observable on this host" unless this session's keryx calls carry the caller token `keryx review start` printed.
663
666
 
664
- `keryx review complete` refuses status `completed` while any item fails. A failing item is waived only by the operator, in a terminal: `keryx review complete --waive <item> "<their own words>"`, repeatable; the waiver is recorded with the quote and the time. `keryx review publish` is held by the same checklist. A not-ready package goes to GitHub only through `keryx review publish --partial`, which puts a "Partial review" header on the post and never approves. The shell guard stops a publish command that runs through the keryx shell; a publisher outside it (CI, another agent, a script file) is not stopped, and that limit is named, not hidden.
667
+ `keryx review complete` refuses status `completed` while any item fails. A failing item is waived only by the operator. In keryx shell call `review_waive_readiness` for the item: the operator answers it as a card, the waiver is recorded with the card text and the time, and then you run `keryx review complete`. Never send the operator to a terminal. Outside keryx shell the operator runs `keryx review complete --waive <item> "<their own words>"` in a terminal, repeatable. Unattended, record the item as Not run. `keryx review publish` is held by the same checklist. Publishing is the operator's decision too: in keryx shell call `review_publish` (a card shows the target and the body; never send the operator to a terminal). A not-ready package goes to GitHub only as a partial review (`review_publish` with `partial: true`, or `keryx review publish --partial`), which puts a "Partial review" header on the post and never approves. The shell guard stops a publish command that runs through the keryx shell; a publisher outside it (CI, another agent, a script file) is not stopped, and that limit is named, not hidden.
665
668
 
666
669
  ## Fix rounds — dispositions, regressions, withdrawal
667
670
 
@@ -684,6 +687,20 @@ sync as abandoned"* is a claim; the disposition is whether the branch it renamed
684
687
  is reachable and pinned. On a recorded round, two such commits asserted behaviour
685
688
  on lines no test could reach.
686
689
 
690
+ ### Delta rounds — what `review start` hands you
691
+
692
+ `keryx review start` detects the round and writes `<package>/round.json` and `<package>/prior_findings.json`. It searches every source, because the earlier round may have run on another machine: the local package, git history (tracked package files), the PR's `keryx round` block, PR comments, and the flow's packages. `round.json` carries `round`, `source`, `sourcesTried`, `previous`, `mode`, `range`, `fixHunks`, `newHunks` and `carried`.
693
+
694
+ | `mode` | `range` | Review |
695
+ |---|---|---|
696
+ | `first` | merge-base..head | A first round. `sourcesTried` records what was searched when nothing was found. |
697
+ | `delta` | previous head..head | `fix` slices (a hunk that answers a prior finding): `review-logic`, `review-regression`, the authors of the attached findings and the verifier, each with its `prior_findings`. `new` slices: round 1, with the roles the slice names. Unchanged code: not re-reviewed. `carried` findings keep their dispositions. |
698
+ | `fallback-first` | merge-base..head | The previous head is not an ancestor (force-push, rebase). Review the whole range with the prior findings attached. |
699
+
700
+ A fix hunk still has a radius: enumerate what names the thing it changed (`review_context.scope.files`), as in any fix round. The attached findings are the contract: each leaves the round with a disposition, below.
701
+
702
+ A reviewer on a FIX slice reports those dispositions itself: its `REVIEW_RESULT` carries `prior_dispositions: [{id, disposition}]` with one entry for every attached finding id (`disposition` is `closed`, `open`, `partial`, `regressed` or `withdrawn`), judged against the code. `keryx review ingest` reads the array into the ledger; an attached id with no entry stays undisposed.
703
+
687
704
  ### A fix is a change, and changes get reviewed
688
705
 
689
706
  The most expensive class in a multi-round review is **the defect the fix
@@ -756,9 +773,18 @@ and `.json`. A mutant is `killed` (the suite went red), `survived` (nothing pins
756
773
  behaviour), `timeout`, or `invalid` (anchor missing or not unique, file outside the copy).
757
774
  A survivor is evidence for the finding that names it.
758
775
 
759
- `keryx review complete` refuses while proposed mutants are unrun, unless
760
- `dispatch.mutationWaiver = { operatorQuote, reason }` carries the operator's own words.
761
- `keryx review run --autonomous` is unchanged: it records `Not run: mutation pass` as before.
776
+ `keryx review complete` refuses while proposed mutants are unrun on an attended round, unless the
777
+ operator waived the pass themselves: the `review_waive_mutation` card in keryx shell, or `keryx review
778
+ waive-mutation --package <review-dir> --reason "<why>"` in their terminal (it writes
779
+ `operator-decisions.json`; a `dispatch.mutationWaiver` quote you write is not enough on a package
780
+ `keryx review start` created). Attended is what the start recorded in `run-profile.json`: every round
781
+ except `review start --unattended` and `keryx review run --autonomous`, which record `Not run: mutation
782
+ pass` without asking.
783
+
784
+ These operator gates (cards, terminal-only commands, plan confirmation, decision records) keep a
785
+ cooperating agent from cutting corners and make every decision visible and attributable; they do not
786
+ stop a hostile same-user agent, which can fake a pty or write the JSON records itself (the TM-03/TM-04
787
+ boundary). The autonomous runner's mutation-gate exemption predates flow 457 and is kept on purpose.
762
788
 
763
789
  `keryx review mutate --cap <n>` runs the first `n` candidates and records `cap` and `not_reached`
764
790
  in `mutation-<n>.json`. The table then prints `Not run: N candidates` (and the report must carry
@@ -827,12 +853,13 @@ minute 119, and the PR merged first; the other re-dispatched a finished wave and
827
853
  41 slices. The operator can only act on a risk they were told about.
828
854
 
829
855
  1. On a PR target read merged / approved / CI (`gh pr view <n> --json state,reviewDecision,statusCheckRollup`). Say in one line what the state means for the round: an approved PR with green CI can merge any minute, and a merged PR makes the rest of the round a post-merge audit.
830
- 2. **Later, once the package and slices exist** (after `review scope`, `review start` and `review slice`, before the first reviewer starts): `keryx review required --mode all --scope .metaproject/data/review/scope.json --depth auto [--package <review-dir>]` prints the reviewer set and the depth it chose (see "Depth floor"); auto needs the file list and a line count, else the round is full. `keryx review estimate --package <review-dir> [--manifest <slices/manifest.json>]` prints assignments, waves and a duration range; the manifest defaults to `<package>/slices/manifest.json`, then `.metaproject/data/review/slices/manifest.json`.
856
+ 2. **Later, once the package and slices exist** (after `review scope`, `review start` and `review slice --package`, before the first reviewer starts): `keryx review required --mode all --scope .metaproject/data/review/scope.json --depth auto --package <review-dir>` prints the reviewer set and the depth it chose (see "Depth floor"); auto needs the file list and a line count, else the round is full. `keryx review estimate --package <review-dir> [--manifest <slices/manifest.json>]` prints assignments, waves and a duration range; the manifest defaults to `<package>/slices/manifest.json`, then `.metaproject/data/review/slices/manifest.json`.
831
857
  3. Show the operator depth + estimate and the merge risk before the first dispatch. Attended: let them choose `full` over a light default. Unattended: record both in the report and continue.
858
+ 4. **An over-threshold plan waits for the operator.** `estimate` flags a plan over `reviewPlan.maxDispatches` (default 40) or `reviewPlan.maxMinutes` (default 90) in `routing.config.json`; `dispatch-check --package` and `ledger build` refuse it (`REVIEWER_INPUT_PLAN_UNCONFIRMED`) until `<review-dir>/plan-confirmation.json` exists. Only the operator writes it: the `review_confirm_plan` card in keryx shell, or `keryx review confirm-plan --package <review-dir>` (or `keryx review estimate --package <review-dir> --confirm --quote "<their words>"`) in their terminal; both refuse without a TTY. Unattended, the plan is not dispatched: report the estimate and stop.
832
859
 
833
860
  ## Early verdict — the verdict is interim until `complete`
834
861
 
835
- As soon as every reviewer result and the verifier's are on disk, save each verifier pass to `research-evidence/verifications.json` first (without it a refuted finding still counts), then run `keryx review verdict <id|path> --raw .metaproject/data/review/raw [--json]` on the shell host, or without `--raw` where the round's raw results sit in `<package>/raw`. It prints the interim verdict and writes `verdict-interim.md` into the package. Give the operator that verdict in the same message; do not hold it for the mutation pass, the ledger or `complete`.
862
+ As soon as every reviewer result and the verifier's are on disk, save each verifier pass to `research-evidence/verifications.json` first (without it a refuted finding still counts), then run `keryx review verdict <id|path> [--json]`: it reads `<package>/raw`, where every host keeps the round's results (`--raw <dir>` only for results kept elsewhere; the shared `.metaproject/data/review/raw` mixes in other rounds' replies). It prints the interim verdict and writes `verdict-interim.md` into the package. Give the operator that verdict in the same message; do not hold it for the mutation pass, the ledger or `complete`.
836
863
 
837
864
  The tail keeps running after it: the mutation pass (`keryx review mutate`), `ledger build`, `ingest`, `readiness` and `keryx review complete`. Every managed round finishes them. The round is **not done** until `complete`: the verdict you gave is interim, and the report says so and names what the tail may still change (a surviving mutant, a verifier refutation, a late reviewer result). A light round has no mutation pass: its tail is `ledger build`, `ingest`, `readiness`, `complete`.
838
865
 
@@ -844,7 +871,7 @@ Do not wait for the last reviewer. When the first `blocker` or `major` finding a
844
871
 
845
872
  After a timeout, a crash or a resumed session, in this order:
846
873
 
847
- 1. **Collect.** `keryx review retry-plan --manifest <slices>/manifest.json --package <input-dir> --reviewer <id> --next-wave` reads `raw/` first and collects late reviewer results; it prints `collected late: N` and never re-hands a slice that is finished.
874
+ 1. **Collect.** `keryx review retry-plan --manifest <package>/slices/manifest.json --package <package> --reviewer <id> --next-wave` reads `<package>/raw/` first and collects late reviewer results; it prints `collected late: N` and never re-hands a slice that is finished.
848
875
  2. **Validate** each collected reply (a `STATUS:` line and a `REVIEW_RESULT` block matching `reviewer-finding.schema.json`), **ingest** it, and rebuild `research.json` with `ledger build`; run `ingest --research` once it prints READY.
849
876
  3. **Dispatch only what is missing:** the wave `retry-plan` prints. A wave whose results are on disk is never dispatched again.
850
877
  4. **A second timeout of the same reviewer changes the task, not only the diff size:** fewer slices per dispatch, a narrower focus (one concern or one directory), or a lighter model tier for a mechanical slice. Two results in a row with nothing new are `Not run`, as `retry-plan` prints.
@@ -852,3 +879,41 @@ After a timeout, a crash or a resumed session, in this order:
852
879
  ## dispatch-check on every payload
853
880
 
854
881
  Before any mass dispatch run `keryx review dispatch-check --payload <file> --manifest <dir>/manifest.json` on every payload, on every host. It fails `REVIEWER_INPUT_PATH_MISSING` when a `skill_path` or `context_doc` names a file that is not there, and still fails a payload that names no slice, exceeds the wave ceiling or breaks `reviewer-input.schema.json`. Fix the payload; a dead path costs a whole wave of refusals. Related: `review mutate` runs in a scratch copy under the repo and prints the baseline's tail when the baseline is red; `review start --graph-timeout <s>` bounds the graph build.
882
+
883
+ ## Review Plan Preview — legacy groups
884
+
885
+ ```text
886
+ Optional legacy/profile reviewers:
887
+ - code-ai-review: available via --code-ai or --legacy-profiles
888
+ - code-learned-review: available via --learned or --legacy-profiles
889
+ - code-style-review: available via --code-style or --legacy-profiles
890
+ - code-mobx-store-review: auto-suggest when *.store.ts or MobX patterns are present; available via --mobx-store or --legacy-profiles
891
+
892
+ Skipped reviewers:
893
+ - code-ai-review: profile reviewer, not selected unless --code-ai/--legacy-profiles
894
+ - code-learned-review: profile reviewer, not selected unless --learned/--legacy-profiles
895
+ - code-style-review: legacy style profile, not selected unless --code-style/--legacy-profiles
896
+ - code-mobx-store-review: not selected unless --mobx-store/--legacy-profiles or MobX store files are detected
897
+ ```
898
+
899
+ ## Token and context budget
900
+
901
+ The orchestrator owns the token budget. Sub-reviewers receive only the context their domain needs.
902
+
903
+ Budget rules:
904
+ - Compute a scope digest before dispatch: file list, diff stats, module map, and top risks.
905
+ - Send full diffs only for files relevant to each reviewer.
906
+ - For large files, send changed hunks plus nearby symbols first; include the full file only when path mode or the reviewer requires whole-file context.
907
+ - Never send generated files, lockfiles, snapshots, build output, or vendored code unless the reviewer is specifically about that file type.
908
+ - Cap each reviewer prompt with the `per_reviewer` budget when provided; otherwise use the smallest prompt that preserves evidence.
909
+ - Record omitted files and truncation in `review_context.token_policy.omissions`.
910
+ - If a reviewer returns `NEEDS_CONTEXT`, provide only the missing targeted context, not the entire repository.
911
+
912
+ Default budget guidance:
913
+
914
+ | Review size | Detection | Context mode | Dispatch style |
915
+ |---|---|---|---|
916
+ | small | <= 5 files and <= 300 changed lines | `light` | full relevant diff to selected reviewers |
917
+ | medium | <= 20 files or <= 2,000 changed lines | `light` | per-domain filtered diff |
918
+ | large | > 20 files or > 2,000 changed lines | ask `full` | staged waves by domain |
919
+ | high-risk | auth/API/core/security/data migrations | ask `full` | staged waves, verifier included |