// tests/validators/brief-review-stamp.test.mjs // Operator decision 2026-10-08 (voyage-lekerepo trial point 14): /trekplan // Phase 4b re-ran brief-reviewer right after /trekbrief had run it on the same // text. Now /trekbrief stamps the body it reviewed (on a passed gate), and // /trekplan reviews again only when the stamp is absent or the body changed — // a brief from any other producer has no stamp and is always reviewed. // Same decision: every exploration agent runs at every codebase size; the // contradicting "Adaptive" rule is gone. import { test } from 'node:test'; import { strict as assert } from 'node:assert'; import { spawnSync } from 'node:child_process'; import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'; import { dirname, join } from 'node:path'; import { tmpdir } from 'node:os'; import { fileURLToPath } from 'node:url'; import { stampBriefReview, checkBriefReview } from '../../lib/validators/brief-review-stamp.mjs'; import { stampIntentApproval } from '../../lib/validators/intent-approval.mjs'; const HERE = dirname(fileURLToPath(import.meta.url)); const ROOT = join(HERE, '..', '..'); const CLI = join(ROOT, 'lib', 'validators', 'brief-review-stamp.mjs'); const BRIEF = [ '---', 'type: trekbrief', 'brief_version: "2.2"', 'task: t', 'slug: s', '---', '', '## TL;DR', '', 'A toy.', '', '## Intent', '', 'Why it matters.', '', '## Goal', '', 'What.', '', '## Success Criteria', '', '- `npm test` exits 0.', '', ].join('\n'); test('stamp, then check: current', () => { const s = stampBriefReview(BRIEF); assert.equal(s.stamped, true); assert.match(s.text, /^brief_reviewed_hash: "sha256:[0-9a-f]{64}"$/m); assert.equal(checkBriefReview(s.text).state, 'current'); }); test('no stamp: absent (another producer\'s brief is always reviewed)', () => { assert.equal(checkBriefReview(BRIEF).state, 'absent'); }); test('a changed body after the stamp: stale', () => { const s = stampBriefReview(BRIEF).text; assert.equal(checkBriefReview(s.replace('Why it matters.', 'Why it matters a lot.')).state, 'stale'); assert.equal(checkBriefReview(s + '\n## Non-Goals\n\n- none\n').state, 'stale'); }); test('frontmatter changes (the intent approval stamp) and CRLF keep the review current', () => { const s = stampBriefReview(BRIEF).text; const approved = stampIntentApproval(s).text; assert.notEqual(approved, s); assert.equal(checkBriefReview(approved).state, 'current'); assert.equal(checkBriefReview(s.replace(/\n/g, '\r\n')).state, 'current'); }); test('re-stamping replaces the old stamp, never adds a second', () => { const twice = stampBriefReview(stampBriefReview(BRIEF).text).text; assert.equal(twice.match(/^brief_reviewed_hash:/gm).length, 1); }); test('CLI: --stamp writes the file, --check exits 0 current / 1 stale or absent / 2 usage', () => { const dir = mkdtempSync(join(tmpdir(), 'voyage-brief-stamp-')); try { const p = join(dir, 'brief.md'); writeFileSync(p, BRIEF); const run = (...a) => spawnSync(process.execPath, [CLI, ...a], { encoding: 'utf8' }); assert.equal(run('--check', p).status, 1); assert.equal(run('--stamp', p).status, 0); assert.equal(run('--check', p).status, 0); writeFileSync(p, readFileSync(p, 'utf8').replace('What.', 'What else.')); const c = run('--check', '--json', p); assert.equal(c.status, 1); assert.equal(JSON.parse(c.stdout).state, 'stale'); assert.equal(run('--check').status, 2); } finally { rmSync(dir, { recursive: true, force: true }); } }); test('prose: /trekbrief stamps after a passed gate; /trekplan Phase 4b checks before it reviews again', () => { const brief = readFileSync(join(ROOT, 'commands', 'trekbrief.md'), 'utf8'); const plan = readFileSync(join(ROOT, 'commands', 'trekplan.md'), 'utf8'); assert.match(brief, /brief-review-stamp\.mjs --stamp/); const p4b = plan.slice(plan.indexOf('## Phase 4b'), plan.indexOf('## Phase 5')); assert.match(p4b, /brief-review-stamp\.mjs --check/); }); test('prose: every exploration agent runs at every codebase size; no "Adaptive" rule contradicts it', () => { const plan = readFileSync(join(ROOT, 'commands', 'trekplan.md'), 'utf8'); assert.match(plan, /All agents run for all codebase sizes/); assert.doesNotMatch(plan, /\*\*Adaptive\*\*/); assert.doesNotMatch(plan, /does not need 7 exploration agents/); });