chore(cleanup): R-b R1 — Voyage's own stats, events and OTel export removed

Removes Voyage's measurement, statistics and export apparatus (decision 189;
condition 175 met in step 1) and the R-a leftovers: lib/stats/, lib/exporters/,
the otel-export and post-bash-stats hooks, yardstick, end-state and comparison
gates, synthesis-measure, gold-scorer, docs/observability.md,
examples/observability/, docs/T1-cc26-delegated-orchestration.md and their
tests and fixtures. The six command stats phases and the /trekexecute
main-merge event blocks go; intent-approval --stamp no longer emits
brief-approved. README and docs point to Claude Code's own OpenTelemetry.

Files removed: 52. Files edited: 37.
npm test: 2930 tests (2928 pass / 0 fail / 2 skipped) before, 2600 tests
(2598 pass / 0 fail / 2 skipped) after. removed-surfaces group R1 green.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-11-07 20:11:00 +01:00
commit 21480e8627
Signed by: ktg
SSH key fingerprint: SHA256:JakMjO6FTBBzN0Bhfj9saOoEjaFxlSdYuZQQpM/lF9Q
89 changed files with 94 additions and 10290 deletions

View file

@ -1,422 +0,0 @@
// tests/scripts/comparison-gate.test.mjs
// The comparison gate counts the areas where Voyage + the operator's way of working is
// level with or ahead of every reference framework, and fells the table when a claim
// has no evidence behind it. It also counts the "tidy" denominator: every Voyage part a
// documented Claude Code primitive covers, and how many of those are resolved.
//
// Like the yardstick's tests, these pin the MECHANICS in both directions against
// throwaway fixtures. They deliberately do NOT assert that the real table is red today:
// the gate is supposed to turn green, and a test that pins today's distance would fail
// on the day the work is done. Nothing here reads the real table or the real source.
import { test } from 'node:test';
import { strict as assert } from 'node:assert';
import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join, dirname } from 'node:path';
import { execFileSync } from 'node:child_process';
import {
parseLoc,
parseSourceAreas,
listParts,
evaluate,
render,
main,
} from '../../scripts/comparison-gate.mjs';
// --- helpers ---------------------------------------------------------------
const lines = (n) => `${Array.from({ length: n }, (_, i) => `line ${i + 1}`).join('\n')}\n`;
const SOURCE = [
'# report',
'',
'## 2. Per kapabilitet',
'',
'| Kapabilitet | A | B |',
'|---|---|---|',
'| Alpha | x | y |',
'| Beta | x | y |',
'',
'## 3. Next section',
'',
'| Not | an | area |',
'|---|---|---|',
'| Gamma | x | y |',
'',
].join('\n');
function world() {
const dir = mkdtempSync(join(tmpdir(), 'comparison-gate-'));
const files = {
'vy/own.md': lines(5),
'pm/source.md': SOURCE,
'pm/why.md': lines(3),
'sp/ref.md': lines(10),
};
for (const [rel, body] of Object.entries(files)) {
const p = join(dir, rel);
mkdirSync(dirname(p), { recursive: true });
writeFileSync(p, body);
}
return { dir, roots: { VY: join(dir, 'vy'), PM: join(dir, 'pm'), SP: join(dir, 'sp') } };
}
const cleanup = (w) => rmSync(w.dir, { recursive: true, force: true });
// A table that is fully green: every area level or ahead, every cell with evidence,
// an independent reader, and the one covered part resolved with a measured reason.
function greenData(w) {
return {
schema: 'voyage-comparison/1',
source: { loc: 'PM:source.md', heading: '## 2. Per kapabilitet' },
roots: w.roots,
references: [{ id: 'SP', name: 'obra/superpowers' }],
reader: { kind: 'uavhengig', who: 'fixture', date: '2026-10-02' },
areas: [
{
id: 'alpha',
title: 'Alpha',
own: { evidence: [{ loc: 'VY:own.md:1-2', says: 'own side' }] },
cells: {
SP: { verdict: 'likt', why: 'level', evidence: [{ loc: 'SP:ref.md:3-10', says: 'ref side' }] },
},
},
{
id: 'beta',
title: 'Beta',
own: { evidence: [{ loc: 'VY:own.md:5', says: 'own side' }] },
cells: {
SP: {
verdict: 'foran',
why: 'the reference has nothing here',
evidence: [{
absence: { query: 'grep -rn beta .', hits: 0, known_positive: 'grep -rn line . finds 10' },
says: 'no beta in the reference',
}],
},
},
},
],
tidy: {
primitives: [{ id: 'subagents', name: 'Subagents', doc: 'https://code.claude.com/docs/en/sub-agents', quote: 'q' }],
parts: [
{
path: 'commands/x.md', covered_by: ['subagents'], coverage: 'delvis', why: 'w',
resolution: 'maalt-grunn', reason: { loc: 'PM:why.md:1-3', says: 'measured' },
},
{ path: 'lib/y.mjs', covered_by: [], coverage: 'ikke-dekket', why: 'w', resolution: null, reason: null },
],
},
};
}
const PARTS = ['commands/x.md', 'lib/y.mjs'];
const run = (w, data) => evaluate(data, { parts: PARTS });
const problemText = (r) => r.problems.join('\n');
// --- parsing -----------------------------------------------------------------
test('parseLoc: root, path and a line or a line range', () => {
assert.deepEqual(parseLoc('SP:skills/a/SKILL.md:38-88'), { root: 'SP', path: 'skills/a/SKILL.md', start: 38, end: 88 });
assert.deepEqual(parseLoc('VY:lib/x.mjs:7'), { root: 'VY', path: 'lib/x.mjs', start: 7, end: 7 });
assert.equal(parseLoc('lib/x.mjs:7'), null, 'a loc without a root is not evidence');
assert.equal(parseLoc('VY:lib/x.mjs'), null, 'a loc without a line is not evidence');
assert.equal(parseLoc('VY:lib/x.mjs:9-3'), null, 'a range that runs backwards is not evidence');
assert.equal(parseLoc('VY:lib/x.mjs:0'), null, 'lines count from 1');
});
test('parseSourceAreas: reads the first column of the table under the heading, and only that table', () => {
assert.deepEqual(parseSourceAreas(SOURCE, '## 2. Per kapabilitet'), ['Alpha', 'Beta']);
assert.equal(parseSourceAreas(SOURCE, '## 9. Missing'), null);
});
test('listParts: tracked files in the scope, eval cases as one part each, nothing outside the scope', () => {
const dir = mkdtempSync(join(tmpdir(), 'comparison-gate-parts-'));
try {
for (const rel of ['commands/a.md', 'lib/u/b.mjs', 'evals/case-1/eval.json', 'evals/case-1/fixture/x.md',
'evals/case-2/eval.json', 'docs/not-a-part.md', 'settings.json', 'untracked/z.md']) {
mkdirSync(dirname(join(dir, rel)), { recursive: true });
writeFileSync(join(dir, rel), 'x\n');
}
execFileSync('git', ['init', '-q'], { cwd: dir });
execFileSync('git', ['add', 'commands', 'lib', 'evals', 'docs', 'settings.json'], { cwd: dir });
assert.deepEqual(listParts(dir), ['commands/a.md', 'evals/case-1/', 'evals/case-2/', 'lib/u/b.mjs', 'settings.json']);
} finally {
rmSync(dir, { recursive: true, force: true });
}
});
// --- the comparison ------------------------------------------------------------
test('a fully evidenced table, every area level or ahead, read by an independent reader, is green', () => {
const w = world();
try {
const r = run(w, greenData(w));
assert.deepEqual(r.problems, []);
assert.equal(r.comparison.level_or_ahead, 2);
assert.equal(r.comparison.total, 2);
assert.equal(r.green, true);
} finally { cleanup(w); }
});
test('a cell with NO evidence fells the table, whatever its verdict says', () => {
const w = world();
try {
const data = greenData(w);
data.areas[0].cells.SP.evidence = [];
const r = run(w, data);
assert.match(problemText(r), /alpha.*SP.*no evidence/);
assert.equal(r.green, false);
} finally { cleanup(w); }
});
test('an area with no evidence on our own side fells the table', () => {
const w = world();
try {
const data = greenData(w);
delete data.areas[1].own;
const r = run(w, data);
assert.match(problemText(r), /beta.*own.*no evidence/);
assert.equal(r.green, false);
} finally { cleanup(w); }
});
test('a cited line past the end of the file is not evidence', () => {
const w = world();
try {
const data = greenData(w);
data.areas[0].cells.SP.evidence[0].loc = 'SP:ref.md:3-11';
const r = run(w, data);
assert.match(problemText(r), /SP:ref\.md:3-11.*10 lines/);
assert.equal(r.green, false);
} finally { cleanup(w); }
});
test('a cited file that does not exist, or that escapes its root, is not evidence', () => {
const w = world();
try {
const data = greenData(w);
data.areas[0].cells.SP.evidence[0].loc = 'SP:missing.md:1';
data.areas[0].own.evidence[0].loc = 'VY:../pm/source.md:1';
const r = run(w, data);
assert.match(problemText(r), /SP:missing\.md:1.*does not exist/);
assert.match(problemText(r), /VY:\.\.\/pm\/source\.md:1.*outside its root/);
} finally { cleanup(w); }
});
test('an absence without a known-positive control is not evidence, and neither is one with hits', () => {
const w = world();
try {
const data = greenData(w);
delete data.areas[1].cells.SP.evidence[0].absence.known_positive;
let r = run(w, data);
assert.match(problemText(r), /beta.*SP.*known_positive/);
const again = greenData(w);
again.areas[1].cells.SP.evidence[0].absence.hits = 2;
r = run(w, again);
assert.match(problemText(r), /beta.*SP.*hits/);
} finally { cleanup(w); }
});
test('a web citation needs a verbatim quote', () => {
const w = world();
try {
const data = greenData(w);
data.areas[0].cells.SP.evidence = [{ url: 'https://example.org/playbook#review', says: 'x' }];
let r = run(w, data);
assert.match(problemText(r), /alpha.*SP.*quote/);
data.areas[0].cells.SP.evidence = [{ url: 'https://example.org/playbook#review', quote: 'every change is reviewed', says: 'x' }];
r = run(w, data);
assert.deepEqual(r.problems, []);
} finally { cleanup(w); }
});
test('the denominator comes from the SOURCE: an area the source lists but the table drops fells it', () => {
const w = world();
try {
const data = greenData(w);
data.areas.pop();
const r = run(w, data);
assert.match(problemText(r), /Beta.*missing from the table/);
assert.equal(r.comparison.total, 2, 'the total is the source count, not the table count');
assert.equal(r.green, false);
} finally { cleanup(w); }
});
test('an area the source does not list is not counted and is reported', () => {
const w = world();
try {
const data = greenData(w);
data.areas.push({ ...data.areas[0], id: 'gamma', title: 'Gamma' });
const r = run(w, data);
assert.match(problemText(r), /Gamma.*not in the source/);
assert.equal(r.comparison.total, 2);
} finally { cleanup(w); }
});
test('a missing reference cell fells the table; an unknown verdict fells it', () => {
const w = world();
try {
const data = greenData(w);
data.references.push({ id: 'PS', name: 'mattpocock/skills' });
let r = run(w, data);
assert.match(problemText(r), /alpha.*PS.*missing/);
const again = greenData(w);
again.areas[0].cells.SP.verdict = 'probably fine';
r = run(w, again);
assert.match(problemText(r), /alpha.*SP.*verdict/);
} finally { cleanup(w); }
});
test('one reference ahead of us in one area: that area is not counted, and it is named', () => {
const w = world();
try {
const data = greenData(w);
data.areas[0].cells.SP.verdict = 'bak';
const r = run(w, data);
assert.deepEqual(r.problems, []);
assert.equal(r.comparison.level_or_ahead, 1);
assert.deepEqual(r.comparison.behind, [{ area: 'alpha', references: ['SP'] }]);
assert.equal(r.green, false);
} finally { cleanup(w); }
});
test('the count per reference shows which framework pulls the total down', () => {
const w = world();
try {
const data = greenData(w);
data.references.push({ id: 'PS', name: 'mattpocock/skills' });
for (const a of data.areas) a.cells.PS = { ...a.cells.SP };
data.areas[0].cells.PS = { ...data.areas[0].cells.SP, verdict: 'bak' };
const r = run(w, data);
assert.deepEqual(r.problems, []);
assert.deepEqual(r.comparison.per_reference, { SP: 2, PS: 1 });
assert.equal(r.comparison.level_or_ahead, 1);
assert.match(render(r), /PS: 1 of 2/);
} finally { cleanup(w); }
});
test('14 of 14 is not green until an INDEPENDENT reader judged it', () => {
const w = world();
try {
const data = greenData(w);
data.reader.kind = 'pm-rapport';
const r = run(w, data);
assert.deepEqual(r.problems, []);
assert.equal(r.comparison.level_or_ahead, 2);
assert.equal(r.green, false);
assert.match(r.reasons.join('\n'), /independent reader/);
} finally { cleanup(w); }
});
test('a pinned reference whose clone has moved is not evidence for the pinned revision', () => {
const w = world();
try {
execFileSync('git', ['init', '-q'], { cwd: w.roots.SP });
execFileSync('git', ['add', '.'], { cwd: w.roots.SP });
execFileSync('git', ['-c', 'user.name=t', '-c', 'user.email=t@t', 'commit', '-qm', 'x'], { cwd: w.roots.SP });
const data = greenData(w);
data.references[0].pin = '0000000';
const r = run(w, data);
assert.match(problemText(r), /SP.*pinned 0000000.*HEAD/);
data.references[0].pin = execFileSync('git', ['rev-parse', '--short', 'HEAD'], { cwd: w.roots.SP, encoding: 'utf-8' }).trim();
assert.deepEqual(run(w, data).problems, []);
} finally { cleanup(w); }
});
// --- tidy ------------------------------------------------------------------------
test('tidy: a tracked part the list leaves out fells it; the denominator is the tree, not the list', () => {
const w = world();
try {
const r = evaluate(greenData(w), { parts: [...PARTS, 'agents/new.md'] });
assert.match(problemText(r), /agents\/new\.md.*missing from the tidy list/);
assert.equal(r.tidy.parts, 3);
assert.equal(r.green, false);
} finally { cleanup(w); }
});
test('tidy: a covered part counts as resolved only with a measured reason or as removed from the tree', () => {
const w = world();
try {
const data = greenData(w);
data.tidy.parts[0].resolution = 'aapen';
data.tidy.parts[0].reason = null;
let r = run(w, data);
assert.deepEqual(r.problems, []);
assert.equal(r.tidy.covered, 1);
assert.equal(r.tidy.resolved, 0);
assert.equal(r.green, false);
const noReason = greenData(w);
noReason.tidy.parts[0].reason = null;
r = run(w, noReason);
assert.match(problemText(r), /commands\/x\.md.*maalt-grunn.*reason/);
const removed = greenData(w);
removed.tidy.parts[0] = { ...removed.tidy.parts[0], resolution: 'fjernet', reason: null, commit: 'abc1234' };
r = run(w, removed);
assert.match(problemText(r), /commands\/x\.md.*fjernet.*still in the tree/);
r = evaluate(removed, { parts: ['lib/y.mjs'] });
assert.deepEqual(r.problems, []);
assert.equal(r.tidy.resolved, 1);
} finally { cleanup(w); }
});
test('tidy: a primitive without a documentation URL, or a part covered by an unknown primitive, fells it', () => {
const w = world();
try {
const data = greenData(w);
data.tidy.primitives[0].doc = 'somewhere';
data.tidy.parts[0].covered_by = ['subagents', 'nonexistent'];
const r = run(w, data);
assert.match(problemText(r), /subagents.*documentation URL/);
assert.match(problemText(r), /commands\/x\.md.*nonexistent/);
} finally { cleanup(w); }
});
// --- output and CLI ------------------------------------------------------------------
test('render names the count, the behind areas and the reader', () => {
const w = world();
try {
const data = greenData(w);
data.areas[0].cells.SP.verdict = 'bak';
data.reader.kind = 'pm-rapport';
const text = render(run(w, data));
assert.match(text, /1 of 2/);
assert.match(text, /alpha \(SP\)/);
assert.match(text, /pm-rapport/);
assert.match(text, /RED/);
} finally { cleanup(w); }
});
test('main: a missing table is NOT MEASURED and exits 1, never 0; an unknown flag exits 2', () => {
const w = world();
try {
assert.equal(main(['--data', join(w.dir, 'nope.json'), '--json']), 1);
assert.equal(main(['--nope']), 2);
} finally { cleanup(w); }
});
test('main: exit 0 only for a green table, 1 for a red one', () => {
const w = world();
try {
const file = join(w.dir, 'table.json');
writeFileSync(file, JSON.stringify(greenData(w)));
// --parts-from pins the denominator to a fixture repo instead of the real tree
const repo = join(w.dir, 'repo');
for (const rel of PARTS) {
mkdirSync(dirname(join(repo, rel)), { recursive: true });
writeFileSync(join(repo, rel), 'x\n');
}
execFileSync('git', ['init', '-q'], { cwd: repo });
execFileSync('git', ['add', '.'], { cwd: repo });
assert.equal(main(['--data', file, '--parts-from', repo, '--json']), 0);
const red = greenData(w);
red.areas[0].cells.SP.evidence = [];
writeFileSync(file, JSON.stringify(red));
assert.equal(main(['--data', file, '--parts-from', repo, '--json']), 1);
} finally { cleanup(w); }
});

View file

@ -1,950 +0,0 @@
// tests/scripts/end-state-gate.test.mjs
// The end-state gate counts the distance to "Voyage is finished" as five tallies:
// open pipeline defects, unresolved experiments/opt-ins, dormant agents, open operator
// decisions, and feat commits after the freeze tag. "Finished" = all five at 0 AND the
// registry the gate counts from is intact against its frozen denominator.
//
// These tests pin the gate's MECHANICS in both directions — every tally can be 0 and can
// be > 0 — against throwaway fixture trees. They deliberately do NOT assert that the real
// repo is red today: the gate is supposed to go green, and a test that pins the current
// distance would fail on the day the work is done. What they DO pin about the real repo
// is the denominator itself (see "the frozen denominator" below).
import { test } from 'node:test';
import { strict as assert } from 'node:assert';
import { mkdtempSync, mkdirSync, writeFileSync, rmSync, existsSync, readFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join, dirname, resolve } from 'node:path';
import { spawnSync } from 'node:child_process';
import { fileURLToPath } from 'node:url';
import {
evaluateCondition,
evaluateCheck,
measure,
loadRegistry,
loadFrozen,
spawnedNames,
checkSignature,
verifyIntegrity,
render,
PROBE_NOTES,
} from '../../scripts/end-state-gate.mjs';
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..', '..');
const GATE = join(ROOT, 'scripts', 'end-state-gate.mjs');
// --- the frozen denominator ------------------------------------------------
// Denominator frozen 2026-09-17, the day the end-state
// direction was chosen. An entry may CLOSE; it may never be removed or have its check
// changed, and the gate's agent/decision/freeze configuration may not move. To change
// anything below you must change this test — say in the commit message who decided it.
const FROZEN = {
defects: {
'D-01': '48f7f5cca070091e8f9b9ca0c7cdb7a1880733691935c25d07ea1d3e8d508fc9',
'D-02': 'dfc94dba04a9116ae9be2097a0c5a9d8313b02c7de1ca6b49a472c1823a6d1e1',
// Amended 2026-09-18 (operator decision): D-03/D-04 became behaviour probes.
// Amended a second time the same day, as a maintenance decision: those
// behaviour probes were greps for an export name, and a two-line stub
// exporting both names closed them on an unfixed tree (mutant M6, pinned
// below). They now RUN a named test.
// Amended a third time the same day, same standing: a named test can be
// EMPTY, and two empty tests with the right names closed both defects on a
// tree without lib/verification/ (mutant M7, pinned below). Each condition
// now also names the module whose STUB its test must fell. Every amendment
// moved a signature on purpose and removed nothing.
'D-03': '98698ce74c243353713786b8604160f6672568b090884e9428d9e5e9fbcad89d',
'D-04': 'df11a2e95db7b014ce077db0473e5dde4195ace92d8077cacdc1cee273947b47',
'D-05': '8fe6df52b43496c3302400507cb98002dcf8d2a12d92085e14bda4c7819bc7ba',
'D-06': '72a787c8154d1c18849e9856dcf1a67703d6b5541f88db81d6bab13cab14b418',
'D-07': '1bf3e0cd36c621720697475b0a3fd7db78611d66b58a9ce035e7695e57c69f1b',
},
experiments: {
'E-01': 'f7718897cec8ace6879fe79f5f32760ec957c3642e7186f8aa1688ce77b3f4e8',
'E-02': 'c8ff12c504ba7a9ac36f11bb8f9b713263e9b4eb28c07d984d9e2115980e740d',
'E-03': '17153ad8808615a833a49ae0c3523264ce055aa690e5542a75bae1874495e7e8',
},
agents: {
dir: 'agents',
spawnSites: 'commands/*.md',
referenceMarker: 'Reference document, not a spawnable capability',
},
decisions: {
file: 'STATE.md',
section: '## Åpne operatørbeslutninger',
open: '^- \\[ \\] ',
closed: '^- \\[x\\] ',
},
freeze: { tag: 'end-state-freeze', featPattern: '^feat(\\(|!|:)' },
};
// --- helpers ---------------------------------------------------------------
function fixture(files) {
const dir = mkdtempSync(join(tmpdir(), 'end-state-gate-'));
for (const [rel, body] of Object.entries(files)) {
const p = join(dir, rel);
mkdirSync(dirname(p), { recursive: true });
writeFileSync(p, body);
}
return dir;
}
const cleanup = (...dirs) => { for (const d of dirs) rmSync(d, { recursive: true, force: true }); };
const DECISIONS = { file: 'STATE.md', section: '## Open decisions', open: '^- \\[ \\] ', closed: '^- \\[x\\] ' };
const AGENTS = { dir: 'agents', spawnSites: 'commands/*.md', referenceMarker: 'Reference document, not a spawnable capability' };
const FREEZE = { tag: 'end-state-freeze', featPattern: '^feat(\\(|!|:)' };
function registry(overrides = {}) {
return { defects: [], experiments: [], agents: AGENTS, decisions: DECISIONS, freeze: FREEZE, ...overrides };
}
// A frozen manifest that matches `reg` exactly.
function frozenFor(reg) {
const sigs = (list) => Object.fromEntries(list.map((e) => [e.id, checkSignature(e.check)]));
return { defects: sigs(reg.defects), experiments: sigs(reg.experiments), agents: reg.agents, decisions: reg.decisions, freeze: reg.freeze };
}
function git(dir, ...args) {
const r = spawnSync('git', [
'-c', 'user.name=fixture', '-c', 'user.email=fixture@example.invalid',
'-c', 'core.hooksPath=/dev/null', '-c', 'commit.gpgsign=false', '-c', 'tag.gpgsign=false',
...args,
], { cwd: dir, encoding: 'utf8' });
assert.equal(r.status, 0, `git ${args.join(' ')}: ${r.stderr}`);
return r.stdout;
}
function gitInit(dir) {
git(dir, 'init', '-q');
git(dir, 'add', '-A');
git(dir, 'commit', '-q', '--allow-empty', '-m', 'chore: fixture baseline');
}
function gitCommit(dir, subject) {
git(dir, 'commit', '-q', '--allow-empty', '-m', subject);
}
const rowById = (result, id) => result.rows.find((r) => r.id === id);
// --- conditions -----------------------------------------------------------
test('evaluateCondition: match / no-match on a single file, multiline regex', () => {
const dir = fixture({ 'a.md': 'intro\n### Heading\nbody\n' });
try {
assert.equal(evaluateCondition(dir, { path: 'a.md', pattern: '^### Heading', flags: 'm', expect: 'match' }), true);
assert.equal(evaluateCondition(dir, { path: 'a.md', pattern: '^### Other', flags: 'm', expect: 'match' }), false);
assert.equal(evaluateCondition(dir, { path: 'a.md', pattern: '^### Other', flags: 'm', expect: 'no-match' }), true);
} finally { cleanup(dir); }
});
test('evaluateCondition: globs (dir/*.ext, dir/**/*.ext) and path arrays match ANY file', () => {
const dir = fixture({
'commands/x.md': 'nothing here\n',
'lib/deep/y.mjs': 'const FLAG = process.env.SOME_FLAG;\n',
});
try {
assert.equal(evaluateCondition(dir, { path: 'commands/*.md', pattern: 'SOME_FLAG', expect: 'match' }), false);
assert.equal(evaluateCondition(dir, { path: 'lib/**/*.mjs', pattern: 'SOME_FLAG', expect: 'match' }), true);
assert.equal(evaluateCondition(dir, { path: ['commands/*.md', 'lib/**/*.mjs'], pattern: 'SOME_FLAG', expect: 'match' }), true);
assert.equal(evaluateCondition(dir, { path: ['commands/*.md', 'lib/**/*.mjs'], pattern: 'SOME_FLAG', expect: 'no-match' }), false);
} finally { cleanup(dir); }
});
test('evaluateCondition: section scoping reads only from the heading to the next "## "', () => {
const dir = fixture({
'doc.md': '## 5. Design\nno status here\n## 6. PoC\n> **STATUS: RUN AND DECLINED**\n',
});
try {
const inFive = { path: 'doc.md', section: '## 5.', pattern: '^> \\*\\*STATUS:', flags: 'm', expect: 'no-match' };
const inSix = { ...inFive, section: '## 6.' };
assert.equal(evaluateCondition(dir, inFive), true, 'section 5 has no status block');
assert.equal(evaluateCondition(dir, inSix), false, 'section 6 has one');
} finally { cleanup(dir); }
});
test('evaluateCondition: a literal NUL byte is detectable', () => {
const dir = fixture({ 'nul.mjs': "const SEP = '\u0000';\n", 'clean.mjs': "const SEP = '\\x00';\n" });
try {
assert.equal(evaluateCondition(dir, { path: 'nul.mjs', pattern: '\\u0000', expect: 'match' }), true);
assert.equal(evaluateCondition(dir, { path: 'clean.mjs', pattern: '\\u0000', expect: 'match' }), false);
} finally { cleanup(dir); }
});
test('evaluateCondition: a missing file, a missing glob base or a missing section throws', () => {
const dir = fixture({ 'a.md': 'x\n' });
try {
assert.throws(() => evaluateCondition(dir, { path: 'missing.md', pattern: 'x', expect: 'no-match' }), /missing\.md/);
assert.throws(() => evaluateCondition(dir, { path: 'nodir/*.md', pattern: 'x', expect: 'no-match' }), /nodir/);
assert.throws(() => evaluateCondition(dir, { path: 'a.md', section: '## 9.', pattern: 'x', expect: 'no-match' }), /## 9\./);
} finally { cleanup(dir); }
});
test('evaluateCondition: a glob over an EXISTING dir with no matching files throws (no silent no-match)', () => {
// In a no-match condition, "silently nothing matched" would read as the condition holding.
const dir = fixture({ 'docs/readme.txt': 'x\n' });
try {
assert.throws(() => evaluateCondition(dir, { path: 'docs/*.md', pattern: 'x', expect: 'no-match' }), /docs\/\*\.md/);
assert.throws(() => evaluateCondition(dir, { path: 'docs/**/*.md', pattern: 'x', expect: 'no-match' }), /docs\/\*\*\/\*\.md/);
} finally { cleanup(dir); }
});
test('evaluateCheck: open only when ALL conditions hold; null check is not fellable', () => {
const dir = fixture({
'r.md': 'run the `### Bridge agent` block\n',
'fixed.md': 'run the `### Bridge agent` block\n### Bridge agent\n',
});
const dangling = (file) => [
{ path: file, pattern: '`### Bridge agent`', expect: 'match' },
{ path: file, pattern: '^### Bridge agent', flags: 'm', expect: 'no-match' },
];
try {
assert.equal(evaluateCheck(dir, dangling('r.md')).status, 'open');
assert.equal(evaluateCheck(dir, dangling('fixed.md')).status, 'closed');
assert.equal(evaluateCheck(dir, null).status, 'not-fellable');
const broken = evaluateCheck(dir, dangling('gone.md'));
assert.equal(broken.status, 'not-fellable');
assert.match(broken.detail, /gone\.md/);
} finally { cleanup(dir); }
});
// --- spawn instructions (what "referenced by a command" means) -------------
test('spawnedNames: a row of a table headed `Agent` is a spawn instruction; other tables are not', () => {
const md = [
'Launch the new agents:', '',
'| Agent | Purpose |', '|-------|---------|', '| `alpha-agent` | does a |', '| `beta-agent` | does b |', '',
'| Name | Purpose |', '|------|---------|', '| `gamma-agent` | just a list |', '',
].join('\n');
const names = spawnedNames(md);
assert.ok(names.has('alpha-agent') && names.has('beta-agent'));
assert.ok(!names.has('gamma-agent'), 'a table not headed "Agent" is not a roster');
});
test('spawnedNames: an imperative Launch/Spawn line names the agents it launches', () => {
const md = [
'Launch the **alpha-agent** agent:',
'- Launch `beta-agent` (Agent tool) with the findings.',
'3. Spawn `voyage:gamma-agent` in the background.',
'**Launch** the `delta-agent` agent now.',
'launch `epsilon-agent` too',
].join('\n');
const names = spawnedNames(md);
for (const n of ['alpha-agent', 'beta-agent', 'gamma-agent', 'delta-agent', 'epsilon-agent']) {
assert.ok(names.has(n), `${n} should count as spawned`);
}
});
test('spawnedNames: an agent block with a Prompt: line is a spawn instruction; a bare bold name is not', () => {
const md = [
'**alpha-agent** — adversarial review of the plan.',
'Prompt: "Review this plan."',
'',
'**beta-agent** — mentioned for context only.',
'It is not launched here.',
].join('\n');
const names = spawnedNames(md);
assert.ok(names.has('alpha-agent'));
assert.ok(!names.has('beta-agent'));
});
test('spawnedNames: prose, negation, comments, fences and quotes are never spawn instructions', () => {
const md = [
'The alpha-agent is dormant and is never spawned.',
'Never launch `beta-agent`.',
'In quick mode we used to launch `gamma-agent`.',
'<!-- Launch the `delta-agent` agent -->',
'<!--',
'Launch the `epsilon-agent` agent',
'-->',
'```',
'Launch the `zeta-agent` agent',
'| Agent |',
'|---|',
'| `eta-agent` |',
'```',
'> Launch the `theta-agent` agent',
].join('\n');
const names = spawnedNames(md);
for (const n of ['alpha-agent', 'beta-agent', 'gamma-agent', 'delta-agent', 'epsilon-agent', 'zeta-agent', 'eta-agent', 'theta-agent']) {
assert.ok(!names.has(n), `${n} must not count as spawned`);
}
});
// --- the tallies, both directions ------------------------------------------
test('defects tally: > 0 while a check holds, 0 once fixed; not-fellable counts as open', () => {
const defect = {
id: 'D-X',
summary: 'removed tool still referenced',
probe: 'phrase',
check: [{ path: 'commands/plan.md', pattern: '\\bTeamCreate\\b', expect: 'match' }],
};
const unfellable = { id: 'D-Y', summary: 'no runnable check yet', check: null };
const base = { 'STATE.md': '## Open decisions\n', 'agents/a.md': 'x\n', 'commands/plan.md': 'Launch `a`\n' };
const red = fixture({ ...base, 'commands/plan.md': 'Launch `a` and TeamCreate\n' });
const green = fixture(base);
try {
let row = rowById(measure(red, registry({ defects: [defect] })), 'defects');
assert.equal(row.open, 1);
assert.equal(row.total, 1);
row = rowById(measure(green, registry({ defects: [defect] })), 'defects');
assert.equal(row.open, 0);
row = rowById(measure(green, registry({ defects: [defect, unfellable] })), 'defects');
assert.equal(row.open, 1, 'a defect without a runnable check stays open');
assert.equal(row.items.find((i) => i.id === 'D-Y').status, 'not-fellable');
} finally { cleanup(red, green); }
});
test('experiments tally: an env-gated opt-in is open until its gate is gone', () => {
const exp = {
id: 'E-X',
summary: 'default-off loop',
probe: 'phrase',
check: [{ path: ['commands/*.md', 'lib/**/*.mjs'], pattern: 'LOOP_ENABLED', expect: 'match' }],
};
const base = { 'STATE.md': '## Open decisions\n', 'agents/a.md': 'x\n', 'commands/r.md': 'Launch `a`\n' };
const red = fixture({ ...base, 'lib/util/cap.mjs': 'if (process.env.LOOP_ENABLED) {}\n' });
const green = fixture({ ...base, 'lib/util/cap.mjs': 'export const x = 1;\n' });
try {
assert.equal(rowById(measure(red, registry({ experiments: [exp] })), 'experiments').open, 1);
assert.equal(rowById(measure(green, registry({ experiments: [exp] })), 'experiments').open, 0);
} finally { cleanup(red, green); }
});
test('dormant-agents tally: an agent no command spawns counts; reference docs never do', () => {
const files = {
'STATE.md': '## Open decisions\n',
'agents/used-agent.md': '---\nname: used-agent\ndescription: |\n does work\n---\n',
'agents/idle-agent.md': '---\nname: idle-agent\ndescription: |\n never wired\n---\n',
'agents/some-orchestrator.md': '---\nname: some-orchestrator\ndescription: Reference document, not a spawnable capability — docs\n---\n',
'commands/run.md': 'Launch the **used-agent** agent.\n',
};
const red = fixture(files);
const green = fixture({ ...files, 'commands/other.md': 'Spawn `idle-agent` in parallel.\n' });
try {
let row = rowById(measure(red, registry()), 'dormant-agents');
assert.equal(row.open, 1);
assert.equal(row.total, 2, 'denominator = spawnable agents (reference docs excluded)');
assert.deepEqual(row.items.filter((i) => i.status === 'open').map((i) => i.id), ['idle-agent']);
row = rowById(measure(green, registry()), 'dormant-agents');
assert.equal(row.open, 0);
} finally { cleanup(red, green); }
});
test('dormant-agents tally: a prose sentence or an HTML comment does not wake a dormant agent', () => {
const files = {
'STATE.md': '## Open decisions\n',
'agents/idle-agent.md': '---\nname: idle-agent\ndescription: |\n never wired\n---\n',
'commands/plan.md': 'The idle-agent is dormant and is never spawned.\n',
'commands/end.md': '<!-- idle-agent -->\nThe research-idle-agents phase.\n',
};
const dir = fixture(files);
try {
assert.equal(rowById(measure(dir, registry()), 'dormant-agents').open, 1);
} finally { cleanup(dir); }
});
test('dormant-agents tally: an unmeasurable agents dir is n/a (null), never 0', () => {
const dir = fixture({ 'STATE.md': '## Open decisions\n', 'commands/r.md': 'x\n' });
try {
const result = measure(dir, registry());
const row = rowById(result, 'dormant-agents');
assert.equal(row.open, null);
assert.equal(row.total, null);
assert.match(row.detail, /not measurable/);
assert.equal(result.green, false);
} finally { cleanup(dir); }
});
test('decisions tally: counts open markers inside the section only, and says it counts ticks', () => {
const state = [
'# STATE',
'- [ ] outside the section, ignored',
'## Open decisions',
'- [ ] first open',
'- [x] already decided',
'- [ ] second open',
'## Next section',
'- [ ] also ignored',
'',
].join('\n');
const red = fixture({ 'STATE.md': state, 'agents/a.md': 'x\n', 'commands/r.md': 'Launch `a`\n' });
const green = fixture({
'STATE.md': '## Open decisions\n- [x] done\n## Next\n',
'agents/a.md': 'x\n',
'commands/r.md': 'Launch `a`\n',
});
try {
let row = rowById(measure(red, registry()), 'decisions');
assert.equal(row.open, 2);
assert.equal(row.total, 3);
assert.match(row.detail, /tick/i, 'the output must say a tick is not verified as a decision');
row = rowById(measure(green, registry()), 'decisions');
assert.equal(row.open, 0);
assert.equal(row.total, 1);
} finally { cleanup(red, green); }
});
test('decisions tally: a missing STATE.md or section is NOT MEASURABLE (null), never 0', () => {
const noState = fixture({ 'agents/a.md': 'x\n', 'commands/r.md': 'Launch `a`\n' });
const noSection = fixture({ 'STATE.md': '# STATE\n- [ ] x\n', 'agents/a.md': 'x\n', 'commands/r.md': 'Launch `a`\n' });
try {
for (const dir of [noState, noSection]) {
const result = measure(dir, registry());
const row = rowById(result, 'decisions');
assert.equal(row.open, null);
assert.ok(row.detail.length > 0, 'the reason is reported');
assert.equal(result.green, false, 'an unmeasurable tally keeps the gate red');
}
} finally { cleanup(noState, noSection); }
});
test('decisions tally: an unmarked list item in the section is format drift → NOT MEASURABLE', () => {
// A STATE written without the marker convention must not read as "0 open".
for (const item of ['1. **Some decision?** prose', '- plain bullet decision', '* star bullet']) {
const dir = fixture({
'STATE.md': `## Open decisions\n- [ ] marked\n${item}\n## Next\n`,
'agents/a.md': 'x\n',
'commands/r.md': 'Launch `a`\n',
});
try {
const row = rowById(measure(dir, registry()), 'decisions');
assert.equal(row.open, null, `unmarked "${item}" must make the tally unmeasurable`);
assert.match(row.detail, /unmarked/);
} finally { cleanup(dir); }
}
});
test('feat-after-freeze tally: not a git repo → n/a (red), never 0', () => {
const dir = fixture({ 'STATE.md': '## Open decisions\n' });
try {
const result = measure(dir, registry());
const row = rowById(result, 'feat-after-freeze');
assert.equal(row.open, null);
assert.match(row.detail, /not measured/);
assert.equal(result.green, false);
} finally { cleanup(dir); }
});
test('feat-after-freeze tally: no freeze tag yet → n/a (red), and the detail names the tag', () => {
const dir = fixture({ 'STATE.md': '## Open decisions\n' });
try {
gitInit(dir);
const row = rowById(measure(dir, registry()), 'feat-after-freeze');
assert.equal(row.open, null);
assert.match(row.detail, /end-state-freeze/);
} finally { cleanup(dir); }
});
test('feat-after-freeze tally: counts feat commits after the tag, 0 when there are none', () => {
const dir = fixture({ 'STATE.md': '## Open decisions\n' });
try {
gitInit(dir);
gitCommit(dir, 'feat: before the freeze does not count');
git(dir, 'tag', 'end-state-freeze');
let row = rowById(measure(dir, registry()), 'feat-after-freeze');
assert.equal(row.open, 0);
assert.equal(row.total, 0);
gitCommit(dir, 'fix(x): a defect fix is allowed');
gitCommit(dir, 'feature: not a conventional feat');
row = rowById(measure(dir, registry()), 'feat-after-freeze');
assert.equal(row.open, 0);
assert.equal(row.total, 2);
gitCommit(dir, 'feat(research): a new capability');
gitCommit(dir, 'feat!: a breaking capability');
row = rowById(measure(dir, registry()), 'feat-after-freeze');
assert.equal(row.open, 2);
assert.equal(row.total, 4);
} finally { cleanup(dir); }
});
// --- registry integrity (the judged party must not own the ledger) ---------
const SAMPLE = registry({
defects: [
{ id: 'D-01', summary: 'first defect', probe: 'phrase', check: [{ path: 'a.md', pattern: 'bad', expect: 'match' }] },
{ id: 'D-02', summary: 'second defect', probe: 'phrase', check: [{ path: 'a.md', pattern: 'worse', expect: 'match' }] },
],
experiments: [
{ id: 'E-01', summary: 'first experiment', probe: 'phrase', check: [{ path: 'a.md', pattern: 'FLAG', expect: 'match' }] },
{ id: 'E-02', summary: 'second experiment', probe: 'phrase', check: [{ path: 'a.md', pattern: 'OPT', expect: 'match' }] },
],
});
const clone = (v) => JSON.parse(JSON.stringify(v));
test('verifyIntegrity: the frozen registry itself is intact; a new entry may be added', () => {
const frozen = frozenFor(SAMPLE);
assert.deepEqual(verifyIntegrity(SAMPLE, frozen), { ok: true, violations: [] });
const grown = clone(SAMPLE);
grown.defects.push({ id: 'D-03', summary: 'found later', probe: 'phrase', check: [{ path: 'a.md', pattern: 'new', expect: 'match' }] });
assert.equal(verifyIntegrity(grown, frozen).ok, true);
});
test('verifyIntegrity: every registry attack is a violation that names what moved', () => {
const frozen = frozenFor(SAMPLE);
const attacks = {
'delete a defect': (r) => { r.defects = r.defects.filter((d) => d.id !== 'D-02'); },
'delete an experiment': (r) => { r.experiments = r.experiments.filter((e) => e.id !== 'E-01'); },
'weaken a defect check': (r) => { r.defects[0].check[0].pattern = '^NEVER MATCHES$'; },
'weaken an experiment check': (r) => { r.experiments[1].check[0].expect = 'no-match'; },
'drop a condition': (r) => { r.defects[0].check = []; },
'point spawnSites at agents': (r) => { r.agents = { ...r.agents, spawnSites: 'agents/*.md' }; },
'change the reference marker': (r) => { r.agents = { ...r.agents, referenceMarker: 'DORMANT' }; },
'move the decisions section': (r) => { r.decisions = { ...r.decisions, section: '## Elsewhere' }; },
'change the open marker': (r) => { r.decisions = { ...r.decisions, open: '^NEVER' }; },
'rename the freeze tag': (r) => { r.freeze = { ...r.freeze, tag: 'some-future-tag' }; },
'duplicate an id': (r) => { r.defects.push(clone(r.defects[0])); },
};
for (const [name, attack] of Object.entries(attacks)) {
const reg = clone(SAMPLE);
attack(reg);
const v = verifyIntegrity(reg, frozen);
assert.equal(v.ok, false, `${name} must be caught`);
assert.ok(v.violations.length > 0 && v.violations.every((s) => typeof s === 'string' && s.length > 0), name);
}
});
test('verifyIntegrity: spawnSites may never include agents/, even if the manifest says so', () => {
const reg = clone(SAMPLE);
reg.agents = { ...reg.agents, spawnSites: 'agents/*.md' };
const v = verifyIntegrity(reg, frozenFor(reg));
assert.equal(v.ok, false);
assert.ok(v.violations.some((s) => /agents\//.test(s)));
});
test('checkSignature: key order does not matter; every field of a condition does', () => {
const a = [{ path: 'a.md', pattern: 'x', flags: 'm', expect: 'match' }];
const reordered = [{ expect: 'match', flags: 'm', pattern: 'x', path: 'a.md' }];
assert.equal(checkSignature(a), checkSignature(reordered));
for (const change of [{ path: 'b.md' }, { pattern: 'y' }, { flags: '' }, { expect: 'no-match' }, { section: '## 1.' }]) {
assert.notEqual(checkSignature([{ ...a[0], ...change }]), checkSignature(a), JSON.stringify(change));
}
assert.match(checkSignature(a), /^[0-9a-f]{64}$/);
});
test('measure: a missing frozen manifest makes integrity n/a and keeps the gate red', () => {
const dir = fixture({ 'STATE.md': '## Open decisions\n' });
try {
const result = measure(dir, registry());
assert.equal(result.integrity.ok, null);
assert.match(result.integrity.detail, /end-state-frozen\.json/);
assert.equal(result.green, false);
} finally { cleanup(dir); }
});
// --- render ----------------------------------------------------------------
test('render: the header counts only tallies that ARE 0, never n/a ones', () => {
const result = {
green: false,
integrity: { ok: true, violations: [], detail: '' },
rows: [
{ id: 'defects', label: 'l', source: 's', open: 0, total: 1, target: 0, items: [], detail: '' },
{ id: 'experiments', label: 'l', source: 's', open: null, total: null, target: 0, items: [], detail: 'not measurable: x' },
{ id: 'dormant-agents', label: 'l', source: 's', open: 0, total: 3, target: 0, items: [], detail: '' },
],
};
const text = render(result);
assert.match(text, /RED \(2 of 3 tallies at 0\)/);
assert.match(text, /\| experiments \| n\/a \| n\/a \|/);
});
test('render: open phrase probes are labelled, closed ids are listed, integrity is shown', () => {
const result = {
green: false,
integrity: { ok: false, violations: ['D-02 removed from the registry'], detail: '' },
rows: [{
id: 'defects', label: 'open pipeline defects', source: 's', open: 1, total: 2, target: 0, detail: '',
items: [
{ id: 'D-01', summary: 'still open', probe: 'phrase', status: 'open', detail: '' },
{ id: 'D-06', summary: 'fixed', probe: 'byte', status: 'closed', detail: '' },
],
}],
};
const text = render(result);
assert.match(text, /\[open · phrase probe\] D-01/);
assert.match(text, /closed: D-06/);
assert.match(text, /registry integrity: VIOLATED/);
assert.match(text, /D-02 removed from the registry/);
});
// --- CLI -------------------------------------------------------------------
function writeGateFiles(dir, reg, frozen = frozenFor(reg)) {
mkdirSync(join(dir, 'scripts'), { recursive: true });
writeFileSync(join(dir, 'scripts', 'end-state-registry.json'), JSON.stringify(reg, null, 2));
mkdirSync(join(dir, 'tests', 'fixtures'), { recursive: true });
writeFileSync(join(dir, 'tests', 'fixtures', 'end-state-frozen.json'), JSON.stringify(frozen, null, 2));
}
function runGate(dir, extra = []) {
return spawnSync(process.execPath, [GATE, '--root', dir, ...extra], { encoding: 'utf8' });
}
const ALL_IDS = ['defects', 'experiments', 'dormant-agents', 'decisions', 'feat-after-freeze'];
test('CLI: all five tallies at 0 with an intact registry → green, exit 0; --json carries the rows', () => {
const dir = fixture({
'STATE.md': '## Open decisions\n- [x] done\n',
'agents/a.md': '---\nname: a\n---\n',
'commands/r.md': 'Spawn `a`\n',
});
try {
writeGateFiles(dir, registry());
gitInit(dir);
git(dir, 'tag', 'end-state-freeze');
const r = runGate(dir, ['--json']);
assert.equal(r.status, 0, r.stdout + r.stderr);
const out = JSON.parse(r.stdout);
assert.equal(out.green, true);
assert.equal(out.integrity.ok, true);
assert.deepEqual(out.rows.map((x) => x.id), ALL_IDS);
assert.ok(out.rows.every((x) => x.open === 0 && x.target === 0 && typeof x.source === 'string'));
} finally { cleanup(dir); }
});
test('CLI: an intact registry with every measurable tally at 0 but no freeze tag → red, exit 1', () => {
// n/a must never be read as 0 — also when nothing else is wrong.
const dir = fixture({
'STATE.md': '## Open decisions\n- [x] done\n',
'agents/a.md': '---\nname: a\n---\n',
'commands/r.md': 'Spawn `a`\n',
});
try {
writeGateFiles(dir, registry());
gitInit(dir);
const r = runGate(dir, ['--json']);
assert.equal(r.status, 1, r.stdout + r.stderr);
const out = JSON.parse(r.stdout);
assert.equal(out.integrity.ok, true);
assert.equal(out.green, false);
assert.equal(out.rows.find((x) => x.id === 'feat-after-freeze').open, null);
assert.ok(out.rows.filter((x) => x.id !== 'feat-after-freeze').every((x) => x.open === 0));
} finally { cleanup(dir); }
});
test('CLI: all tallies at 0 but a tampered registry → red, exit 1 (the combined green attack)', () => {
const dir = fixture({
'STATE.md': '## Open decisions\n- [x] ticked\n',
'agents/a.md': '---\nname: a\n---\n',
'commands/r.md': 'Spawn `a`\n',
});
try {
const honest = registry({ defects: [{ id: 'D-01', summary: 'a real defect', probe: 'phrase', check: [{ path: 'commands/r.md', pattern: 'Spawn', expect: 'match' }] }] });
const tampered = registry(); // the open defect simply left the ledger
writeGateFiles(dir, tampered, frozenFor(honest));
gitInit(dir);
git(dir, 'tag', 'end-state-freeze');
const r = runGate(dir);
assert.equal(r.status, 1, r.stdout + r.stderr);
assert.match(r.stdout, /RED/);
assert.match(r.stdout, /VIOLATED/);
assert.match(r.stdout, /D-01/);
} finally { cleanup(dir); }
});
test('CLI: any tally > 0 → red, exit 1; the table names every row', () => {
const dir = fixture({
'STATE.md': '## Open decisions\n- [ ] undecided\n',
'agents/a.md': '---\nname: a\n---\n',
'commands/r.md': 'Spawn `a`\n',
});
try {
writeGateFiles(dir, registry());
const r = runGate(dir);
assert.equal(r.status, 1, r.stderr);
for (const label of ALL_IDS) assert.match(r.stdout, new RegExp(label));
assert.match(r.stdout, /RED/);
} finally { cleanup(dir); }
});
test('CLI: an unreadable registry is a usage error (exit 2), not a verdict', () => {
const dir = fixture({ 'STATE.md': '## Open decisions\n' });
try {
const r = runGate(dir);
assert.equal(r.status, 2);
assert.match(r.stderr, /end-state-registry\.json/);
} finally { cleanup(dir); }
});
// --- the real repo: denominator pinned, state never pinned -----------------
test('the frozen denominator: tests/fixtures/end-state-frozen.json is exactly the literal above', () => {
const file = loadFrozen(ROOT);
const { why, ...rest } = file;
assert.ok(typeof why === 'string' && why.length > 20, 'the manifest says why it is frozen');
assert.deepEqual(rest, FROZEN);
});
test('the frozen denominator: the real registry is intact against it', () => {
const v = verifyIntegrity(loadRegistry(ROOT), FROZEN);
assert.deepEqual(v, { ok: true, violations: [] }, v.violations.join('\n'));
});
test('real registry: every counted entry has an id, a summary, a probe kind and a check that RUNS here', () => {
const reg = loadRegistry(ROOT);
const entries = [...reg.defects, ...reg.experiments];
const ids = new Set();
for (const e of entries) {
assert.match(e.id, /^[DE]-\d{2}$/, `bad id ${e.id}`);
assert.ok(!ids.has(e.id), `duplicate id ${e.id}`);
ids.add(e.id);
assert.ok(typeof e.summary === 'string' && e.summary.length > 10, `${e.id} needs a summary`);
assert.ok(Object.keys(PROBE_NOTES).includes(e.probe), `${e.id} must declare a probe kind the gate can explain`);
// A check that cannot evaluate against this very repo is a typo, not a finding.
assert.notEqual(evaluateCheck(ROOT, e.check).status, 'not-fellable', `${e.id} check does not run here`);
}
});
test('real repo: five rows, open is a count or null, exit code agrees with rows + integrity', () => {
const r = spawnSync(process.execPath, [GATE, '--json'], { encoding: 'utf8', cwd: ROOT });
assert.ok(r.status === 0 || r.status === 1, r.stderr);
const out = JSON.parse(r.stdout);
assert.deepEqual(out.rows.map((x) => x.id), ALL_IDS);
for (const row of out.rows) {
assert.ok(row.open === null || (Number.isInteger(row.open) && row.open >= 0), `${row.id}: ${row.open}`);
}
const green = out.rows.every((row) => row.open === 0) && out.integrity.ok === true;
assert.equal(out.green, green);
assert.equal(r.status, green ? 0 : 1);
assert.ok(existsSync(join(ROOT, 'scripts', 'end-state-registry.json')));
assert.ok(readFileSync(join(ROOT, 'tests', 'fixtures', 'end-state-frozen.json'), 'utf8').length > 0);
});
// --- probe labelling -------------------------------------------------------
//
// The gate labelled only `phrase` probes, so every other probe kind rendered
// unlabelled — indistinguishable from an entry that declared nothing. Once
// D-03/D-04 became behaviour probes (operator decision 2026-09-18) the reader
// needs to see WHICH kind of evidence each closed entry rests on.
test('PROBE_NOTES: every probe kind the registry may declare carries a note', () => {
assert.deepEqual(Object.keys(PROBE_NOTES).sort(), ['behaviour', 'byte', 'phrase']);
for (const [kind, note] of Object.entries(PROBE_NOTES)) {
assert.ok(note.length > 20, `${kind} needs a note that says what the probe can and cannot prove`);
}
});
test('render: every probe kind is labelled, open and closed — not just phrase', () => {
const text = render({
green: false,
integrity: { ok: true, violations: [], detail: '' },
rows: [{
id: 'defects', label: 'open pipeline defects', source: 's', open: 2, total: 3, target: 0, detail: '',
items: [
{ id: 'D-01', summary: 'still open', probe: 'phrase', status: 'open', detail: '' },
{ id: 'D-03', summary: 'still open', probe: 'behaviour', status: 'open', detail: '' },
{ id: 'D-06', summary: 'fixed', probe: 'byte', status: 'closed', detail: '' },
],
}],
});
assert.match(text, /\[open · phrase probe\] D-01/);
assert.match(text, /\[open · behaviour probe\] D-03/);
assert.match(text, /closed: D-06 \(byte probe\)/);
});
test('the detail line carries one note per probe kind PRESENT, and none for kinds absent', () => {
const dir = fixture({
'a.md': 'bad\n',
'STATE.md': '## Open decisions\n- [x] done\n',
'agents/a.md': '---\nname: a\n---\n',
'commands/r.md': 'Spawn `a`\n',
});
try {
writeGateFiles(dir, registry({
defects: [
{ id: 'D-01', summary: 'a phrase defect', probe: 'phrase', check: [{ path: 'a.md', pattern: 'bad', expect: 'match' }] },
{ id: 'D-02', summary: 'a behaviour defect', probe: 'behaviour', check: [{ path: 'a.md', pattern: 'nope', expect: 'match' }] },
],
}));
gitInit(dir);
const out = JSON.parse(runGate(dir, ['--json']).stdout);
const detail = rowById(out, 'defects').detail;
assert.match(detail, /phrase probe closes on rewording/);
assert.match(detail, /behaviour probe/);
assert.ok(!/byte probe/.test(detail), 'a kind no entry declares must not be explained');
assert.equal(rowById(out, 'experiments').detail, '', 'an empty row explains nothing');
} finally { cleanup(dir); }
});
// --- a probe that RUNS a test, and the M6 mutant ---------------------------
//
// Measured 2026-09-18 (re-measured on 6cafb4c): a two-line file
// export function runPlanVerification() { return { ok: true }; }
// export function formatCriteriaEvidence() { return ''; }
// dropped into an otherwise UNFIXED tree closed both D-03 and D-04, and the
// gate reported "defects 0 of 7, registry intact". A grep condition can only
// ask whether a string is present, so a behaviour probe built from one is a
// phrase probe pointed at code. A condition that RUNS a named test and reads
// its TAP result cannot be closed that way.
const M6_STUB = [
'export function runPlanVerification() { return { ok: true }; }',
"export function formatCriteriaEvidence() { return ''; }",
'',
].join('\n');
// A fixture pair: a module, and a test that BINDS it. `green one` passes on
// the tree and fails against a stub of the module - which is what makes it a
// behaviour probe rather than a name.
const MODULE = 'export function answer() { return 42; }\n';
const TEST_FILE = [
"import { test } from 'node:test';",
"import { strict as assert } from 'node:assert';",
"import { answer } from '../lib/m.mjs';",
"test('green one', () => { assert.equal(answer(), 42); });",
"test('red one', () => { assert.ok(false, 'red on purpose'); });",
'',
].join('\n');
test('a test condition RUNS the named test and reads its result', () => {
const dir = fixture({ 'tests/t.test.mjs': TEST_FILE, 'lib/m.mjs': MODULE });
try {
const cond = (name, expect) => ({ test: 'tests/t.test.mjs', name, expect, stubs: ['lib/m.mjs'] });
assert.equal(evaluateCondition(dir, cond('green one', 'passes')), true);
assert.equal(evaluateCondition(dir, cond('green one', 'fails')), false);
assert.equal(evaluateCondition(dir, cond('red one', 'passes')), false);
assert.equal(evaluateCondition(dir, cond('red one', 'fails')), true);
} finally { cleanup(dir); }
});
test('a test condition naming a test that does not run is NOT FELLABLE, never closed', () => {
const dir = fixture({ 'tests/t.test.mjs': TEST_FILE, 'lib/m.mjs': MODULE });
try {
for (const cond of [
{ test: 'tests/t.test.mjs', name: 'no such test', expect: 'fails', stubs: ['lib/m.mjs'] },
{ test: 'tests/missing.test.mjs', name: 'green one', expect: 'fails', stubs: ['lib/m.mjs'] },
]) {
const r = evaluateCheck(dir, [cond]);
assert.equal(r.status, 'not-fellable', JSON.stringify(cond));
assert.ok(r.detail.length > 0, 'the gate must say WHY the check could not fire');
}
} finally { cleanup(dir); }
});
test('M6 mutant: a stub exporting both symbols does NOT close D-03 or D-04', () => {
const dir = fixture({ 'lib/cosmetic/stub.mjs': M6_STUB });
try {
const entries = loadRegistry(ROOT).defects.filter((e) => e.id === 'D-03' || e.id === 'D-04');
assert.equal(entries.length, 2, 'D-03 and D-04 are still in the registry');
for (const e of entries) {
assert.notEqual(
evaluateCheck(dir, e.check).status, 'closed',
`${e.id} closed on a tree where nothing is fixed: ${JSON.stringify(e.check)}`,
);
}
} finally { cleanup(dir); }
});
test('the gate states out loud that the wiring is pinned by text, not proven', () => {
const r = spawnSync(process.execPath, [GATE], { encoding: 'utf8', cwd: ROOT });
assert.ok(r.status === 0 || r.status === 1, r.stderr);
assert.match(r.stdout, /wiring: /);
assert.match(r.stdout, /pinned by TEXT/);
assert.match(r.stdout, /plugin-eval/);
});
// --- M7: a probe must bind the test's CONTENT, not its name ---------------
//
// Measured 2026-09-18 (re-measured on e1e7bdf): the cosmetic close came back
// one level up. The probe reads the test file from the SAME tree it measures,
// so a four-line file holding two EMPTY tests with the two named names —
// test('runPlanVerification: a plan whose success criterion FAILS fells the run', () => {});
// test('formatCriteriaEvidence: one row per criterion, with command and exit code', () => {});
// — closed D-03 and D-04 on a tree where `lib/verification/` did not exist at
// all: "defects 0 of 7, registry intact". An empty test is the new two-line
// stub. The only form that cannot be closed by a name is one that requires the
// named test to FELL a mutant: the gate runs it a second time against a tree
// where the module it binds is replaced by a stub exporting the same names and
// doing nothing. A test that passes against both is not a behaviour probe.
const EMPTY_NAMED_TESTS = [
"import test from 'node:test';",
"test('runPlanVerification: a plan whose success criterion FAILS fells the run', () => {});",
"test('formatCriteriaEvidence: one row per criterion, with command and exit code', () => {});",
'',
].join('\n');
const REAL_RUNNER = join(ROOT, 'lib', 'verification', 'criteria-runner.mjs');
const REAL_RUNNER_TEST = join(ROOT, 'tests', 'lib', 'criteria-runner.test.mjs');
test('M7 mutant: two EMPTY tests with the right names do NOT close D-03 or D-04', () => {
// The checkpoint's reproduction: an unfixed tree (no lib/verification/) plus
// the four-line test file.
const dir = fixture({ 'tests/lib/criteria-runner.test.mjs': EMPTY_NAMED_TESTS });
try {
const entries = loadRegistry(ROOT).defects.filter((e) => e.id === 'D-03' || e.id === 'D-04');
assert.equal(entries.length, 2, 'D-03 and D-04 are still in the registry');
for (const e of entries) {
const r = evaluateCheck(dir, e.check);
assert.equal(r.status, 'not-fellable', `${e.id} closed on a tree where nothing is fixed`);
assert.ok(r.detail.length > 0, 'the gate must say WHY the check could not fire');
}
} finally { cleanup(dir); }
});
test('M7 mutant: an empty named test does not close the defect even when the module IS present', () => {
// The harder case: the real module is there, so the stub CAN be built — and
// the empty test passes against it, which is exactly the proof that the test
// binds the name and nothing else.
const dir = fixture({
'tests/lib/criteria-runner.test.mjs': EMPTY_NAMED_TESTS,
'lib/verification/criteria-runner.mjs': readFileSync(REAL_RUNNER, 'utf8'),
});
try {
for (const e of loadRegistry(ROOT).defects.filter((x) => x.id === 'D-03' || x.id === 'D-04')) {
const r = evaluateCheck(dir, e.check);
assert.equal(r.status, 'not-fellable', `${e.id} closed on an empty test`);
assert.match(r.detail, /stub/i, 'the gate must name the mutant the test failed to fell');
}
} finally { cleanup(dir); }
});
test("D-03/D-04 still CLOSE on the real tree — the named tests do fell a stub", () => {
// The positive control. Without it, "not closed" everywhere would read as a
// working probe when the probe is simply broken.
for (const e of loadRegistry(ROOT).defects.filter((x) => x.id === 'D-03' || x.id === 'D-04')) {
const r = evaluateCheck(ROOT, e.check);
assert.equal(r.status, 'closed', `${e.id} is not closed on the real tree: ${r.detail}`);
}
});
test('a test condition must name the module its test binds, or it cannot fire', () => {
const dir = fixture({ 'tests/t.test.mjs': TEST_FILE, 'lib/m.mjs': MODULE });
try {
for (const cond of [
{ test: 'tests/t.test.mjs', name: 'green one', expect: 'passes' },
{ test: 'tests/t.test.mjs', name: 'green one', expect: 'passes', stubs: [] },
{ test: 'tests/t.test.mjs', name: 'green one', expect: 'passes', stubs: ['lib/gone.mjs'] },
]) {
const r = evaluateCheck(dir, [cond]);
assert.equal(r.status, 'not-fellable', JSON.stringify(cond));
assert.ok(r.detail.length > 0, 'the gate must say WHY');
}
} finally { cleanup(dir); }
});
test('the stub mutant leaves the measured tree untouched', () => {
const dir = fixture({ 'tests/t.test.mjs': TEST_FILE, 'lib/m.mjs': MODULE });
try {
const before = readFileSync(join(dir, 'lib', 'm.mjs'), 'utf8');
evaluateCheck(dir, [{ test: 'tests/t.test.mjs', name: 'green one', expect: 'passes', stubs: ['lib/m.mjs'] }]);
assert.equal(readFileSync(join(dir, 'lib', 'm.mjs'), 'utf8'), before, 'the mutation must happen in a copy, never in place');
} finally { cleanup(dir); }
});
test('the frozen file claims no authority it does not have', () => {
// Measured the same day: the tracked frozen file claimed its second
// amendment was operator-authorised. No operator authorised it; it followed
// from a maintenance decision. A file whose whole job is to be an explicit
// decision trail may not overclaim in either direction.
const why = loadFrozen(ROOT).why;
assert.ok(why.length > 0, 'the frozen manifest must say WHY it changed');
assert.ok(
!/operator-authoris|operator-authoriz|by work order|PM checkpoint/i.test(why),
'the frozen file may not claim operator authorisation, and coordination metadata belongs in the local plan',
);
});

View file

@ -13,7 +13,7 @@
// - a stats file with no `effort` field is a loud error, never a silently
// empty group that reads as "no gain".
//
// Pattern: tests/scripts/synthesis-measure.test.mjs (pure core, no fixtures on disk).
// Pure core, no fixtures on disk.
import { test } from 'node:test';
import { strict as assert } from 'node:assert';
@ -248,7 +248,7 @@ test('decideVerdict: a null gain is insufficient data, never a decline', () => {
// appends; nothing read it.
//
// The stats record carries counts, not names — names are free prose and
// field-allowlist.mjs denies prose by omission — so the run attests membership
// the record denies prose by omission — so the run attests membership
// with a low-cardinality boolean instead, and the gate refuses to call
// activation OK without it.
// ---------------------------------------------------------------------------

View file

@ -1,101 +0,0 @@
// tests/scripts/synthesis-measure.test.mjs
// NW3 (S12) — deterministic Δ main-context measurement core.
//
// The gate metric (T1 §2) is Δ main-context tokens for an equivalent-quality
// digest. This pins the pure accounting that turns fixture token counts into a
// verdict, under the two framings that decide NW3:
//
// - FAITHFUL (current flow): Phase 5 swarm runs FOREGROUND, so its outputs are
// already RESIDENT in main before Phase 7. Delegating only the synthesis read
// cannot evict them → main holds base+out+dig in BOTH arms → Δ ≈ 0.
// - DISK-POTENTIAL (upper bound): IF outputs were on disk (a separate Phase-5
// change, out of NW3 scope), the delegated arm holds base+dig only → Δ = out/(base+out+dig).
//
// POSITIVE adopt requires Δ ≥ 30% AND quality ≥ inline (T1 §5 thresholds).
import { test } from 'node:test';
import { strict as assert } from 'node:assert';
import {
estimateTokens,
mainContextTokens,
deltaPct,
decideVerdict,
analyze,
} from '../../scripts/synthesis-measure.mjs';
test('estimateTokens: ~chars/4 heuristic, monotonic, non-negative', () => {
assert.equal(estimateTokens(''), 0);
assert.equal(estimateTokens('abcd'), 1);
assert.equal(estimateTokens('abcde'), 2); // ceil(5/4)
assert.ok(estimateTokens('a'.repeat(400)) === 100);
assert.ok(estimateTokens('x'.repeat(1000)) > estimateTokens('x'.repeat(500)));
});
test('mainContextTokens: inline arm holds base + out + dig', () => {
assert.equal(mainContextTokens({ base: 50000, out: 12000, dig: 1500, arm: 'inline' }), 63500);
});
test('mainContextTokens: delegated_faithful still holds out (Phase-5 resident) + dig', () => {
// The decisive structural fact: foreground swarm delivery already made `out`
// resident; delegating Phase 7 does not evict it.
assert.equal(
mainContextTokens({ base: 50000, out: 12000, dig: 1500, arm: 'delegated_faithful' }),
63500,
);
});
test('mainContextTokens: delegated_disk holds base + dig only (out lives in the sub-agent)', () => {
assert.equal(
mainContextTokens({ base: 50000, out: 12000, dig: 1500, arm: 'delegated_disk' }),
51500,
);
});
test('mainContextTokens: unknown arm throws (no silent default)', () => {
assert.throws(() => mainContextTokens({ base: 1, out: 1, dig: 1, arm: 'nope' }));
});
test('deltaPct: (A-B)/A; equal arms → 0; B smaller → positive fraction', () => {
assert.equal(deltaPct(100, 100), 0);
assert.equal(deltaPct(100, 75), 0.25);
assert.equal(deltaPct(0, 0), 0); // guard divide-by-zero
});
test('decideVerdict: ≥30% AND quality-ok → POSITIVE', () => {
assert.equal(decideVerdict(0.30, true), 'POSITIVE');
assert.equal(decideVerdict(0.45, true), 'POSITIVE');
});
test('decideVerdict: quality loss forces NEGATIVE even at a large Δ', () => {
assert.equal(decideVerdict(0.60, false), 'NEGATIVE');
});
test('decideVerdict: <15% → NEGATIVE; the [15%,30%) band → INCONCLUSIVE', () => {
assert.equal(decideVerdict(0.149, true), 'NEGATIVE');
assert.equal(decideVerdict(0.00, true), 'NEGATIVE');
assert.equal(decideVerdict(0.15, true), 'INCONCLUSIVE');
assert.equal(decideVerdict(0.2999, true), 'INCONCLUSIVE');
});
test('analyze: faithful arm is structurally Δ=0 → NEGATIVE regardless of sizes', () => {
const a = analyze({ baseTokens: 50000, outTokens: 12000, digTokens: 1500, qualityOK: true });
assert.equal(a.faithful.deltaPct, 0);
assert.equal(a.faithful.verdict, 'NEGATIVE');
assert.equal(a.faithful.armA, a.faithful.armB);
});
test('analyze: disk arm Δ = out/(base+out+dig)', () => {
const a = analyze({ baseTokens: 50000, outTokens: 12000, digTokens: 1500, qualityOK: true });
const expected = 12000 / (50000 + 12000 + 1500);
assert.ok(Math.abs(a.disk.deltaPct - expected) < 1e-9);
assert.equal(a.disk.armB, 51500);
});
test('analyze: disk verdict tracks BASE — large fixed baseline can sink the upper bound below 30%', () => {
// Small base → disk Δ clears 30%; large base → it does not. Demonstrates the
// upper bound is itself BASE-sensitive (sweep, do not assert one number).
const small = analyze({ baseTokens: 10000, outTokens: 12000, digTokens: 1500, qualityOK: true });
const large = analyze({ baseTokens: 200000, outTokens: 12000, digTokens: 1500, qualityOK: true });
assert.equal(small.disk.verdict, 'POSITIVE'); // 12000/23500 ≈ 0.51
assert.equal(large.disk.verdict, 'NEGATIVE'); // 12000/213500 ≈ 0.056
});

View file

@ -1,660 +0,0 @@
// tests/scripts/yardstick.test.mjs
// The yardstick prints Voyage's three numbers (use · trust · interrupts) with
// denominators read from their SOURCE, plus a fourth row that asks whether the
// end-state gate itself can be fooled by a signature-preserving mutant.
//
// Like the gate's own test, these tests pin the MECHANICS in both directions
// against throwaway fixtures - every number can be countable and can be not
// countable, the mutant row can read felled and not felled. They deliberately
// do NOT assert that the real data is red today: the yardstick is supposed to
// turn green, and a test that pins today's distance would fail on the day the
// work is done. Nothing here reads the real order queue or the real stats.
import { test } from 'node:test';
import { strict as assert } from 'node:assert';
import { mkdtempSync, mkdirSync, writeFileSync, rmSync, readFileSync, symlinkSync } from 'node:fs';
import { spawnSync } from 'node:child_process';
import { tmpdir } from 'node:os';
import { join, dirname, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
import {
DEFAULT_CUTOFF,
MARKER_SINCE,
loadStats,
readOrders,
measureUse,
measureTrust,
measureInterrupts,
emitterCallSites,
buildM9Tree,
measureMutants,
measureAll,
render,
main,
} from '../../scripts/yardstick.mjs';
// New exports are read through the namespace, so a missing one fails its own
// tests instead of failing this whole file at link time.
import * as Y from '../../scripts/yardstick.mjs';
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..', '..');
// --- helpers ---------------------------------------------------------------
function fixture(files) {
const dir = mkdtempSync(join(tmpdir(), 'yardstick-'));
for (const [rel, body] of Object.entries(files)) {
const p = join(dir, rel);
mkdirSync(dirname(p), { recursive: true });
writeFileSync(p, body);
}
return dir;
}
const cleanup = (...dirs) => { for (const d of dirs) rmSync(d, { recursive: true, force: true }); };
const jsonl = (...rows) => `${rows.map((r) => (typeof r === 'string' ? r : JSON.stringify(r))).join('\n')}\n`;
// `marker` writes the order's solution-choice marker the way dispatch does: an
// HTML comment on its own line in the body, `<!-- loesningsvalg: <value>; grunn=... -->`.
// `arbeidsform` writes `<!-- arbeidsform: <value> -->` on its own line, as dispatch does.
function order({ id, date, workClass, slug, marker, arbeidsform, extra = '' }) {
const lines = ['---', 'from: .claude', 'to: some-repo', `order-id: ${id}`, `subject: order ${id}`, `date: ${date}`];
if (workClass !== undefined) lines.push(`work-class: ${workClass}`);
if (slug !== undefined) lines.push(`slug: ${slug}`);
lines.push('---');
if (arbeidsform !== undefined) lines.push(`<!-- arbeidsform: ${arbeidsform} -->`);
if (marker !== undefined) lines.push(`<!-- loesningsvalg: ${marker}; grunn=fixture -->`);
lines.push('', `# ORDER ${id}`, extra, '');
return lines.join('\n');
}
const review = (ts, verdict, slug = 's') => ({ ts, slug, verdict });
// A /trekbrief stats record naming the order it ran (the writer adds order_*).
const briefRun = ({ order_id, slug = 's', ts = '2026-10-04T10:00:00Z' }) => ({ ts, slug, order_id, order_claimed_at: ts, order_reason: order_id ? null : 'none-claimed' });
// The runs index the yardstick joins on, built from stats files `{ name: [records] }`.
function runsFrom(files = {}) {
const dir = fixture(Object.fromEntries(Object.entries(files).map(([n, recs]) => [n, jsonl(...recs)])));
try { return Y.orderRuns(loadStats(dir)); } finally { cleanup(dir); }
}
const runsOf = (...records) => runsFrom(records.length ? { 'trekbrief-stats.jsonl': records } : {});
// measureUse over a fixture queue; counting starts at MARKER_SINCE unless the test says otherwise.
function use(files, { records = [], runs, cutoff = DEFAULT_CUTOFF, countingSince = MARKER_SINCE } = {}) {
const coord = fixture(files);
try {
return measureUse({ queue: readOrders(coord), runs: runs ?? runsOf(...records), cutoff, countingSince });
} finally { cleanup(coord); }
}
// --- the stats loader --------------------------------------------------------
test('loadStats: an invalid JSON line is COUNTED, never silently dropped', () => {
const dir = fixture({
'trekreview-stats.jsonl': jsonl(review('2026-09-01T00:00:00Z', 'ALLOW'), '{not json', '', review('2026-09-02T00:00:00Z', 'BLOCK')),
});
try {
const stats = loadStats(dir);
const f = stats.files.find((x) => x.name === 'trekreview-stats.jsonl');
assert.equal(f.lines, 3, 'blank lines are not lines; the invalid one is');
assert.equal(f.records.length, 2);
assert.deepEqual(f.invalid, [2], 'the invalid line is reported by its line number');
} finally { cleanup(dir); }
});
test('loadStats: a missing data directory is reported, not read as zero', () => {
const stats = loadStats(join(tmpdir(), 'yardstick-no-such-dir-8f3a'));
assert.equal(stats.missing, true);
assert.deepEqual(stats.files, []);
});
// --- 2 · TRUST ---------------------------------------------------------------
test('trust: the ALLOW streak is read in ts order, not file order', () => {
// File order ends on ALLOW, ALLOW; chronologically the last review is a BLOCK.
const dir = fixture({
'trekreview-stats.jsonl': jsonl(
review('2026-09-01T00:00:00Z', 'ALLOW'),
review('2026-09-05T00:00:00Z', 'BLOCK'),
review('2026-09-02T00:00:00Z', 'ALLOW'),
review('2026-09-03T00:00:00Z', 'ALLOW'),
),
});
try {
const row = measureTrust(loadStats(dir));
assert.equal(row.countable, true);
assert.equal(row.denominator, 4);
assert.equal(row.value, 0, 'the chronologically last review is a BLOCK');
assert.equal(row.facts.longestStreak, 3);
assert.deepEqual(row.facts.verdicts, { ALLOW: 3, BLOCK: 1 });
assert.equal(row.facts.last.verdict, 'BLOCK');
} finally { cleanup(dir); }
});
test('trust: both spacings of the verdict field count the same (it is read as JSON, not grepped)', () => {
const dir = fixture({
'trekreview-stats.jsonl': jsonl(
'{"ts": "2026-09-01T00:00:00Z", "slug": "a", "verdict": "BLOCK"}',
'{"ts":"2026-09-02T00:00:00Z","slug":"b","verdict":"ALLOW"}',
),
});
try {
const row = measureTrust(loadStats(dir));
assert.deepEqual(row.facts.verdicts, { BLOCK: 1, ALLOW: 1 });
assert.equal(row.value, 1);
} finally { cleanup(dir); }
});
test('trust: an invalid line is left out of n and said out loud', () => {
const dir = fixture({
'trekreview-stats.jsonl': jsonl(review('2026-09-01T00:00:00Z', 'ALLOW'), '{"ts": oops'),
});
try {
const row = measureTrust(loadStats(dir));
assert.equal(row.denominator, 1);
assert.equal(row.facts.invalid, 1);
assert.match(row.detail, /1 invalid line/);
} finally { cleanup(dir); }
});
test('trust: an empty or missing review file is NOT countable', () => {
const empty = fixture({ 'trekreview-stats.jsonl': '' });
const none = fixture({ 'trekplan-stats.jsonl': jsonl({ ts: '2026-09-01T00:00:00Z', slug: 'x' }) });
try {
for (const dir of [empty, none]) {
const row = measureTrust(loadStats(dir));
assert.equal(row.countable, false, dir);
assert.equal(row.value, null);
assert.ok(row.detail.length > 0, 'the row must say WHY it cannot be counted');
}
} finally { cleanup(empty, none); }
});
// --- 1 · USE -----------------------------------------------------------------
test('use: orders are read from orders/, archive/ and claimed/, and nothing else', () => {
const coord = fixture({
'repo-a/orders/o1.md': order({ id: 'o1', date: '2026-09-22T10:00:00Z' }),
'repo-a/orders/archive/o2.md': order({ id: 'o2', date: '2026-09-01T10:00:00Z' }),
'repo-b/orders/claimed/o3.md': order({ id: 'o3', date: '2026-09-22T10:00:00Z' }),
'repo-b/orders/claimed/o3.claim': 'claimed',
'repo-b/inbox/m1.md': order({ id: 'm1', date: '2026-09-22T10:00:00Z' }),
'repo-b/orders/broken.md': 'no frontmatter at all\n',
});
try {
const q = readOrders(coord);
assert.equal(q.files, 4, 'three orders and one unreadable file, all .md under */orders/');
assert.equal(q.orders.length, 3);
assert.equal(q.unreadable.length, 1);
} finally { cleanup(coord); }
});
test('use: a dot-mailbox is a mailbox - its orders count, and the detail names it', () => {
// Measured 2026-09-22: a hand count over `coord/*/orders` came out lower than
// the yardstick, because the shell's `*` skips dot-directories and the queue
// does not. The detail names them, so the next re-measure can reconcile.
const coord = fixture({
'r/orders/o1.md': order({ id: 'o1', date: '2026-09-22T10:00:00Z' }),
'.pm/orders/archive/o2.md': order({ id: 'o2', date: '2026-09-22T10:00:00Z' }),
});
try {
const q = readOrders(coord);
assert.equal(q.orders.length, 2);
const row = measureUse({ queue: q, runs: runsOf(), cutoff: DEFAULT_CUTOFF, countingSince: MARKER_SINCE });
assert.match(row.detail, /2 order files in 2 mailboxes/);
assert.match(row.detail, /dot-mailboxes .pm 1/);
} finally { cleanup(coord); }
});
test('use: the marker is counted from 2026-09-28, the day pre-order-loesningsvalg.sh began enforcing it', () => {
assert.equal(MARKER_SINCE, '2026-09-28');
});
test('use: no order carrying a loesningsvalg marker means NOT COUNTABLE, not 0 %', () => {
const row = use({
'r/orders/o1.md': order({ id: 'o1', date: '2026-09-29T10:00:00Z' }),
'r/orders/o2.md': order({ id: 'o2', date: '2026-09-30T10:00:00Z' }),
});
assert.equal(row.countable, false);
assert.equal(row.value, null);
assert.equal(row.denominator, 0);
assert.equal(row.facts.scanned, 2);
assert.equal(row.facts.withMarker, 0);
assert.equal(row.facts.notMeasured, 2, 'an unmarked order is not measured - never a no');
assert.match(row.detail, /0 of 2 orders carry a loesningsvalg marker/);
assert.match(row.detail, /2 not measured/);
});
test('use: plan and prove are NEW work, ikke-nytt is not; unmarked and pre-2026-09-28 orders are not measured', () => {
const row = use({
'r/orders/plan.md': order({ id: 'plan', date: '2026-09-28T00:00:00Z', marker: 'plan' }),
'r/orders/archive/prove.md': order({ id: 'prove', date: '2026-10-01T00:00:00Z', marker: 'prove' }),
'r/orders/claimed/ikke.md': order({ id: 'ikke', date: '2026-10-01T00:00:00Z', marker: 'ikke-nytt' }),
'r/orders/none.md': order({ id: 'none', date: '2026-10-01T00:00:00Z' }),
'r/orders/early.md': order({ id: 'early', date: '2026-09-27T23:59:59Z', marker: 'plan' }),
}, { records: [briefRun({ order_id: 'plan' }), briefRun({ order_id: 'ikke', slug: 'other' }), briefRun({ order_id: 'early', slug: 'old' })] });
assert.equal(row.facts.newWork, 2, 'plan and prove');
assert.equal(row.facts.notNew, 1);
assert.equal(row.facts.beforeMarker, 1);
assert.equal(row.facts.unmarked, 1);
assert.equal(row.facts.withVoyageRun, 1, 'plan has a trekbrief record naming it');
assert.equal(row.facts.noRecord, 1, 'prove has none - not measured, never a no');
assert.equal(row.countable, true);
assert.equal(row.value, 1);
assert.equal(row.denominator, 1, 'YES + declared NO; prove is not measured');
assert.equal(row.facts.notMeasured, 3, 'unmarked, before 2026-09-28, and prove without a record');
assert.match(row.detail, /value = 1 of 1 measured/);
});
test('use: work-class in the frontmatter no longer decides anything - only the marker does', () => {
const row = use({
'r/orders/a.md': order({ id: 'a', date: '2026-09-29T00:00:00Z', workClass: 'new' }),
'r/orders/b.md': order({ id: 'b', date: '2026-09-29T00:00:00Z', workClass: 'maintenance', marker: 'prove' }),
}, { records: [briefRun({ order_id: 'a' }), briefRun({ order_id: 'b', slug: 'b' })] });
assert.equal(row.facts.newWork, 1, 'b is new by its marker; a has no marker and is not measured');
assert.equal(row.value, 1);
assert.equal(row.denominator, 1);
assert.equal(row.facts.notMeasured, 1);
});
test('use: only a marker on its own line counts - a mention in prose or an unknown value is not measured', () => {
const row = use({
'r/orders/prose.md': order({ id: 'prose', date: '2026-09-29T00:00:00Z', extra: 'Count from the marker `<!-- loesningsvalg: plan -->` in the body.' }),
'r/orders/odd.md': order({ id: 'odd', date: '2026-09-29T00:00:00Z', marker: 'kanskje' }),
'r/orders/both.md': order({ id: 'both', date: '2026-09-29T00:00:00Z', marker: 'ikke-nytt', extra: 'Prose names `<!-- loesningsvalg: plan -->` too.' }),
});
assert.equal(row.denominator, 0);
assert.equal(row.facts.notNew, 1, 'both: the line marker wins over the prose mention');
assert.equal(row.facts.notMeasured, 2, 'prose has no marker; kanskje is no known value');
assert.equal(row.countable, false);
});
test('use: a cutoff later than 2026-09-28 moves the start of the count', () => {
const row = use({
'r/orders/a.md': order({ id: 'a', date: '2026-09-29T00:00:00Z', marker: 'plan' }),
'r/orders/b.md': order({ id: 'b', date: '2026-10-02T00:00:00Z', marker: 'plan' }),
}, { cutoff: '2026-10-01', records: [briefRun({ order_id: 'a' }), briefRun({ order_id: 'b', slug: 'b' })] });
assert.equal(row.facts.newWork, 1);
assert.equal(row.facts.beforeMarker, 1);
assert.equal(row.value, 1, 'b only');
assert.match(row.source, /from 2026-10-01/);
});
// --- use: the order-id join (source C) -------------------------------------------
test('use: a new-work order is YES only when a trekbrief record names its order id', () => {
const row = use({ 'r/orders/o.md': order({ id: 'o', date: '2026-09-29T00:00:00Z', marker: 'plan' }) },
{ records: [briefRun({ order_id: 'o' })] });
assert.equal(row.countable, true);
assert.equal(row.value, 1);
assert.equal(row.denominator, 1);
assert.equal(row.facts.withVoyageRun, 1);
assert.deepEqual(row.facts.matched, ['o']);
});
test('use: no record, or a record naming another id, is NOT MEASURED - never a no', () => {
const row = use({ 'r/orders/a.md': order({ id: 'a', date: '2026-09-29T00:00:00Z', marker: 'plan' }) },
{ records: [briefRun({ order_id: 'zzz' })] });
assert.equal(row.facts.noRecord, 1);
assert.equal(row.facts.withVoyageRun, 0);
assert.equal(row.countable, false);
assert.equal(row.value, null);
assert.equal(row.denominator, 0);
assert.equal(row.facts.notMeasured, 1);
});
test('use: an equal slug alone no longer matches - only the order id does', () => {
const row = use({ 'r/orders/a.md': order({ id: 'a', date: '2026-09-29T00:00:00Z', marker: 'plan', slug: 'feat-a' }) },
{ records: [briefRun({ order_id: null, slug: 'feat-a' }), briefRun({ order_id: 'other', slug: 'feat-a' })] });
assert.equal(row.facts.withVoyageRun, 0);
assert.equal(row.facts.noRecord, 1);
});
test('use: an order id in another stats file does not count - only /trekbrief records the order', () => {
const row = use({ 'r/orders/a.md': order({ id: 'a', date: '2026-09-29T00:00:00Z', marker: 'plan' }) },
{ runs: runsFrom({ 'trekplan-stats.jsonl': [{ ts: 't', slug: 's', order_id: 'a' }] }) });
assert.equal(row.facts.withVoyageRun, 0);
assert.equal(row.facts.noRecord, 1);
});
test('use: two records with the same id and slug count once; the same id under two slugs is disputed', () => {
const once = use({ 'r/orders/a.md': order({ id: 'a', date: '2026-09-29T00:00:00Z', marker: 'plan' }) },
{ records: [briefRun({ order_id: 'a' }), briefRun({ order_id: 'a', ts: '2026-10-05T00:00:00Z' })] });
assert.equal(once.value, 1);
assert.equal(once.denominator, 1);
const two = use({ 'r/orders/a.md': order({ id: 'a', date: '2026-09-29T00:00:00Z', marker: 'plan' }) },
{ records: [briefRun({ order_id: 'a', slug: 'x' }), briefRun({ order_id: 'a', slug: 'y' })] });
assert.equal(two.facts.disputed, 1);
assert.equal(two.facts.withVoyageRun, 0);
assert.equal(two.countable, false, 'a disputed order is not measured');
});
test('use: one slug naming two order ids makes both disputed - a brief cannot run two orders', () => {
const row = use({
'r/orders/a.md': order({ id: 'a', date: '2026-09-29T00:00:00Z', marker: 'plan' }),
'r/orders/b.md': order({ id: 'b', date: '2026-09-29T00:00:00Z', marker: 'plan' }),
}, { records: [briefRun({ order_id: 'a', slug: 'one' }), briefRun({ order_id: 'b', slug: 'one' })] });
assert.equal(row.facts.disputed, 2);
assert.equal(row.facts.withVoyageRun, 0);
});
test('use: arbeidsform: ordre is a declared NO even with a record; arbeidsform: voyage with a record is YES', () => {
const row = use({
'r/orders/a.md': order({ id: 'a', date: '2026-09-29T00:00:00Z', marker: 'plan', arbeidsform: 'ordre' }),
'r/orders/b.md': order({ id: 'b', date: '2026-09-29T00:00:00Z', marker: 'plan', arbeidsform: 'voyage' }),
}, { records: [briefRun({ order_id: 'a', slug: 'a' }), briefRun({ order_id: 'b', slug: 'b' })] });
assert.equal(row.facts.declaredNo, 1);
assert.equal(row.facts.withVoyageRun, 1);
assert.deepEqual(row.facts.matched, ['b']);
assert.equal(row.value, 1);
assert.equal(row.denominator, 2);
});
test('use: a veto marker mentioned mid-line in prose does not veto', () => {
const row = use({ 'r/orders/a.md': order({ id: 'a', date: '2026-09-29T00:00:00Z', marker: 'plan', extra: 'Not this: `<!-- arbeidsform: ordre -->` in a sentence.' }) },
{ records: [briefRun({ order_id: 'a' })] });
assert.equal(row.facts.declaredNo, 0);
assert.equal(row.value, 1);
});
test('use: arbeidsform: ordre on an ikke-nytt or unmarked order adds nothing to the denominator', () => {
const row = use({
'r/orders/y.md': order({ id: 'y', date: '2026-09-29T00:00:00Z', marker: 'plan' }),
'r/orders/i.md': order({ id: 'i', date: '2026-09-29T00:00:00Z', marker: 'ikke-nytt', arbeidsform: 'ordre' }),
'r/orders/u.md': order({ id: 'u', date: '2026-09-29T00:00:00Z', arbeidsform: 'ordre' }),
}, { records: [briefRun({ order_id: 'y' })] });
assert.equal(row.facts.declaredNo, 0);
assert.equal(row.denominator, 1);
});
test('use: arbeidsform: voyage without a record is NOT MEASURED - the declaration is never the source', () => {
const row = use({ 'r/orders/a.md': order({ id: 'a', date: '2026-09-29T00:00:00Z', marker: 'plan', arbeidsform: 'voyage' }) });
assert.equal(row.facts.withVoyageRun, 0);
assert.equal(row.facts.noRecord, 1);
assert.equal(row.countable, false);
});
test('use: orders before the counting start are NOT MEASURED; an order dated exactly on it counts', () => {
const row = use({
'r/orders/early.md': order({ id: 'early', date: '2026-10-01T23:59:59Z', marker: 'plan' }),
'r/orders/on.md': order({ id: 'on', date: '2026-10-02T00:00:00Z', marker: 'plan' }),
}, { countingSince: '2026-10-02', records: [briefRun({ order_id: 'early', slug: 'e' }), briefRun({ order_id: 'on' })] });
assert.equal(row.facts.beforeMarker, 1);
assert.equal(row.value, 1);
assert.equal(row.denominator, 1);
assert.deepEqual(row.facts.matched, ['on']);
});
test('use: with no counting start the row is NOT COUNTABLE and every order is NOT MEASURED', () => {
const row = use({
'r/orders/a.md': order({ id: 'a', date: '2026-09-29T00:00:00Z', marker: 'plan' }),
'r/orders/b.md': order({ id: 'b', date: '2026-09-29T00:00:00Z', marker: 'plan', arbeidsform: 'ordre' }),
}, { countingSince: null, records: [briefRun({ order_id: 'a' })] });
assert.equal(row.countable, false);
assert.equal(row.value, null);
assert.equal(row.facts.notMeasured, row.facts.scanned);
assert.equal(row.facts.countingSince, null);
assert.match(row.detail, /counting has not started/);
assert.match(row.source, /counting not started/);
});
test('use: the window starts at the latest of the cutoff, MARKER_SINCE and the counting start', () => {
const files = { 'r/orders/a.md': order({ id: 'a', date: '2026-10-04T00:00:00Z', marker: 'plan' }) };
assert.match(use(files, { cutoff: '2026-10-05', countingSince: '2026-10-03' }).source, /from 2026-10-05/);
assert.match(use(files, { cutoff: '2026-09-21', countingSince: '2026-10-03' }).source, /from 2026-10-03/);
});
test('use: the exact outcome over YES, declared NO, no record and disputed', () => {
const row = use({
'r/orders/y.md': order({ id: 'y', date: '2026-09-29T00:00:00Z', marker: 'plan' }),
'r/orders/n.md': order({ id: 'n', date: '2026-09-29T00:00:00Z', marker: 'prove', arbeidsform: 'ordre' }),
'r/orders/r.md': order({ id: 'r', date: '2026-09-29T00:00:00Z', marker: 'plan', arbeidsform: 'voyage' }),
'r/orders/d.md': order({ id: 'd', date: '2026-09-29T00:00:00Z', marker: 'plan' }),
'r/orders/u.md': order({ id: 'u', date: '2026-09-29T00:00:00Z' }),
'r/orders/e.md': order({ id: 'e', date: '2026-09-01T00:00:00Z', marker: 'plan' }),
}, { records: [briefRun({ order_id: 'y', slug: 'y' }), briefRun({ order_id: 'd', slug: 'd1' }), briefRun({ order_id: 'd', slug: 'd2' })] });
assert.equal(row.countable, true);
assert.equal(row.value, 1);
assert.equal(row.denominator, 2, 'y (YES) + n (declared NO)');
assert.equal(row.facts.withVoyageRun, 1);
assert.equal(row.facts.declaredNo, 1);
assert.equal(row.facts.noRecord, 1);
assert.equal(row.facts.disputed, 1);
assert.equal(row.facts.notMeasured, 4, 'r (no record) + d (disputed) + u (unmarked) + e (before the window)');
assert.match(row.detail, /value = 1 of 2 measured/);
});
test('use: ordersNamedByARecord counts named orders even before counting starts (the known-positive check)', () => {
const row = use({
'r/orders/a.md': order({ id: 'a', date: '2026-09-29T00:00:00Z', marker: 'plan' }),
'r/orders/b.md': order({ id: 'b', date: '2026-09-29T00:00:00Z', marker: 'plan' }),
}, { countingSince: null, records: [briefRun({ order_id: 'a' })] });
assert.equal(row.countable, false);
assert.equal(row.facts.ordersNamedByARecord, 1);
});
// --- 3 · INTERRUPTS ----------------------------------------------------------
test('interrupts: no user_input record means NOT COUNTABLE, with the line denominator stated', () => {
const dir = fixture({
'trekexecute-stats.jsonl': jsonl({ ts: 't', session_id: 's', success: true }, { ts: 't', event: 'main-merge-gate', payload: {} }),
'trekplan-stats.jsonl': jsonl({ ts: 't', slug: 'x' }),
});
try {
const row = measureInterrupts({ stats: loadStats(dir), callSites: { sites: [], scanned: 3 } });
assert.equal(row.countable, false);
assert.equal(row.facts.lines, 3);
assert.equal(row.facts.userInput, 0);
assert.match(row.detail, /0 user_input records of 3 lines in 2 files/);
assert.match(row.detail, /0 emitter call sites/);
} finally { cleanup(dir); }
});
test('interrupts: user_input WITHOUT a slug or run id is still not countable per delivery', () => {
const dir = fixture({
'trekexecute-stats.jsonl': jsonl({ ts: 't', event: 'user_input', payload: { question: 'q' } }),
});
try {
const row = measureInterrupts({ stats: loadStats(dir), callSites: { sites: [], scanned: 1 } });
assert.equal(row.countable, false);
assert.equal(row.facts.userInput, 1);
assert.equal(row.facts.withDelivery, 0);
} finally { cleanup(dir); }
});
test('interrupts: user_input carrying a slug or run id is countable, per delivery', () => {
const dir = fixture({
'trekexecute-stats.jsonl': jsonl(
{ ts: 't1', event: 'user_input', payload: { slug: 'feat-a' } },
{ ts: 't2', event: 'user_input', payload: { slug: 'feat-a' } },
{ ts: 't3', event: 'user_input', payload: { run_id: 'r-9' } },
),
});
try {
const row = measureInterrupts({ stats: loadStats(dir), callSites: { sites: [], scanned: 1 } });
assert.equal(row.countable, true);
assert.equal(row.value, 3);
assert.deepEqual(row.facts.perDelivery, { 'feat-a': 2, 'r-9': 1 });
} finally { cleanup(dir); }
});
test('emitterCallSites: counts user_input emissions outside lib/stats/ and tests/ only', () => {
const root = fixture({
'commands/a.md': 'node ${CLAUDE_PLUGIN_ROOT}/lib/stats/event-emit.mjs \\\n --event user_input \\\n',
'commands/b.md': 'the emitter knows user_input as an event name - prose, not a call\n',
'lib/util/x.mjs': "emitEvent('user_input', { slug });\n",
'lib/stats/event-emit.mjs': "emit('user_input', {});\n",
'tests/lib/y.test.mjs': "emit('user_input', {});\n",
'hooks/scripts/h.mjs': "spawnSync('node', [EMIT, '--event', 'user_input']);\n",
});
try {
const r = emitterCallSites(root);
assert.deepEqual(r.sites.map((s) => s.file).sort(), ['commands/a.md', 'hooks/scripts/h.mjs', 'lib/util/x.mjs']);
assert.equal(r.scanned, 4, 'commands/a.md, commands/b.md, lib/util/x.mjs, hooks/scripts/h.mjs');
} finally { cleanup(root); }
});
// --- 4 · the signature-preserving mutant (M9) ----------------------------------
const MODULE = 'export function verdict(code) { return { status: code === 0 ? "PASSED" : "FAILED" }; }\n';
const STRONG_TEST = [
"import { test } from 'node:test';",
"import { strict as assert } from 'node:assert';",
"import { verdict } from '../lib/m.mjs';",
"test('verdict fells a failing exit', () => { assert.equal(verdict(1).status, 'FAILED'); });",
'',
].join('\n');
const behaviourRegistry = {
defects: [{
id: 'D-X', probe: 'behaviour',
check: [{ test: 'tests/t.test.mjs', name: 'verdict fells a failing exit', expect: 'fails', stubs: ['lib/m.mjs'] }],
}],
experiments: [],
};
test('buildM9Tree: every export keeps its name and returns {status:"PASSED"}; every named test only checks typeof', async () => {
const root = fixture({ 'lib/m.mjs': MODULE, 'tests/t.test.mjs': STRONG_TEST });
const m9 = buildM9Tree(root, behaviourRegistry);
try {
const mod = readFileSync(join(m9, 'lib', 'm.mjs'), 'utf8');
assert.match(mod, /export function verdict\(\) \{ return \{ status: 'PASSED' \}; \}/);
const t = readFileSync(join(m9, 'tests', 't.test.mjs'), 'utf8');
assert.match(t, /verdict fells a failing exit/);
assert.match(t, /typeof/);
assert.doesNotMatch(t, /FAILED/, 'the mutant test asserts nothing about behaviour');
assert.equal(readFileSync(join(root, 'lib', 'm.mjs'), 'utf8'), MODULE, 'the measured tree is never touched');
} finally { cleanup(root, m9); }
});
test('mutants: a gate that CLOSES the probe on M9 has felled 0 of 1', () => {
const root = fixture({ 'lib/m.mjs': MODULE, 'tests/t.test.mjs': STRONG_TEST });
try {
const row = measureMutants(root, {
registry: behaviourRegistry,
evaluate: () => ({ status: 'closed', detail: '' }),
runTest: () => true,
});
assert.equal(row.countable, true);
assert.equal(row.value, 0);
assert.equal(row.denominator, 1);
assert.match(row.detail, /D-X closed/);
} finally { cleanup(root); }
});
test('mutants: a gate that refuses to close the probe on M9 has felled 1 of 1', () => {
const root = fixture({ 'lib/m.mjs': MODULE, 'tests/t.test.mjs': STRONG_TEST });
try {
const row = measureMutants(root, {
registry: behaviourRegistry,
evaluate: () => ({ status: 'not-fellable', detail: 'still passes against a signature-preserving mutant' }),
runTest: () => true,
});
assert.equal(row.value, 1);
assert.equal(row.denominator, 1);
} finally { cleanup(root); }
});
test('mutants: a mutant whose own tests do not pass is not LIVE, so the row cannot be counted', () => {
// Without this control a broken fixture would read as "felled".
const root = fixture({ 'lib/m.mjs': MODULE, 'tests/t.test.mjs': STRONG_TEST });
try {
const row = measureMutants(root, {
registry: behaviourRegistry,
evaluate: () => ({ status: 'not-fellable', detail: 'x' }),
runTest: () => null,
});
assert.equal(row.countable, false);
assert.equal(row.value, null);
assert.match(row.detail, /not live/);
} finally { cleanup(root); }
});
test('mutants: against the REAL gate and registry, M9 is live and the denominator is 1', () => {
// Pins the measurement's shape, not today's value: M9's typeof-only tests
// really do pass on the M9 tree (so "felled" can only come from the gate).
const row = measureMutants(ROOT);
assert.equal(row.countable, true, row.detail);
assert.equal(row.denominator, 1);
assert.ok(row.value === 0 || row.value === 1);
assert.deepEqual(row.facts.entries.sort(), ['D-03', 'D-04']);
});
// --- the whole yardstick -------------------------------------------------------
function world({ orders = {}, stats = {} } = {}) {
const coord = fixture(Object.keys(orders).length ? orders : { 'r/orders/.keep': '' });
const data = fixture(Object.keys(stats).length ? stats : { '.keep': '' });
return { coord, data };
}
test('measureAll + main: RED with exit 1 while any number is not countable', () => {
const { coord, data } = world({
orders: { 'r/orders/o.md': order({ id: 'o', date: '2026-09-22T00:00:00Z' }) },
stats: { 'trekreview-stats.jsonl': jsonl(review('2026-09-01T00:00:00Z', 'ALLOW')) },
});
try {
const result = measureAll({ root: ROOT, coordDir: coord, dataDir: data, cutoff: DEFAULT_CUTOFF });
assert.equal(result.green, false);
assert.equal(result.countable, 1);
const text = render(result);
assert.match(text, /1 of 3 numbers countable/);
assert.match(text, /signature-preserving mutants felled: \d of 1/);
assert.match(text, /verdict: NOT JUDGED/);
for (const id of ['use', 'trust', 'interrupts', 'mutants']) assert.match(text, new RegExp(`\\| ${id} \\|`));
assert.equal(main(['--root', ROOT, '--coord', coord, '--data', data, '--json']), 1);
} finally { cleanup(coord, data); }
});
test('measureAll: all three countable and the mutant felled is still RED until the verdict can be judged', () => {
const { coord, data } = world({
orders: { 'r/orders/o.md': order({ id: 'o', date: '2026-09-29T00:00:00Z', marker: 'plan' }) },
stats: {
'trekbrief-stats.jsonl': jsonl(briefRun({ order_id: 'o', slug: 'a' })),
'trekreview-stats.jsonl': jsonl(review('2026-09-01T00:00:00Z', 'ALLOW', 'a')),
'trekexecute-stats.jsonl': jsonl({ ts: 't', event: 'user_input', payload: { slug: 'a' } }),
},
});
try {
const result = measureAll({
root: ROOT, coordDir: coord, dataDir: data, cutoff: DEFAULT_CUTOFF, countingSince: MARKER_SINCE,
mutantOptions: { evaluate: () => ({ status: 'not-fellable', detail: '' }) },
});
assert.equal(result.countable, 3);
assert.equal(result.rows.find((r) => r.id === 'mutants').value, 1);
assert.equal(result.verdict.judged, false);
assert.equal(result.green, false);
} finally { cleanup(coord, data); }
});
test('main: an unknown argument or a malformed cutoff is a usage error (exit 2)', () => {
assert.equal(main(['--nope']), 2);
assert.equal(main(['--cutoff', '21.09.2026']), 2);
});
test('measureAll: without countingSince it uses USE_COUNTING_SINCE, whatever its value', () => {
assert.ok('USE_COUNTING_SINCE' in Y, 'scripts/yardstick.mjs exports USE_COUNTING_SINCE');
const { coord, data } = world({
orders: { 'r/orders/o.md': order({ id: 'o', date: '2026-10-29T00:00:00Z', marker: 'plan' }) },
stats: { 'trekbrief-stats.jsonl': jsonl(briefRun({ order_id: 'o' })) },
});
try {
const all = measureAll({ root: ROOT, coordDir: coord, dataDir: data, cutoff: DEFAULT_CUTOFF,
mutantOptions: { evaluate: () => ({ status: 'not-fellable', detail: '' }) } });
const direct = measureUse({ queue: readOrders(coord), runs: Y.orderRuns(loadStats(data)), cutoff: DEFAULT_CUTOFF,
countingSince: Y.USE_COUNTING_SINCE });
assert.deepEqual(all.rows.find((r) => r.id === 'use'), direct);
} finally { cleanup(coord, data); }
});
test('main: the CLI prints its result when run through a symlink', () => {
const { coord, data } = world();
const links = mkdtempSync(join(tmpdir(), 'yardstick-link-'));
try {
const link = join(links, 'yardstick.mjs');
symlinkSync(join(ROOT, 'scripts', 'yardstick.mjs'), link);
const r = spawnSync(process.execPath, [link, '--coord', coord, '--data', data, '--json'], { encoding: 'utf8', timeout: 120000 });
assert.ok(r.stdout.trim().length > 0, `no output through a symlink (exit ${r.status})`);
assert.ok(Array.isArray(JSON.parse(r.stdout).rows));
} finally { cleanup(coord, data, links); }
});