-
v6.4.0 Stable
released this
2026-10-16 22:25:08 +00:00 | 85 commits to main since this releaseA new plan version, 1.9, in which every path in a step's
Files:and on its
Test first:File:line stands first, in backticks, so the reader no longer
guesses paths from prose (decision 16). The same delivery closes the six
findings from the test repo's trial 4 and stopsnpm testfrom pointing a live
session's stop guard at a temp-repo lock. Every fix began with a test that
failed on the code before it. Suite 2517 (2515 pass, 0 fail, 2 skipped),
measured bynpm teston the third remediation's Step 2 commit
(829da48), the commit before this section.The converging critic loop came after that measurement (decisions 43 and
44). From round 2 the plan gate counts a critic round by rule A, and both
reviewers state rule B. Suite 2602 (2600 pass, 0 fail, 2 skipped), measured
bynpm testonmainat4e28dc5, the tree this release review covered.Nothing here asks anything of users. Older plans warn, they do not fail: a plan
below 1.9 is read as in 6.3.1, apart from the fixes under Fixed, and gets one
warning per step whoseFiles:names a path that is not backticked.Doors
- two-way: plan_version 1.9 — a 1.9 plan read by 6.3.1 gets PLAN_VERSION_MISMATCH as a warning and the 6.3.1 reader, so a revert rewrites no plan.
- two-way: Files reader (three 6.3.0 answers restored) — a revert brings back 6.3.1's answers; no file format changes.
- two-way: the test files on the Test first File line are the backticked paths right after File: (operator decision 20) — a revert reads every path-shaped span again.
- two-way: red proof checks --tests against the plan — a revert accepts any list again.
- two-way: brief-conflict mark on review findings — an older verdict gate ignores the field.
- two-way: review Pass 1 ranks by catalogue tier and a dropped duplicate never lowers its group — a revert restores the asserted-severity ranking.
- two-way: the workflow review puts back every engine finding the coordinator did not return (operator decision 23) — opt-in path only; a revert restores the old floor.
- two-way: approval commits require a Co-Authored-By trailer — only Voyage's own commands call the CLI, and they pass it.
- two-way: explorer prompts, stamp order, test env — prose and test-side only.
- two-way: a 1.9 wrapped line keeps its paths only after a comma (operator decision 29), and a File: line with nothing after it takes its first wrapped line — a revert joins every wrapped line again.
- two-way: below 1.9 a test file after a note in brackets, and, plus or + is read when it is clearly a test (operator decision 28 and operator decision 31) — a revert reads only the run right after File: again.
- two-way: red proof reads the step's test files from the plan, prints them, and refuses a plan it cannot read (operator decision 30) — the older prose that passes --tests still runs against it.
- two-way: original_severity names what the kept finding asserted — only tests read the field.
- two-way: the workflow review fails closed when its coordinator returns nothing, and names every reviewer that did not run in allow_blocked_by — opt-in path only.
- two-way: below 1.8, when the plan names no test file, the helper and the executor give red proof the files the helper wrote (operator decision 41) — a revert leaves such a step unproven and unlocked.
- two-way: rule A in the plan gate (decision 43) — an older gate ignores the new verdict fields, and a revert counts every round fully.
- two-way: rule B and the security key in the reviewers (decision 43) — prose only; a revert restores the old rating.
- two-way: plan dedup passes the reviewers' marks and rule-B fields through, and its two fixes — a revert drops the fields and brings back the line-0 collapse and the crash.
- two-way: the post-compact hook test's timeout (decision 44) — test-side only.
- two-way: the critic-loop matcher needs overlapping texts, and a new finding never takes an old id (operator decision 48) — a revert matches by id or line alone again.
- two-way: plan dedup keeps a lowered_from that is not a severity (operator decision 48) — a revert counts it as no lowering again.
- two-way: plan dedup ranks a merged pair by what rule B counts (operator decision 48) — a revert brings back the order-dependent merge.
Added
- plan_version 1.9: the file first on every line. Each entry of
Files:
and eachTest first:File:line opens with its backticked path or paths;
everything from the first other text on is description and is never read.
A 1.9 plan that breaks this getsPLAN_STEP_PATH_NOT_FIRSTor
PLAN_STEP_PATH_NOT_A_PATH(errors under--strict, warnings without). The
parser, the validator, the tests-only check, the plan-file sweep (K6) and red
proof read a 1.9 plan by this grammar. 1.9 is the current target: Handover
4, the plan template,/trekplan, the planning orchestrator and CLAUDE.md
say so, and the rules introduced at 1.8 say "1.8 or later". - A warning for older plans. Below 1.9, a path in
Files:that is not
backticked gets the warningPLAN_STEP_PATH_UNTICKED, under--stricttoo. - The brief-conflict mark. A
/code-reviewfinding at the MAJOR tier whose
recommended action goes against a brief Non-Goal or another stated choice
drops to MINOR, markedcontradicts_briefandbrief_lowered_from: MAJOR;
any other engine finding only gets the mark, and a BLOCKER is never lowered.
/trekreviewpasses the brief's choices to the coordinator, which writes the
mark intoreview.md; the opt-in workflow review applies the same rule and
floors an illegal lowering. On an ALLOW or WARN review the verdict gate
answers exit 2 for a finding lowered or marked outside that one shape:
brief_lowered_fromon any other finding, a mark on a reviewer finding, a
mark or an engine finding below its catalogue tier, or a mark with a missing
or unknown rule key. - The critic loop converges by rule A, counted by the plan gate
(decision 43). Round 1 is unchanged. From round 2 on,
plan-gate.mjs --diffprints what changed since the text the last round
reviewed. Both reviewers get it and mark each previous finding by id. Then
--recordcounts the round: a new major that cites a plan line outside
that diff counts as minor. A blocker, a security finding and a finding
with no plan line count at full severity. A previous finding stays counted
until it is marked resolved. The gate keeps each recorded round's text in
the git directory, so a snapshot is never committed. A plan outside any git
repository keeps none, and its next round counts fully. Every new verdict
field is optional, and absent means round-1 behaviour, so an older verdict
block gives the same exit codes. Phase 9, Handover 4, the planning
orchestrator, CLAUDE.md and the README say so. - Rule B in both reviewers (decision 43). plan-critic and scope-guardian
state it: a major that a named test,Regression:command or gate in the
plan will fail on during execution is minor, never a blocker and never a
security finding. The gate records each such lowering from round 1 on.
Plan dedup passes the reviewers' marks and rule-B fields through. The
operator answered three questions on 2026-10-15: rule B applies from round
1 and rule A from round 2; both reviewers tag a security finding with the
review catalogue's security key; a lowered finding that is re-reported as
major stays minor, and only a re-report as blocker counts as blocker.
Fixed
- The suite no longer hands the session id to the lock CLI.
npm test
preloads a helper that removesCLAUDE_CODE_SESSION_IDfor the whole run,
and every test that spreads the process environment into a child uses a
shared helper without it. A live session's stop guard is no longer pointed
at a temp-repo lock. A test file run on its own withnode --teststill
passes the id to a child it starts without anenv(release review). - The three
Files:regressions from 6.3.1's Known issues give 6.3.0's
answer again: a source file after a described test is kept, a path that a
description only mentions is not read as a file, and a backticked bare name
such asLICENSEalone on a following line is read as a file. - The test files on the
Test first:File:line are the backticked
paths that stand right afterFile:, separated only by commas or spaces,
and below plan_version 1.9 also each further path after a note in brackets
((new),*(new)*,(existing …)) or afterand,plusor+, as long
as it is clearly a test (operator decision 28, 13.10, and
operator decision 31, 14.10; reviewbd2520b0). Every one of them is read,
locked and copied for red proof, not only the first. A path in the
description after them is no test file, at every plan_version
(operator decision 20, 12.10; review6c31212c), so a step whoseFile:
line names its source in the description is no longer read as tests-only. - A 1.9
Test first:names its test only on a line that opens with
File:, the way the executor, K6 and red proof read it. Below 1.9 the
check reads as before. - Engine provenance in the review. Ingest takes
enginefrom the payload,
never from a field a reviewer wrote on its own finding, and dedup ranks by
catalogue tier, so a reviewer-agent finding is kept over an engine finding,
and the kept finding carries the group's highest severity, in the
coordinator's Pass 1 and in the workflow dedup. A brief-conflict mark can no
longer lower a reviewer's MAJOR (operator decision 2026-10-12). On the
workflow path, floor (b) and the put-back of every engine finding the
coordinator did not return (both below) hold the same line after the
coordinator answers. - Explorers and reviewers stay in the repo.
/trekplantells its
brief-reviewer, the eight Phase 5 explorers, the Phase 6 deep-dives, the
plan-critic and the scope-guardian to read local files only inside the repo
under exploration plus the paths their prompt gives, and every explorer gets
the brief. - The brief review stamp covers only text the reviewer saw. For a
small
brief, the reviewer's gaps are written after the stamp, so the stamp reads
stale and/trekplanreviews the brief once more. - Approval commits carry the caller's Co-Authored-By trailer.
artifact-commit.mjstakes--trailerand refuses (exit 1, before anything
is staged or committed) a missing, multi-line or malformed trailer, an unfilled{model}, and
one that names a session link./trekbrief,/trekplanand/trekexecute
pass it;/trekexecuteprints the reason and goes on when the approval is
logged but not committed. - A list joiner no longer ends the read of a plain path below 1.9. In
Files:, a+,&,andororbetween backticked paths is no word of
description, so a plain path after them is read as a file again, as 6.3.1
read it, and a step of two tests joined by+and a plain source is not
tests-only (review182ceb93). - A 1.9 entry keeps the paths of a line wrapped after a comma, and a
numberedFile:line names its test. A line that is no list item keeps
its paths only after a comma, when the entry so far ends with one
(operator decision 29, 14.10; reviewsd21ff81e,eaeb398e), so a
Files:list wrapped after a comma names every file: the step is not
tests-only, and K6 plans the second file too. Otherwise that line, and
every later wrapped line of the entry, is description and never read. A
File:line with nothing after it takes its first wrapped line. The
Test first:File:line may open with-,*,+,1.or1), and
any list item ends it (reviewsb4fa1927,4b6460e5). - A 1.9 plan refuses placeholders and mixed-case bare names as files
(operator decision 22, 13.10; review33f37f53). A leading backticked span
that is a placeholder (none,TBD,TODO,TBA,N/A,NA,..., in
any case) or a bare name that is neither in capitals nor a build file, such
as the mixed-caseParser, isPLAN_STEP_PATH_NOT_A_PATH, and its hint
says to write./Namefor such a file.LICENSE,READMEandMakefile
stay files; below 1.9 nothing changes. - The engine of a payload is read from an own property. Ingest no longer
gives the findings of a payload whose reviewer is namedtoString,
constructor,__proto__or another nameObject.prototypecarries an
engine(it gave them a function or an object), andtoReviewerPayload
refuses an engine namedtoStringwith its "engine must be one of" error
(review3799ea6c). - Pass 1 ranks by catalogue tier, and a duplicate never lowers its group.
Of findings with the same(file, line, rule_key), the coordinator's Pass 1
anddedupByTripletkeep the one with the higher catalogue tier, then a
reviewer-agent finding over an engine finding, then the higher asserted
severity, then thebrief-conformance-reviewerfinding, then the first
seen, and write the kept finding at the highest severity its group asserted.
Before, a marked code-review MAJOR beat a reviewer's MINOR on the same
triplet and the review came out ALLOW; now it is WARN (reviewbc7f4e23;
the coordinator's prose, operator decision 24). - The workflow review puts back every engine finding the coordinator did not
return (operator decision 23, 13.10; reviewsab1b5d9f,bc7f4e23). On
the opt-in workflow path, dedup ranks as Pass 1 does, and every engine
finding with no returned finding at its exact(file, line, rule_key)is
put back at its own severity, one per triplet (the higher-severity copy when
two share it), so dropping, moving or relabelling an engine finding no
longer lowers the verdict. Beside it, floor (b): a returned finding is never
below the lower of its reviewer counterpart's severity and its catalogue
tier (for a key outside the catalogue, the counterpart's severity). The
workflow path is now stricter than the default path (see Known issues). - An approval trailer with a blank or padded name is refused.
artifact-commit.mjsrefuses a trailer whose name is empty or only spaces,
or that holds two spaces in a row, so an empty{model}("Claude" and two
spaces) fails as the module header promises. A name with a parenthesis,
such as "Claude Opus 5.5 (1M context)", is still accepted (review
8420915b). - The plan validator parses each step once.
validatePlanContentreads a
step's fields once and every check,--steps-fromincluded, reads them from
there; its errors and warnings are unchanged (review93382464). - Red proof reads the step's test files from the plan and prints them, and
the executor defines them once (reviewcf241526;
operator decision 30, 14.10; reviews793fc1aa,09ae46d8,d01df508,
11ee78c5). With--planand--step,red-proof.mjsreads the step's
test files from the plan as decision 20 and, below 1.9, decision 31 set
them, and prints the list it ran astests(atests:line in text mode).
The helper and the executor pass no--tests, and the lock's--filesis
that printed list. A--teststhat names another set is exit 2 with a
reason that startstests-mismatchand the plan's list inplan_tests; a
plan or step it cannot read is exit 2 with a reason that starts
plan-unreadable, and the executor corrects its own call; a step whose
plan names no test file reads as before.commands/trekexecute.mddefines
the step's test files in one sentence the other places point to. - The
/trekbriefpass branch names no## Brief Quality, and the stats
rows span their blocks (operator decision 21, 12.10). That section belongs
to the exhausted and force-stopped branches only. In
tests/fixtures/jsonl-schemas.mdtheline_refof the trekbrief, trekplan
and trekreview stats rows runs from the phase heading to the closing fence of
its stats-append block, and a test pins all four command rows (trekexecute's
too) by exact equality. original_severitynames what the kept finding asserted (review
08deae68). When Pass 1 raises a finding to its duplicate group's
severity, Pass 3 writesoriginal_severityfrom the finding's own
severity, and only when that differs from its catalogue tier; the carrier
fieldpass1_raised_fromnever leaves the contract.- The workflow review fails closed when its coordinator returns nothing
(reviewedf2ec56). A coordinator that returns no verdict and findings
counts as a missing reviewer: the merged findings are read at their
catalogue tier or higher (never lowered), the verdict starts at WARN (a
BLOCK stays BLOCK), and every reviewer, engine and coordinator that did not
deliver is named inallow_blocked_byasmissing-reviewer:<name>, so the
verdict gate exits 2 on such a WARN. - K6 keeps its own normaliser and
LIST_ITEMis one literal again
(operator decision 27, 13.10; review7961a700). The two/simplifyedits
that crossed the first remediation's fence around K6 are reverted. - The control-run test leaves headroom over a slow start (review
703d87e1). Under full-suite load the start-point run of red proof's
control-run test was killed at its 2 s timeout. The test now gives red proof
a 15 s timeout and starts every run but the control slowly on purpose, so a
timeout without headroom fails on demand; the numbers live in
tests/helpers/timing.mjs. - Below 1.8 a plan that names no test file gets the files the helper
wrote (review7b3b59ed; operator decision 41, 14.10). AFile:line
below 1.8 may name its test without backticks, so red proof reads no test
file from the plan and answersno test files given. The helper then runs
the same red proof again with--testsnaming the files it wrote, and the
executor gives red proof that same list, so such a step is proven and locked. - The post-compact hook test survives a slow start (decision 44). Its
hook child had a fixed 5 s timeout and was killed under full-suite load.
The timeout now comes fromtests/helpers/timing.mjs, and a killed hook
child reads as a failure instead of exit 0. - Plan dedup keeps distinct file-level findings apart, and no longer
crashes on a bad field (decision 43). Findings of one rule key on line 0
or with no line no longer collapse into one. An emptyfileor aline
that is not a whole number no longer crashes the finding id; the line
becomes null and the finding stands. - The critic loop no longer folds a new finding into an old one by its id
or line alone (reviews4ab24b07,d03835c4; operator decision 48,
16.10).- What happened: an equal id or the old finding's line was enough. The new
text was lost, and a new file-level major could count as an old rule-B
minor. - Now the texts must overlap, a finding with a plan line is never matched
by id, and a new finding never takes an old finding's id.
- What happened: an equal id or the old finding's line was enough. The new
- A
lowered_fromthat is not a severity now counts as blocker (reviews
8782602b,ebe164e2; operator decision 48, 16.10). It was read as no
lowering. A blank one is still no lowering. - Plan dedup no longer lets reviewer order lower a blocker (review
69c9cebd; operator decision 48, 16.10).- A merge keeps the copy rule B counts highest, on the merged keys.
- This also covers a blocker claim merged into a plain major, found during
this round.
Known issues
- The session split reads a 1.9 plan as an older plan (operator answer 3).
- Marked MINOR findings still feed
recurrence/ project-memory proposals. - The default review path's verdict gate does not compare
review.mdwith the
engine payloads, so only the opt-in workflow path puts an engine finding the
coordinator did not return back (operator decision 23). The operator made
that check a separate delivery later (operator decision 25, 13.10). - Below 1.9 the plan-file sweep (K6) keeps its own wider reader of the
File:
line (operator 2026-10-11): it plans every backticked path on that line, also
one in the description that decision 20 no longer counts as a test file. - Red proof accepts a
--teststhat matches the plan's list and prints it in
the spelling it was given, not the plan's (review2d624b54; deferred by
operator decision 42, 14.10). ingestkeeps apass1_raised_fromand anoriginal_severitythat a
payload wrote on its own finding (reviewsc06d5385,e031a480; deferred
by operator decision 42, 14.10).- When its coordinator returns nothing, the workflow review raises the merged
findings in place; this has no effect on its output today (review
6ff82e75; deferred by operator decision 42, 14.10). - A whitespace-only line ends a 1.9
Test first:File:entry but not a
Files:entry, to be skipped in both by operator decision 40 (review
4b6460e5; deferred by operator decision 42, 14.10). The same id stands
in a Fixed bullet above, which fixed the list-item case of that review; the
whitespace-only case came back open. - A 1.9 wrapped line read as description is dropped without a warning, even
when it opens with a backticked path, to be warned on by
operator decision 39 (review4e1607cb; deferred by
operator decision 42, 14.10). - Handover 4's
Files:bullet words its empty-entry rule as for aFile:
line (review4f22b101; deferred by operator decision 42, 14.10). - Accepted deviation: the 1.9
File:selector repeats the list-marker set of
LIST_ITEM(review4dce7c74; operator decision 38, 14.10, decision 27
stands). - The line diff's LCS table has no size bound. A rewritten gap of tens of
thousands of lines takes seconds to minutes and gigabytes, and can end
outside exit 0/1/2. Real plans measure about 1,200 lines (review
8a9b5a17; deferred by operator decision 48, 16.10). - A previous finding re-reported on its own edited line is counted twice.
Such a re-report of a lowered finding counts at its full severity (review
8004ea85; deferred by operator decision 48, 16.10). - A
linesent as a numeric string ("42") is read as no line and counted
at full severity. The agent templates givelineas a number (review
c257625e; deferred by operator decision 48, 16.10). npm testdoes not runtests/e2e-critic-diff-mode.sh. It runs under
## Verificationand in/trekreview's success-criteria check (review
818b1346; deferred by operator decision 48, 16.10).- The matcher's residual (review
4ab24b07; operator decision 50, 16.10): a
previous finding marked resolved by every raiser and re-reported in other
words (content overlap below 0.7) on an unchanged line is a new finding,
which rule A can lower to minor. The same holds for a re-report in the same
short words (fewer than 6 content words) away from the previous finding's
place. - A short new finding at a previous finding's place is matched to it when
all its content words appear in the old text: the overlap is measured
against the shorter text, and the place clause has no word floor. The new
text is lost, and the old finding's severity is counted, a rule-B minor
included (reviewea8c1752; deferred by operator decision 51, 16.10). - In a merge of three or more copies, a copy's rule-B claim that ties on the
keys merged so far is dropped. When the security key arrives with a later
copy, reviewer order still decides between minor and major (reviews
436ade33,f9ba85e1; deferred by operator decision 51, 16.10). - A
lowered_fromsuch as"none","n/a",falseor0counts as
blocker, by design (fail-closed). A reviewer that writes one on a finding
it did not lower turns a minor into a BLOCK (review79d1dc97; deferred by
operator decision 51, 16.10). - The rule that a blank
lowered_fromis no lowering lives only in plan
dedup. A--recordinput that bypasses dedup withlowered_from: ""counts
as blocker (review2e7afd61; deferred by operator decision 51, 16.10). - When the plan has not changed since the previous round, the gate counts
the round fully, and a previous finding that no reviewer reports again
leaves the count without being marked resolved. This predates the critic
loop's diff mode (review4c340d4a; deferred by operator decision 51,
16.10). - A near-duplicate merge in plan dedup keeps only the survivor's place, so
rule A can lower a new major in the changed text to minor when its partner
cites an unchanged line, and the round can record PASS. 6.3.1 counted that
merge major (reviewef1633b6; deferred by operator decision 52, 16.10). - Below 1.9, regression A's restored reading also takes a plain slash path
that a description only mentions after a comma (`tests/a.test.mjs` — covers the parser, lib/parse.mjs stays as is). 6.3.1 read only the test
file; now the step is no longer tests-only, and the validator warns
PLAN_STEP_PATH_UNTICKEDon the mentioned path (review38a8ad34;
deferred by operator decision 52, 16.10). - The verdict gate's brief-lowering check compares severities in upper case
only, so an engine finding written"severity": "major"reads as an
illegal lowering and the gate exits 2 (fail-closed) (review20b626e2;
deferred by operator decision 52, 16.10). - The opt-in workflow review's floor raises an illegally lowered or marked
reviewer finding but keeps itsbrief_lowered_fromandcontradicts_brief,
so the verdict gate still exits 2 on that review (fail-closed) (review
c614baad; deferred by operator decision 52, 16.10).
Downloads
-
Source code (ZIP)
1 download
-
Source code (TAR.GZ)
1 download