feat(review): the critic's own security key SECURITY_RISK (decision 167)

lib/review/rule-catalogue.mjs gains SECURITY_RISK (BLOCKER, category
security, memory route rule): Voyage's own security key for a finding by
its own reviewers that SECURITY_INJECTION does not cover.
SECURITY_REVIEW_VULNERABILITY is described as the engines' key only.
plan-critic and scope-guardian name SECURITY_INJECTION or SECURITY_RISK
and no longer the engines' key.

The count moves from 17 to 18 in every pin: rule-catalogue.test,
claude-md-scope [CAT] (which now also refuses a stale 17), doc-consistency,
review-prose-pins, docs/architecture.md and the two reviewer agents.
critic-severity-rules pins three security keys; its "every security key
named" check leaves out the engines' key, and a new pin says the critic
never names it.

Existing tests changed for the planned rule: the four count pins above
(17 -> 18), and critic-severity-rules' two-key test (now three keys).
tests/lib/engine-findings.test.mjs: a comment naming the "(17 keys)" pin
now says 18.

Part 2, step 2.3 of the E plan.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-11-08 08:55:34 +01:00
commit 5cb2918baa
Signed by: ktg
SSH key fingerprint: SHA256:JakMjO6FTBBzN0Bhfj9saOoEjaFxlSdYuZQQpM/lF9Q
12 changed files with 67 additions and 31 deletions

View file

@ -1,7 +1,7 @@
// lib/review/rule-catalogue.mjs
// Canonical rule catalogue for /trekreview.
//
// 17 rule keys, 4-tier severity (matches brief contract). Decision 98 added
// 18 rule keys, 4-tier severity (matches brief contract). Decision 98 added
// CLAUDE_MD_DEVIATION and CLAUDE_MD_STALE (both MINOR): a change that breaks, or
// makes untrue, a line of the target repo's tracked instruction files.
// llm-security 5-tier alignment is a v1.1 candidate.
@ -14,6 +14,13 @@
// style, readability): the second voyage-lekerepo trial (2026-10-08) saw a pure
// simplification proposal enter as MAJOR and drive the verdict.
//
// E 2.3 (decision 167) added SECURITY_RISK (BLOCKER): Voyage's own security
// key, for a security finding by its own reviewers (plan-critic,
// scope-guardian, the code reviewer's part for command texts) that
// SECURITY_INJECTION does not cover. SECURITY_REVIEW_VULNERABILITY is the
// engines' key only: Voyage's reviewers never use it, and a finding under it
// is never Voyage's own (lib/review/threat-model.mjs).
//
// `memory_route` decides where a finding class that recurs across two
// review.md files is proposed as project memory (P5, lib/review/recurrence.mjs):
// 'check' - mechanical: a deterministic check can catch it;
@ -137,9 +144,16 @@ export const RULE_CATALOGUE = Object.freeze([
rule_key: 'SECURITY_REVIEW_VULNERABILITY',
severity: 'BLOCKER',
category: 'security',
description: "A vulnerability reported by Claude Code's /security-review that no narrower rule_key covers.",
description: "A vulnerability reported by a security engine (Claude Code's /security-review) that no narrower rule_key covers. The engines' key only: Voyage's own reviewers use SECURITY_RISK.",
memory_route: null,
}),
Object.freeze({
rule_key: 'SECURITY_RISK',
severity: 'BLOCKER',
category: 'security',
description: "Voyage's own security finding (a concrete attack path, high confidence) that SECURITY_INJECTION does not cover.",
memory_route: 'rule',
}),
// memory_route null: a lesson about the instruction files would feed back into them.
Object.freeze({
rule_key: 'CLAUDE_MD_DEVIATION',