The code-correctness reviewer's dimension 6 shrinks to what the engines do
not read: command, skill and agent markdown carrying shell, with Claude
Code's threshold (a concrete attack path, high confidence), the keys
SECURITY_INJECTION or SECURITY_RISK, and threat_model_ref quoting the
brief's Outside: line; the code-level bullets go to the engines.
The coordinator puts a Voyage security finding with a threat_model_ref
into the trailing JSON block's known_outside, never into findings.
review-finalize gains the pass `outside`, right after engine: it only
raises. An entry the brief at the review's brief_path does not back now
(line gone, threat model not usable, an engine finding, not a security
finding) goes back into the findings at its catalogue tier with a Source
line, R-step and raised verdict, as the engine put-back does; the rest are
listed under the new `## Outside the Threat Model` section.
verdict-gate decideOpenFindings (and so scripts/release-check.mjs)
re-checks every entry against brief_path through the new
notBackedOutside and exits 2 for one not backed. review-validator
shape-checks the optional known_outside (REVIEW_KNOWN_OUTSIDE_MALFORMED).
threat-model.mjs gains reviewThreatModel and isKnownEntry for the three.
/trekreview Phase 8.8 lists the known issues outside the threat model
(not answered, not counted); the review template shows the section and
field; Handover 1 names the optional ## Threat Model and its code,
Handover 6 names known_outside and its code.
Part 2, step 2.5 of the E plan.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
plan-gate.mjs --record --brief <brief.md> (a known flag; its value is kept
out of the positional arguments, a missing value is a usage error) applies
the brief's threat model to the deduped findings before countRound when
threat-model.mjs usable() says it may: a backed finding (Voyage's own
security finding whose threat_model_ref equals an Outside: line's text)
leaves the counted set and the stop rule and goes to the new optional
verdict field known_outside ({id, rule_key, text, line}), carried to later
rounds until a reviewer marks it resolved or it is reported again under its
id. The verdict stores brief_path (carried when a later round has none).
The --record line adds known_outside (a count) and threat_model
({applied, why}): a threat model that is not usable backs nothing, every
security finding counts, and the output says why. extractVerdict
shape-checks both new fields.
The bare gate re-reads the brief at brief_path each run: an entry still
backed is a warning, PLAN_GATE_KNOWN_OUTSIDE; one no longer backed (line
gone, approval stale or not logged, brief unreadable, no brief_path, or not
a Voyage security finding) stops the plan, PLAN_GATE_OUTSIDE_NOT_BACKED: it
counts in full. gatePlan takes an optional threatModel for tests.
plan-review-dedup keeps threat_model_ref on a merge only when every merged
copy carries the same one; the S160 known issue is fixed: a null in a
reviewer's findings list is skipped instead of crashing the CLI.
plan-critic and scope-guardian: a security finding needs a concrete attack
path and high confidence (Claude Code's threshold, 167), uses
SECURITY_INJECTION or SECURITY_RISK, and quotes the Outside: line's text in
threat_model_ref when one applies; the json template carries the field.
/trekplan Phase 9 passes the brief path to plan-critic and --brief to
--record. Handover 4 names the two fields, the two codes and the flag.
Part 2, step 2.4 of the E plan.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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>
New lib/review/threat-model.mjs, the one reader both gates use:
readThreatModel(briefText) -> {present, inside, outside, problems} through
brief-validator's parseThreatModel; usable(briefPath, repo) = present, well
formed, and the intent approval current by the two checks /trekplan Phase 1
runs (checkIntentApprovalContent, then verifyLog kind intent with the
hash's sha256: stripped and the subject normalized), else not usable with
the reason in `why`; backedLine(finding, tm) = the Outside: text the
finding's threat_model_ref equals exactly, else null. Only a security
finding not from an engine can be outside (218): a finding with an
`engine`, or carrying the engines' key SECURITY_REVIEW_VULNERABILITY, is
never backed.
Part 2, step 2.2 of the E plan.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A brief may carry an optional `## Threat Model` with one line per bullet,
`- Inside: <text>` or `- Outside: <text>`. Present and malformed (no such
bullet, another label or form, empty text, two sections) is
BRIEF_THREAT_MODEL_MALFORMED; absent is today's rule. No brief_version bump
(the ceremony / artifact_store precedent). Sections are found fence- and
comment-aware through intent-approval's new sectionTexts, so the validator
and the hash count the same sections; brief-validator exports
parseThreatModel for the reader.
The intent hash covers `## Threat Model` when present (two sections -> null
hash, as Intent and Goal), so an edited, added or removed threat model
makes the approval stale; a brief without one hashes exactly as before. The
stale message and the /trekplan halt table name the section.
/trekbrief offers the section in its question round when the task touches
a guard, a gate, untrusted input, secrets or publishing, writes it only
when given, shows it verbatim at the Phase 4h approval, and --approve reads
it out. The template documents it; brief-gate-coverage pairs the new code.
Part 2, step 2.1 of the E plan.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- plan-gate: the bare gate's stale-verdict reason no longer says "run the
next round" once the stop rule fired; it says there is no next round, as
acceptOpen already does.
- trekplan Phase 9: "REVISE after the last round" (Fix now with
--extra-round) is qualified "and the stop rule did not fire", pinned in
review-loop-docs.test.mjs next to the [STP] pins.
- plan-gate-stop-rule tests: a planted stop-rule acceptance claiming an open
security blocker stays STOP; a planted acceptance without under:
"stop-rule" stays STOP; the "a blocker -> refused" test now asserts the
blocker refusal; --accept-open under the stop rule covers an open MAJOR
and the gate passes with a WARN.
- review-rounds prepare: when the stop rule is judged (P >= 2) and either
round's JSON block cannot be read, exit 2 (not measured) with "stop rule:
a round has no readable JSON block" instead of skipping the rule. The
[RND] differing-archive and [CAP] fixtures now use readable archives; one
new [STP] test covers an unreadable archive and an unreadable review.md.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
/trekplan Phase 9: when --record or the gate reports the stop rule there
is no new round; AskUserQuestion with the class and counts, "Known issue"
(--accept-open, a security finding refused) or "New mechanism" (stop, the
plan stays unapproved); the round-3 blocker path never offers
--extra-round after the stop rule. Phase 10 prints round of
max_rounds + extra_rounds.
/trekexecute Phase 7.2 step 4: after a round-2 BLOCK or fixed-pending,
before any R-step, review-rounds.mjs prepare --dry-run; review-stop-rule:
gives the same question ("Known issue" = /trekreview --answers, a BLOCKER
keeps the merge locked; "New mechanism" = stop). /trekreview Phase 3 tells
the stop rule's exit 1 from the cap's. plan-critic and scope-guardian:
rule_key names the class, never the instance.
New pins in review-loop-docs, critic-severity-rules and review-prose-pins.
Part 1, step 1.4 of the E plan.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
prepare (also --dry-run) judges the previous round's archive and
review.md when it would open round 3: blocking = BLOCKER + counting MAJOR
with the verdict gate's pre-existing reading, new = no carried_from, class
= classOf. Fired -> exit 1, `review-stop-rule: <describeStop line>` and
`stop_rule`, nothing archived. The cap stays. A round with no readable
JSON block gives no summary and the rule is not judged.
countingMajors moves from review-answers.mjs into review-rounds.mjs and is
re-exported by review-answers (as isSecurityFinding is); review-rounds
still imports nothing from review-answers.
Existing test updated for the planned rule: the [CRY] occurrence case adds
a third round-1 MAJOR resolved in round 2, so its round-3 control is not
stopped by "not fewer".
Part 1, step 1.3 of the E plan.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
recordVerdict appends each round's summary to a new optional verdict
field `rounds` (carried from the previous verdict; newByClass null for a
round counted in full) and stores `stop_rule`; extractVerdict shape-checks
both. After a fired stop rule --record exits 1 with PLAN_GATE_STOP_RULE
and writes nothing (--extra-round included). The bare gate stops with
PLAN_GATE_STOP_RULE and the operator line in place of the open-blocker and
open-major reasons; --json and --record output carry the decision.
--accept-open after a fired stop rule is allowed with rounds left, covers
open blockers and majors (`under: "stop-rule"`), refuses a counting
security finding (PLAN_GATE_SECURITY_OPEN); the gate then warns.
Known issue fixed: REVIEW_LOG_SECTIONS drops "Adversarial Pass 2 (v5.1.1
high-effort)"; the CHANGELOG known-issue line closes and Handover 4 names
the heading list, the new fields and codes.
Existing tests updated for the planned rule: fixtures that ran a later
round after one with no fewer blocking findings now use a falling count
(plan-gate.test round cap, plan-gate-open-major lastRound, diff-mode
5/18/27 resolve two earlier majors in round 2); the diff-mode CLI pipe
case now expects PLAN_GATE_STOP_RULE (round 3: 2 blocking) after its
clean round 2.
Part 1, step 1.2 of the E plan.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
New lib/review/stop-rule.mjs: classOf (catalogue key, else the lower-cased
dimension before the first slash, else unclassified), roundSummary
(blocking = blockers + counting majors; new = no carried_from; null map
for a round counted in full), decideStop (same-class / not-fewer on the
last pair, round 1 alone never fires) and describeStop (one operator line
with the class, the counts per round and the two recommendations).
Part 1, step 1.1 of the E plan.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Removes Voyage's own stats/OTel export (R1), STORM and the --engine
research choice (R2), and profiles, phase signals and the effort dialog
(R3), plus the R-a leftovers. One fixed path per command (209).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
/code-review high on main..HEAD: the four commands that parse their own
arguments in prose (/trekbrief, /trekplan, /trekresearch, /trekexecute) lost
their --profile handling, and /trekresearch its --engine, so a typed value
became the path or the question. Each now strips a retired flag with its
value; the arg parser retires --profile only for the commands that had it
(not /trekendsession) and --engine for /trekresearch, seen red first.
Stale lines R-b left: architecture's hook row (9 scripts) and bridge agent,
the gap row's removed event ledger, README's contrarian marker, and a
dangling "also" in /trekexecute Phase 8.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The retired --profile is one list the parser drops (with its value, never
an error) instead of a valued flag in six schemas, so the removed-surfaces
check exempts one parser line, not seven; seen red on the old parser.
The empty OPTIONAL_STRING_KEYS machinery, a one-item loop and an unused
plugin-data dir go; the removed-surfaces check reads each file once; the
Phase 8 slice in executor-prose-pins asserts both anchors.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The /trekresearch Phase 4 sentence said contrarian-researcher runs every
time, also under --local; it now runs whenever the scope includes external.
Three stale "sequencing gate" and stats mentions in touched files follow.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The four profiles, the resolver, the profile validator and docs/profiles.md go;
/trekbrief Phase 3.5 and the brief's phase_signals checks go (an older brief's
key is ignored); MANIFEST_PROFILE_DRIFT and profile_used go. Every Profile,
Composition rule, Sequencing gate and High-effort section leaves the commands.
Decision 209: /trekresearch runs the full swarm with contrarian-researcher as
wave 2 every run; /trekreview and the coordinator run all four passes with no
high-effort normalization. Voyage agents are spawned with no model (their own
model: opus applies); the two built-in spawns pass model "opus". --profile
stays in the parser as a retired flag that swallows its value. §Model & effort
moves to docs/architecture.md; the sequencing-gate eval case goes.
Files removed: 44 (43 from the R3 list + tests/commands/trekreview.test.mjs,
whose every test pinned removed text). Files edited: 43.
Tests: 2467 (2466 pass / 0 fail / 1 skipped) before, 2309 (2309 pass / 0 fail /
0 skipped) after. Durable check: all three groups green, none pending.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
/trekresearch loses Phase 4.5, the bounded Phase 5 loop (Phase 5 keeps its
single pass of at most 2 follow-ups), the --engine flag, the deep-research
adapter and its output self-check. hooks.json loses the pre-agent-cap
PreToolUse entry (README: 9 hooks = 9 scripts). The STORM env vars leave the
docs; query-privacy-gate.mjs stays, called by no command, and says so.
Files removed: 13 (4 docs, 1 hook, 1 lib module, 1 script, 5 tests, 1 fixture).
Files edited: 17. Tests: 2600 (2598 pass / 0 fail / 2 skipped) before,
2467 (2466 pass / 0 fail / 1 skipped, R3 pending) after.
Durable check: group R2 green and no longer pending.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Removes Voyage's measurement, statistics and export apparatus (decision 189;
condition 175 met in step 1) and the R-a leftovers: lib/stats/, lib/exporters/,
the otel-export and post-bash-stats hooks, yardstick, end-state and comparison
gates, synthesis-measure, gold-scorer, docs/observability.md,
examples/observability/, docs/T1-cc26-delegated-orchestration.md and their
tests and fixtures. The six command stats phases and the /trekexecute
main-merge event blocks go; intent-approval --stamp no longer emits
brief-approved. README and docs point to Claude Code's own OpenTelemetry.
Files removed: 52. Files edited: 37.
npm test: 2930 tests (2928 pass / 0 fail / 2 skipped) before, 2600 tests
(2598 pass / 0 fail / 2 skipped) after. removed-surfaces group R1 green.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Seen red with REMOVED_SURFACES_ALL=1 before any removal: R1 546, R2 251,
R3 606 lines. Each stage of R-b empties its own pending group.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The trekcontinue-stats line_ref follows Phase 5 to 271-275 (the Phase 1.5
cut moved it). gold-eval.test.mjs and its run fixture come back: they
are the one end-to-end check that the review contract keeps every
seeded finding, and they stay with the scorer until R-b. CHANGELOG:
the removed validator leaves the known-issues text; the review's other
findings outside R-a's files are listed as known issues.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
engine-compare imports the coordinator's title limit and trim instead
of a copy whose reason went with Arm B; the autonomy gate exports one
parser and its test runs in-process with two CLI runs; one import
scanner in lib-imports; the fenced-section walker shared from
tests/helpers/md-section.mjs instead of six copies; plan-gate hash
in-process; living-paths scans once; routing drops the orchestrator
filter whose files are gone; small leftovers removed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
33 more tests of live behaviour from the deleted round files, each in
the test file named after its source and seen failing under a mutation
of that source (log in the project folder). Two stay dropped: one pinned
the removed gate states, one the old Phase 1.5 file comparison. The two
trekexecute.md sentences that still said /trekcontinue compares the two
prompt files now say it uses the project-folder file (line count kept).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
R4-R7 of the cleanup list (decision 188): the June trial docs and
fixtures, the three orchestrator reference docs, the dormant
synthesis-agent, code with no caller (project-discovery, bash-normalize,
fidelity-diff, test-census, the next-session prompt validator, arm B and
the --workflow flag) and the fix-round chain. Living docs repointed; the
reasons for in-session orchestration and the all-opus pin are now written
in docs/architecture.md and docs/profiles.md.
New tests/lib/living-paths.test.mjs: living tracked text names only
plugin paths that exist (seen red with 22 dead pointers before this
commit). docs/T1-cc26-delegated-orchestration.md and
lib/review/gold-scorer.mjs stay until R-b: the frozen end-state registry
names them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
lib/util/autonomy-gate.mjs keeps only gatesValue + parseGatesArgs and the
CLI ({"ok":true,"gates":true|false}; exact usage error on a bad value;
the old --state/--event arguments are a usage error). The four commands
run 'autonomy-gate.mjs --gates [value]' and read gates. Prose (README,
operations, architecture, sdlc-playbook-gap) and the S24, gates-flag
and [#1] tests follow (R9).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
R8 of cleanup R-a (plan .claude/projects/2026-11-07-cleanup-r-a, appendix A).
The live tests of the round files move into the test named after their
source; each moved test was seen red under a mutation of its source.
New: tests/lib/lib-imports.test.mjs, tests/lib/timing.test.mjs (from
timing-under-load). The [#1] --gates rule and shim-line pins move into
tests/lib/autonomy-gate.test.mjs.
Removed: the round test files (retterunde, retterunde-prose-pins,
trial-mechanical-fixes, trial2-fixes, trial2-minor, trial2-minor-prose-pins,
fix-round-4-5a-prose, fix-round-4-5b2-b-prose, timing-under-load), the 8 R8
e2e scripts, and seven round test files on the R-a removal list that pinned
them (fix-round-4-5b-prose, fix-round-4-5b-part-2/3/4-scripts,
fix-round-4-5b-part-4-prose, fix-round-4-5b2-b/c-scripts). The diff-mode e2e
pin (test 24) and the red-script round-wrapper cases go too.
tests/synthetic/plan-run-C.md becomes tests/fixtures/plan-run-c.md,
regenerated from buildPlan({ version: '1.9' }). The red judge, reporter and
judge test headers now name the shared red script.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>