feat(trekresearch): emit and export the five STORM measurement fields
This commit is contained in:
parent
d9cba9c6ea
commit
f3874946ad
7 changed files with 136 additions and 7 deletions
|
|
@ -94,6 +94,81 @@ test('SC #11(b): commands/trekplan.md prose mentions phase_models + parallel_age
|
|||
'trekplan.md prose must mention parallel_agents (additive stats field)');
|
||||
});
|
||||
|
||||
// --- Step 9: the five STORM measurement fields -----------------------------
|
||||
// Four numerics + one low-cardinality label. Without `effort` there is no axis
|
||||
// to group high-vs-standard runs on, and the measurement gate cannot be
|
||||
// computed at all.
|
||||
|
||||
const STORM_FIELDS = [
|
||||
'effort',
|
||||
'unique_sources',
|
||||
'dimensions_baseline',
|
||||
'conv_turns',
|
||||
'empty_turns',
|
||||
];
|
||||
|
||||
test('Step 9: a standard-run trekresearch record parses and survives applyFieldAllowlist', async () => {
|
||||
const { applyFieldAllowlist } = await import('../../lib/exporters/field-allowlist.mjs');
|
||||
// A standard run: loop never armed, so no discovered dimensions and no turns.
|
||||
const raw = JSON.parse(JSON.stringify({
|
||||
_schema_id: 'trekresearch',
|
||||
ts: '2026-08-09T12:00:00.000Z',
|
||||
slug: 'add-auth',
|
||||
mode: 'default',
|
||||
scope: 'both',
|
||||
engine: 'swarm',
|
||||
question: 'free prose that must never reach the exporter',
|
||||
project_dir: '/Users/somebody/repos/x',
|
||||
brief_path: '/Users/somebody/repos/x/brief.md',
|
||||
dimensions: 4,
|
||||
dimensions_baseline: 4,
|
||||
conv_turns: 0,
|
||||
empty_turns: 0,
|
||||
unique_sources: 11,
|
||||
effort: 'standard',
|
||||
agents_local: 5,
|
||||
agents_external: 4,
|
||||
gemini_used: false,
|
||||
confidence: 0.8,
|
||||
contradictions: 1,
|
||||
open_questions: 2,
|
||||
profile: 'premium',
|
||||
profile_source: 'default',
|
||||
}));
|
||||
|
||||
assert.equal(raw.dimensions_baseline, raw.dimensions,
|
||||
'a standard run discovers no dimensions — baseline must equal the final count');
|
||||
|
||||
const out = applyFieldAllowlist(raw, 'trekresearch');
|
||||
for (const field of STORM_FIELDS) {
|
||||
assert.ok(field in out, `${field} must survive the trekresearch allowlist`);
|
||||
}
|
||||
assert.equal(out.conv_turns, 0);
|
||||
assert.equal(out.empty_turns, 0);
|
||||
assert.equal(out.effort, 'standard');
|
||||
// Deny-by-omission must still hold for the PII-ish fields.
|
||||
for (const denied of ['question', 'project_dir', 'brief_path']) {
|
||||
assert.equal(denied in out, false, `${denied} must NOT reach the exporter`);
|
||||
}
|
||||
});
|
||||
|
||||
test('Step 9: commands/trekresearch.md prose names all five measurement fields', () => {
|
||||
const content = readFileSync(join(REPO_ROOT, 'commands', 'trekresearch.md'), 'utf-8');
|
||||
for (const field of STORM_FIELDS) {
|
||||
assert.ok(content.includes(field),
|
||||
`trekresearch.md prose must name ${field} — an emitted-but-undocumented field is unauditable`);
|
||||
}
|
||||
});
|
||||
|
||||
test('Step 9: tests/fixtures/jsonl-schemas.md trekresearch row lists the five fields', () => {
|
||||
const doc = readFileSync(join(REPO_ROOT, 'tests', 'fixtures', 'jsonl-schemas.md'), 'utf-8');
|
||||
const row = doc.split('\n').find(l => l.startsWith('| trekresearch-stats '));
|
||||
assert.ok(row, 'jsonl-schemas.md is missing the trekresearch-stats row');
|
||||
for (const field of STORM_FIELDS) {
|
||||
assert.ok(row.includes(field), `authoring reference must list ${field}`);
|
||||
}
|
||||
});
|
||||
|
||||
test('SC #11(b): commands/trekresearch.md prose mentions external_research_enabled', () => {
|
||||
const content = readFileSync(join(REPO_ROOT, 'commands', 'trekresearch.md'), 'utf-8');
|
||||
assert.match(content, /external_research_enabled/,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue