Make the bake-off-validated Workflow substrate (Arm B) reachable behind an opt-in --workflow flag for /trekreview. Default Phase 5-6 path stays prose to preserve the lower portability floor; --workflow raises the consumer floor to Claude Code 2.1.154+ (the Workflow tool). - arg-parser: --workflow added to trekreview boolean flags - commands/trekreview.md: flag row + Phase 5 substrate-routing gate + new section 'Phase 5-6 via the Workflow substrate' (invocation contract, S10 gotchas, bake-off citation, auto/bypass residual as Known limitation) - docs/command-modes.md: --workflow row in /trekreview table - routes to existing scripts/trekreview-armB.workflow.mjs (byte-identical to the S10 part-B POSITIVE build); integration is pure routing, no script change TDD: 8 new tests (arg-parser flag recognition + combine; command/doc prose pins for route, opt-in posture, 2.1.154+ floor, bake-off evidence). Suite 662 -> 670 (668 pass / 2 skip / 0 fail). plugin validate clean modulo known root-CLAUDE.md warning. Resolves W1-narrow-wins-plan.md S11.
123 lines
5.3 KiB
JavaScript
123 lines
5.3 KiB
JavaScript
// 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');
|
||
});
|