// tests/commands/trekreview.test.mjs // v5.1 prose-pin tests + v5.1.1 runtime SC4 + SC7 tests for /trekreview. 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'; import { resolvePhaseSignal } from '../../lib/profiles/phase-signal-resolver.mjs'; import { validateBriefContent } from '../../lib/validators/brief-validator.mjs'; import { parseDocument } from '../../lib/util/frontmatter.mjs'; const HERE = dirname(fileURLToPath(import.meta.url)); const ROOT = join(HERE, '..', '..'); const COMMAND_FILE = join(ROOT, 'commands', 'trekreview.md'); const MODES_DOC = join(ROOT, 'docs', 'command-modes.md'); const PHASE = 'review'; function read() { return readFileSync(COMMAND_FILE, 'utf8'); } function readModes() { return readFileSync(MODES_DOC, 'utf8'); } function readFixture(name) { return readFileSync(join(ROOT, 'tests', 'fixtures', name), 'utf8'); } function frontmatterOf(text) { const doc = parseDocument(text); return doc.parsed && doc.parsed.frontmatter; } // --- Pattern D prose-pins --- test('trekreview — sequencing-gate surface mentions BRIEF_V51_MISSING_SIGNALS + phase_signals', () => { const text = read(); assert.ok(text.includes('BRIEF_V51_MISSING_SIGNALS'), '/trekreview must surface the BRIEF_V51_MISSING_SIGNALS sequencing gate'); assert.ok(text.includes('phase_signals'), '/trekreview must reference phase_signals (v5.1 composition rule)'); }); test('trekreview — low-effort path references --quick equivalent', () => { const text = read(); const compIdx = text.indexOf('## Composition rule (v5.1)'); assert.ok(compIdx >= 0, 'Composition rule (v5.1) section missing'); const section = text.slice(compIdx, compIdx + 2000); assert.match(section, /--quick/, 'Low-effort path must mention --quick equivalent'); }); // --- v5.1.1 runtime SC4 + SC7 --- test('trekreview — SC4: low-effort fixture → resolver returns {effort: low, model: sonnet}', () => { const fm = frontmatterOf(readFixture('brief-effort-low.md')); const r = resolvePhaseSignal(fm, PHASE); assert.equal(r.effort, 'low'); assert.equal(r.model, 'sonnet'); }); test('trekreview — SC4: standard-effort fixture → resolver returns {effort: standard, model: undefined}', () => { const fm = frontmatterOf(readFixture('brief-effort-standard.md')); const r = resolvePhaseSignal(fm, PHASE); assert.equal(r.effort, 'standard'); assert.equal(r.model, undefined); }); test('trekreview — SC4: high-effort fixture → resolver returns {effort: high, model: opus}', () => { const fm = frontmatterOf(readFixture('brief-effort-high.md')); const r = resolvePhaseSignal(fm, PHASE); assert.equal(r.effort, 'high'); assert.equal(r.model, 'opus'); }); test('trekreview — SC7: brief_version 2.1 + no phase_signals + no partial → BRIEF_V51_MISSING_SIGNALS', () => { // Falsification via brief-v21-no-signals fixture: validator must catch missing signals. const r = validateBriefContent(readFixture('brief-v21-no-signals.md'), { strict: true }); assert.equal(r.valid, false); assert.ok( r.errors.find(e => e.code === 'BRIEF_V51_MISSING_SIGNALS'), `sequencing gate must fire; errors=${JSON.stringify(r.errors)}`, ); }); // --- S11 (NW2 part B) — opt-in --workflow substrate routing --- test('trekreview — Phase 1 flag table documents the --workflow opt-in flag', () => { const text = read(); assert.match(text, /--workflow/, 'commands/trekreview.md must document the --workflow opt-in flag (NW2 part B)'); }); test('trekreview — --workflow routes Phase 5–6 to the validated NW2 Workflow port script', () => { const text = read(); assert.ok(text.includes('scripts/trekreview-armB.workflow.mjs'), 'the --workflow route must reference the bake-off-validated NW2 Workflow port script'); }); test('trekreview — Workflow path is opt-in; default stays prose (portability floor)', () => { const text = read(); assert.match(text, /opt-in/i, '--workflow must be described as opt-in'); assert.ok(text.includes('Default stays prose'), 'the command must state the default Phase 5–6 path stays prose (not Workflow)'); }); test('trekreview — Workflow opt-in documents the Claude Code 2.1.154+ floor', () => { const text = read(); assert.match(text, /2\.1\.154/, 'the --workflow path raises the consumer floor and must document Claude Code 2.1.154+'); }); test('trekreview — bake-off evidence (fidelity-equivalent / T2 results) is cited for the opt-in', () => { const text = read(); assert.ok( text.includes('T2-bakeoff-results.md') && /fidelity-equivalent/i.test(text), 'the opt-in must cite the S10 bake-off (docs/T2-bakeoff-results.md) fidelity-equivalence verdict', ); }); test('command-modes.md — /trekreview table documents --workflow + its CC floor', () => { const text = readModes(); const start = text.indexOf('## /trekreview modes'); assert.ok(start >= 0, 'command-modes.md missing "## /trekreview modes" section'); const end = text.indexOf('\n## ', start + 1); const section = text.slice(start, end === -1 ? undefined : end); assert.match(section, /--workflow/, 'command-modes.md /trekreview table must list the --workflow opt-in flag'); assert.match(section, /2\.1\.154/, 'command-modes.md /trekreview --workflow row must note the Claude Code 2.1.154+ floor'); });