docs(changelog): plan_version 1.9 and the trial-4 findings, with door lines
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
acd0e3dd47
commit
acfd2eb9b6
2 changed files with 136 additions and 0 deletions
89
CHANGELOG.md
89
CHANGELOG.md
|
|
@ -4,6 +4,95 @@ All notable changes to this project will be documented in this file.
|
|||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
||||
|
||||
## Unreleased — plan_version 1.9, the trial-4 findings, session-clean tests
|
||||
|
||||
A 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 stops `npm test` from 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 2381 (2379 pass, 0 fail, 2 skipped),
|
||||
measured by `npm test` on Step 13's commit (`acd0e3d`), the commit before this
|
||||
section.
|
||||
|
||||
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 whose `Files:` 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: every test file on the Test first File line — a revert reads the first file only again.
|
||||
- two-way: brief-conflict mark on review findings — an older verdict gate ignores the field.
|
||||
- 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.
|
||||
|
||||
### Added
|
||||
|
||||
- **plan_version 1.9: the file first on every line.** Each entry of `Files:`
|
||||
and each `Test 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 gets `PLAN_STEP_PATH_NOT_FIRST` or
|
||||
`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 warning `PLAN_STEP_PATH_UNTICKED`, under `--strict` too.
|
||||
- **The brief-conflict mark.** A `/code-review` finding at the MAJOR tier whose
|
||||
recommended action goes against a brief Non-Goal or another stated choice
|
||||
drops to MINOR, marked `contradicts_brief` and `brief_lowered_from: MAJOR`;
|
||||
any other engine finding only gets the mark, and a BLOCKER is never lowered.
|
||||
`/trekreview` passes the brief's choices to the coordinator, which writes the
|
||||
mark into `review.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_from` on 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.
|
||||
|
||||
### Fixed
|
||||
|
||||
- **The suite no longer hands the session id to the lock CLI.** `npm test`
|
||||
preloads a helper that removes `CLAUDE_CODE_SESSION_ID`, and every test that
|
||||
starts a child process passes an environment without it. A live session's
|
||||
stop guard is no longer pointed at a temp-repo lock.
|
||||
- **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 as `LICENSE` alone on a following line is read as a file.
|
||||
- **Every test file on the `Test first:` `File:` line** is read, locked and
|
||||
copied for red proof, not only the first.
|
||||
- **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 `engine` from the payload,
|
||||
never from a field a reviewer wrote on its own finding, and on a severity tie
|
||||
the reviewer-agent finding is kept over the engine finding, 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).
|
||||
- **Explorers and reviewers stay in the repo.** `/trekplan` tells 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 `/trekplan` reviews the brief once more.
|
||||
- **Approval commits carry the caller's Co-Authored-By trailer.**
|
||||
`artifact-commit.mjs` takes `--trailer` and 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`, `/trekplan` and `/trekexecute`
|
||||
pass it; `/trekexecute` prints the reason and goes on when the approval is
|
||||
logged but not committed.
|
||||
|
||||
### 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.
|
||||
|
||||
## v6.3.1 — 2026-10-11 — Fixes from the release review of 6.3.0, and two verdict-gate holes closed
|
||||
|
||||
Rounds 7 to 10 of the release review of 6.3.0. Round 7 is the WARN 6.3.0 was
|
||||
|
|
|
|||
|
|
@ -139,3 +139,50 @@ test('the template\'s own example steps validate as 1.9 with none of the new pat
|
|||
const soft = validatePlanContent(read('templates/plan-template.md'), { strict: false });
|
||||
assert.deepEqual([...soft.errors, ...soft.warnings].map((i) => i.code).filter((c) => NEW_CODES.includes(c)), []);
|
||||
});
|
||||
|
||||
// Step 14: the CHANGELOG's top section is the Unreleased 1.9 delivery, with door
|
||||
// lines the release check accepts. The release check is imported as a module
|
||||
// namespace, so a missing parseDoors export fails an assertion, not the load.
|
||||
const releaseCheck = await import('../../scripts/release-check.mjs');
|
||||
const UNRELEASED = '## Unreleased — plan_version 1.9, the trial-4 findings, session-clean tests';
|
||||
|
||||
function firstChangelogSection() {
|
||||
const lines = read('CHANGELOG.md').split('\n');
|
||||
const start = lines.findIndex((l) => /^## /.test(l));
|
||||
assert.ok(start >= 0, 'CHANGELOG.md has no "## " section');
|
||||
let end = lines.length;
|
||||
for (let i = start + 1; i < lines.length; i++) {
|
||||
if (/^## /.test(lines[i])) { end = i; break; }
|
||||
}
|
||||
return { heading: lines[start], body: lines.slice(start + 1, end).join('\n') };
|
||||
}
|
||||
|
||||
test('CHANGELOG: the first "## " section is the Unreleased plan_version 1.9 section', () => {
|
||||
assert.equal(firstChangelogSection().heading, UNRELEASED);
|
||||
});
|
||||
|
||||
test('CHANGELOG: parseDoors reads the Unreleased section\'s door lines, none bad, one naming plan_version 1.9', () => {
|
||||
assert.equal(typeof releaseCheck.parseDoors, 'function', 'scripts/release-check.mjs exports parseDoors');
|
||||
const { heading, body } = firstChangelogSection();
|
||||
assert.equal(heading, UNRELEASED);
|
||||
const d = releaseCheck.parseDoors(body);
|
||||
assert.equal(d.found, true, 'the Unreleased section has a "### Doors" heading');
|
||||
assert.ok(d.entries.length > 0, 'the Doors list has door lines');
|
||||
assert.deepEqual(d.bad, [], 'every top-level door line reads "- one-way: ..." or "- two-way: ..."');
|
||||
assert.ok(d.entries.some((e) => e.text.includes('plan_version 1.9')),
|
||||
`one door line names plan_version 1.9: ${JSON.stringify(d.entries.map((e) => e.text))}`);
|
||||
});
|
||||
|
||||
test('CHANGELOG: the Unreleased section\'s Known issues name the session split', () => {
|
||||
const { heading, body } = firstChangelogSection();
|
||||
assert.equal(heading, UNRELEASED);
|
||||
const lines = body.split('\n');
|
||||
const start = lines.findIndex((l) => /^### Known issues\s*$/.test(l));
|
||||
assert.ok(start >= 0, 'the Unreleased section has a "### Known issues" heading');
|
||||
let end = lines.length;
|
||||
for (let i = start + 1; i < lines.length; i++) {
|
||||
if (/^###? /.test(lines[i])) { end = i; break; }
|
||||
}
|
||||
const known = lines.slice(start + 1, end).join('\n');
|
||||
assert.match(known, /session split/, `Known issues name the session split: ${JSON.stringify(known)}`);
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue