Commit graph

244 commits

Author SHA1 Message Date
5cb2918baa
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>
2026-11-08 08:55:34 +01:00
bec4500b8f
feat(review): one reader of the brief's threat model (decision 164, 218)
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>
2026-11-08 08:51:04 +01:00
74f75dcb7d
feat(brief): optional threat model in the brief (decision 164, 218)
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>
2026-11-08 08:47:51 +01:00
07a3c06c57
fix(gate): part 1 verifier findings — stop-rule wording, guard tests, unreadable round
- 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>
2026-11-08 07:39:00 +01:00
6b44be4c43
feat(review): stop rule in the review rounds (decision 217, 220)
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>
2026-11-08 07:13:07 +01:00
a576391e28
feat(gate): stop rule in the plan gate (decision 217, 220)
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>
2026-11-08 07:04:48 +01:00
7e09edb24f
feat(review): one shared stop rule for the plan loop and review rounds (decision 217)
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>
2026-11-08 06:58:45 +01:00
b70c37f0e7
fix(cleanup): R-b review round — retired flags in the prose parsers
/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>
2026-11-07 21:36:13 +01:00
fdb401d0ab
refactor(cleanup): simplify pass on R-b
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>
2026-11-07 21:26:25 +01:00
2a35d067d9
chore(cleanup): R-b R3 — profiles, phase signals and the effort dialog removed, one fixed path per command
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>
2026-11-07 21:12:57 +01:00
32621dcb63
chore(cleanup): R-b R2 — STORM loop, cap hook and the --engine research choice removed
/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>
2026-11-07 20:32:38 +01:00
21480e8627
chore(cleanup): R-b R1 — Voyage's own stats, events and OTel export removed
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>
2026-11-07 20:11:00 +01:00
efe981f7bc
refactor(cleanup): simplify pass on the R-a diff
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>
2026-11-07 13:31:30 +01:00
8295601965
chore(cleanup): remove the June trials, orchestrator docs, dormant agent, caller-less code and the fix-round chain
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>
2026-11-07 12:51:54 +01:00
308b149e70
refactor(gates): the autonomy gate is the --gates flag parser
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>
2026-11-07 10:37:03 +01:00
9edc998fac
refactor: simplify pass (trekexecute)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 11:29:46 +01:00
5b9cbeba28
fix(review): the evidence writer takes a verdict only for the branch head
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 10:27:19 +01:00
d4daa9d787
fix(review): the instruction set holds nested rules files and a link's own name
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 10:16:34 +01:00
d81bd39754
fix(review): an answer after a stopped prepare no longer locks the rounds
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 10:05:04 +01:00
fc252f8d56
fix(review): the verdict gate refuses duplicate finding ids
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 09:40:25 +01:00
f1f5ab5528
refactor: simplify pass (trekexecute)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 12:48:04 +01:00
3cb3958238
fix(review): a dropped engine finding keeps the gate not measured, round 1 included
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 11:57:30 +01:00
a09e6c96a1
fix(review): scope_sha_start is bound to the fork point from main
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 11:23:21 +01:00
57e7eba0a0
fix(review): R6 checks every parent of a commit after the review
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 11:07:08 +01:00
ec5b6483ec
feat(hooks): the merge question says how the run was tested and how it is undone 2026-11-02 21:23:24 +01:00
fcba232ccd
feat(review): the code-correctness reviewer checks the repo's tracked instruction files 2026-11-02 20:47:15 +01:00
349a4fc789
feat(review): the standard path puts back engine findings the coordinator dropped 2026-11-02 20:12:46 +01:00
8d399fddfb
feat(review): a REVIEW.md policy caps and skips MINOR findings only 2026-11-02 19:43:54 +01:00
9e7e8d1516
feat(trekexecute): every MAJOR answered before merge, fixed runs the fix loop 2026-11-02 18:44:42 +01:00
635003e8aa
feat(review): review rounds carry findings until resolved, one cap of three 2026-11-02 17:44:23 +01:00
1464605e35
feat(review): pre-existing findings marked from git and re-derived by the gate 2026-11-02 16:37:24 +01:00
ce7dbc27a9
feat(review): a WARN opens the lock only when every counting MAJOR is answered 2026-11-02 15:45:37 +01:00
ce64851a0d
fix(review): an append of review answers to the approval log keeps the review current 2026-11-02 15:01:58 +01:00
5709957e10
feat(review): review_version 1.2 with answers, pre-existing, rounds and policy fields 2026-11-02 14:22:35 +01:00
ed67526987
feat(review): two CLAUDE.md rule keys at MINOR, the catalogue counts 17 2026-11-02 13:53:24 +01:00
8c52c3c32e
fix(arg-parser): a quoted value closes at a quote that ends a word, also after whitespace
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 22:34:38 +01:00
c75ae2d3f5
refactor: simplify pass (trekexecute)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 16:34:32 +01:00
1b9d5fd459
fix(review): a failed git check-ignore writes no pointer, whatever language git speaks
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 15:46:43 +01:00
8be0c05221
fix(arg-parser): a quoted value stops at a quote that starts a word and never swallows a later flag
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 15:18:55 +01:00
52c382c198
refactor: simplify pass (trekexecute)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 20:39:40 +01:00
c7fdbf0d8b
fix(review): applying a lesson skips a symlinked CLAUDE.md and an ignored lessons file
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 17:27:33 +01:00
f1704f0800
fix(arg-parser): take the arguments as stdin text, and block a heredoc that closes early
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 15:40:21 +01:00
afe56899a9
fix(park): park from a CRLF diff and say that a staged new file is parked
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 14:44:33 +01:00
bf4736a254
fix(park): read HEAD membership once and move nothing when it cannot be read
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 14:36:03 +01:00
5ddbcd3de6
fix(verdict-gate): free text added inside the lessons block makes the review stale
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 14:11:41 +01:00
77544841d7
fix(verdict-gate): a failed git call is reported as not measured, not stale
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 14:00:42 +01:00
703c508433
fix(verdict-gate): read --repo=<dir> and refuse unknown options
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 13:44:11 +01:00
e279f12131
fix(verification): the done line and the release check take only full commit ids
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 13:33:51 +01:00
cf7af30b46
fix(verdict-gate): accept only a full 40- or 64-hex reviewed commit
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 13:13:22 +01:00
af90e82794
refactor: simplify pass (trekexecute)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 22:22:18 +02:00