voyage/tests/commands/trekbrief.test.mjs
Kjell Tore Guttormsen 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

80 lines
3.7 KiB
JavaScript

// tests/commands/trekbrief.test.mjs
// Pattern D prose-pins kept as doc-anchors for commands/trekbrief.md.
import { test } from 'node:test';
import { strict as assert } from 'node:assert';
import { readFileSync } from 'node:fs';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
const HERE = dirname(fileURLToPath(import.meta.url));
const ROOT = join(HERE, '..', '..');
const COMMAND_FILE = join(ROOT, 'commands', 'trekbrief.md');
const REVIEWER_FILE = join(ROOT, 'agents', 'brief-reviewer.md');
const TEMPLATE_FILE = join(ROOT, 'templates', 'trekbrief-template.md');
function read() {
return readFileSync(COMMAND_FILE, 'utf8');
}
// --- v5.5 — framing enforcement + TL;DR + memory-alignment prose-pins ---
test('trekbrief — v5.5 Phase 2.5 framing declaration heading present', () => {
const text = read();
assert.match(text, /^## Phase 2\.5 — Framing declaration/m,
'Phase 2.5 framing-declaration heading missing from commands/trekbrief.md');
});
test('trekbrief — v5.5 Phase 2.5 references all four framing values', () => {
const text = read();
const start = text.indexOf('## Phase 2.5');
const section = text.slice(start, text.indexOf('## Phase 3', start));
for (const v of ['preserve', 'refine', 'replace', 'new-direction']) {
assert.ok(section.includes(v), `Phase 2.5 missing framing value "${v}"`);
}
});
test('trekbrief — v5.5 Phase 2.5 runs before any brief prose (precedes Phase 3)', () => {
const text = read();
assert.ok(text.indexOf('## Phase 2.5') < text.indexOf('## Phase 3'),
'Phase 2.5 must come before the completeness loop (before prose)');
assert.ok(text.includes('even in `--quick` mode'),
'framing must be non-skippable even in --quick mode');
});
test('trekbrief — v5.5 Step 4a writes framing + brief_version 2.2 + generates TL;DR', () => {
const text = read();
assert.ok(/brief_version: "2\.2"/.test(text), 'Step 4a must set brief_version 2.2');
assert.ok(/framing: <state\.framing>/.test(text), 'Step 4a must write the committed framing value');
assert.ok(/## TL;DR/.test(text), 'Step 4a must generate the TL;DR section');
});
test('trekbrief — v5.5 Phase 4e gate includes memory_alignment', () => {
const text = read();
assert.ok(/memory_alignment\.score ≥ 4/.test(text),
'Phase 4e gate must require memory_alignment.score ≥ 4');
});
test('trekbrief — v5.5 brief-reviewer declares the memory-alignment dimension', () => {
const reviewer = readFileSync(REVIEWER_FILE, 'utf8');
assert.match(reviewer, /### 6\. Memory alignment/,
'brief-reviewer.md missing dimension 6 (memory alignment)');
assert.ok(reviewer.includes('"memory_alignment"'),
'brief-reviewer.md JSON schema missing memory_alignment key');
assert.ok(/no memory context (is )?supplied/i.test(reviewer),
'brief-reviewer must define the no-memory-context N/A fallback');
});
test('trekbrief — S18 brief-reviewer memory_alignment carries a status field', () => {
const reviewer = readFileSync(REVIEWER_FILE, 'utf8');
assert.ok(reviewer.includes('"status": "verified | n_a | contradictions"'),
'memory_alignment must emit a status enum (verified | n_a | contradictions) so a score-5 N/A (no memory) is distinguishable from a score-5 verified-aligned brief');
});
test('trekbrief — v5.5 template carries framing field, 2.2, and TL;DR section', () => {
const tpl = readFileSync(TEMPLATE_FILE, 'utf8');
assert.ok(/brief_version: "2\.2"/.test(tpl), 'template must declare brief_version 2.2');
assert.match(tpl, /^framing: \{preserve \| refine \| replace \| new-direction\}/m,
'template frontmatter must include the framing field');
assert.match(tpl, /^## TL;DR$/m, 'template must include the ## TL;DR section');
});