test(docs): the order fields stand on all five surfaces (red)
order_id / order_claimed_at / order_reason on the five surfaces: (1) record format = the writer (pinned in stats-landing), (2) Phase 7 prose with "the writer adds", (3) the field-allowlist header names them as dropped and TREKBRIEF_ALLOWED leaves them out, (4) the trekbrief-stats fixture row's `fields` column + EXPORT_DENYLIST, (5) docs/architecture.md Stats. Plus: the row's line_ref must contain the Phase 7 stats-append line (it said 657-672, the line is at 958); /trekbrief --approve reaches Phase 7 with mode "approve" (PM 04.10, point 3) and CLAUDE.md, README.md, docs/command-modes.md say so. Red: 7 doc pins fail. Green on arrival: the yardstick-header pin (Step 6 already rewrote the header) and the otel DROP guard (the fields were never allowlisted). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
5dac5b59be
commit
598ef1b694
2 changed files with 100 additions and 0 deletions
|
|
@ -227,6 +227,15 @@ test('field-allowlist: trekbrief KEEPS intent_approved (veikart steg 1) and drop
|
|||
assert.equal(applyFieldAllowlist({ ...record, intent_approved: false }, 'trekbrief').intent_approved, false);
|
||||
});
|
||||
|
||||
test('field-allowlist: trekbrief DROPS the order fields (coordination metadata) and still KEEPS intent_approved', () => {
|
||||
const out = applyFieldAllowlist({
|
||||
ts: '2026-10-04T10:00:00.000Z', slug: 's', intent_approved: true,
|
||||
order_id: 'o-1', order_claimed_at: '2026-10-04T09:00:00Z', order_reason: null,
|
||||
}, 'trekbrief');
|
||||
for (const k of ['order_id', 'order_claimed_at', 'order_reason']) assert.equal(k in out, false, `${k} must never be exported`);
|
||||
assert.equal(out.intent_approved, true);
|
||||
});
|
||||
|
||||
test('field-allowlist: event-emit applies sub-allowlist to payload', () => {
|
||||
const record = {
|
||||
ts: '2026-05-09T08:00:00.000Z',
|
||||
|
|
|
|||
|
|
@ -2020,3 +2020,94 @@ test('model aliases: profiles.md states the current targets, defaults and sessio
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
// --- the order a /trekbrief run records (yardstick use, source C) ---------------
|
||||
// Five surfaces for order_id / order_claimed_at / order_reason: (1) record format
|
||||
// = the writer, lib/stats/stats-append.mjs (pinned behaviourally in
|
||||
// tests/lib/stats-landing.test.mjs); (2) measured-field prose = /trekbrief Phase 7;
|
||||
// (3) field allowlist = denied, said in the allowlist header; (4) jsonl schemas =
|
||||
// the trekbrief-stats fixture row + EXPORT_DENYLIST; (5) docs = docs/architecture.md.
|
||||
const ORDER_FIELDS = ['order_id', 'order_claimed_at', 'order_reason'];
|
||||
|
||||
function mdSection(text, heading) {
|
||||
const start = text.indexOf(`\n## ${heading}`);
|
||||
assert.ok(start >= 0, `missing "## ${heading}"`);
|
||||
const next = text.indexOf('\n## ', start + 1);
|
||||
return next < 0 ? text.slice(start) : text.slice(start, next);
|
||||
}
|
||||
|
||||
function trekbriefRow() {
|
||||
const row = read('tests/fixtures/jsonl-schemas.md').split('\n').find((l) => l.startsWith('| trekbrief-stats '));
|
||||
assert.ok(row, 'jsonl-schemas.md is missing the `trekbrief-stats` row');
|
||||
return row.split('|').map((c) => c.trim());
|
||||
}
|
||||
|
||||
test('order fields: /trekbrief Phase 7 names them and says the writer adds them', () => {
|
||||
const sec = mdSection(read('commands/trekbrief.md'), 'Phase 7');
|
||||
for (const f of ORDER_FIELDS) assert.ok(sec.includes(`\`${f}\``), `Phase 7 must name \`${f}\``);
|
||||
assert.match(sec, /writer adds/i, 'the model never types the order id - the prose must say who adds it');
|
||||
});
|
||||
|
||||
test('order fields: the trekbrief-stats fixture row lists them in `fields`, and EXPORT_DENYLIST names them', () => {
|
||||
const fields = new Set(trekbriefRow()[2].split(',').map((f) => f.trim()));
|
||||
for (const f of ORDER_FIELDS) assert.ok(fields.has(f), `\`${f}\` missing from the trekbrief-stats \`fields\` column`);
|
||||
const text = read('tests/fixtures/jsonl-schemas.md');
|
||||
const deny = text.slice(text.indexOf('**EXPORT_DENYLIST**'));
|
||||
const block = deny.slice(deny.indexOf('```') + 3, deny.indexOf('```', deny.indexOf('```') + 3));
|
||||
for (const f of ORDER_FIELDS) assert.ok(block.split(',').map((x) => x.trim()).includes(f), `\`${f}\` missing from EXPORT_DENYLIST`);
|
||||
});
|
||||
|
||||
test('order fields: the trekbrief-stats row\'s line_ref still points at the Phase 7 stats-append line', () => {
|
||||
const ref = trekbriefRow()[4];
|
||||
const m = ref.match(/^trekbrief\.md:(\d+)-(\d+)$/);
|
||||
assert.ok(m, `line_ref "${ref}" is not trekbrief.md:A-B`);
|
||||
const lines = read('commands/trekbrief.md').split('\n');
|
||||
const at = lines.findIndex((l) => /^\s*node \$\{CLAUDE_PLUGIN_ROOT\}\/lib\/stats\/stats-append\.mjs trekbrief\b/.test(l)) + 1;
|
||||
assert.ok(at > 0, 'the Phase 7 stats-append line is gone');
|
||||
assert.ok(at >= Number(m[1]) && at <= Number(m[2]), `line_ref ${ref} does not contain the stats-append line (line ${at})`);
|
||||
});
|
||||
|
||||
test('order fields: docs/architecture.md Stats names them and the order-id join', () => {
|
||||
const text = read('docs/architecture.md');
|
||||
const stats = text.slice(text.indexOf('\nStats:'), text.indexOf('\n## Terminology'));
|
||||
for (const f of ORDER_FIELDS) assert.ok(stats.includes(`\`${f}\``), `docs/architecture.md Stats must name \`${f}\``);
|
||||
assert.match(stats, /yardstick/);
|
||||
});
|
||||
|
||||
test('order fields: the field-allowlist header says they are denied, and TREKBRIEF_ALLOWED leaves them out', () => {
|
||||
const text = read('lib/exporters/field-allowlist.mjs');
|
||||
const header = text.slice(0, text.indexOf('const TREKBRIEF_ALLOWED'));
|
||||
for (const f of ORDER_FIELDS) assert.ok(header.includes(f), `the allowlist header must name ${f} among the dropped fields`);
|
||||
const body = text.slice(text.indexOf('const TREKBRIEF_ALLOWED'), text.indexOf(']));', text.indexOf('const TREKBRIEF_ALLOWED')));
|
||||
for (const f of ORDER_FIELDS) assert.ok(!body.includes(`'${f}'`), `${f} must not be allowlisted for export`);
|
||||
});
|
||||
|
||||
test('yardstick header: use joins on the order id, says where a no comes from, and names the false-positive class', () => {
|
||||
const text = read('scripts/yardstick.mjs');
|
||||
const header = text.slice(0, text.indexOf('\nimport '));
|
||||
assert.match(header, /order id/);
|
||||
assert.match(header, /arbeidsform: ordre/);
|
||||
assert.match(header, /false-positive/);
|
||||
assert.match(header, /USE_COUNTING_SINCE/);
|
||||
assert.doesNotMatch(header, /slug equals the order's/, 'the slug join is gone');
|
||||
});
|
||||
|
||||
test('/trekbrief --approve writes the trekbrief record: Phase 1 and Phase 4h run Phase 7 with mode "approve"', () => {
|
||||
const text = read('commands/trekbrief.md');
|
||||
const item4 = text.slice(text.indexOf('4. `--approve <project-dir | brief-file>`'), text.indexOf('In every other mode'));
|
||||
assert.match(item4, /Phase 7/, 'approve mode must reach Phase 7 (PM 04.10: the approval leaves the trekbrief record)');
|
||||
const tail = text.slice(text.indexOf('In `--approve` mode'), text.indexOf('## Phase 5'));
|
||||
assert.match(tail, /Phase 7/);
|
||||
const phase7 = mdSection(text, 'Phase 7');
|
||||
assert.match(phase7, /"mode": "\{default \| quick \| approve\}"/);
|
||||
assert.match(phase7, /"mode": "approve"/, 'Phase 7 must fix the approve-mode values');
|
||||
assert.match(text, /Mode: \{default \| quick \| approve\}/, 'the Phase 1 report lists approve');
|
||||
});
|
||||
|
||||
test('/trekbrief --approve: CLAUDE.md, README.md and docs/command-modes.md say the approval writes the trekbrief record', () => {
|
||||
for (const rel of ['CLAUDE.md', 'README.md', 'docs/command-modes.md']) {
|
||||
const line = read(rel).split('\n').find((l) => l.includes('--approve <'));
|
||||
assert.ok(line, `${rel} has no --approve row`);
|
||||
assert.match(line, /trekbrief (stats )?record/, `${rel}: the --approve row must say it writes the trekbrief record`);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue