fix(docs): the trekbrief pass branch names no Brief Quality, and the stats rows span their blocks

Operator decision 21 (12.10).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-10-13 19:16:51 +02:00
commit 5b94952be9
Signed by: ktg
SSH key fingerprint: SHA256:JakMjO6FTBBzN0Bhfj9saOoEjaFxlSdYuZQQpM/lF9Q
3 changed files with 47 additions and 15 deletions

View file

@ -19,13 +19,13 @@
| schema_id | fields | writer_path | line_ref | v4.1 additive | PII |
|-----------|--------|-------------|----------|---------------|-----|
| trekbrief-stats | ts, task, slug, mode, interview_turns, review_iterations, brief_quality, research_topics, auto_research, auto_result, intent_approved, project_dir, order_id, order_claimed_at, order_reason | commands/trekbrief.md (orchestrator-emit Phase 7; order_* added by lib/stats/stats-append.mjs) | trekbrief.md:1130-1145 | profile, phase_models, profile_source | none |
| trekbrief-stats | ts, task, slug, mode, interview_turns, review_iterations, brief_quality, research_topics, auto_research, auto_result, intent_approved, project_dir, order_id, order_claimed_at, order_reason | commands/trekbrief.md (orchestrator-emit Phase 7; order_* added by lib/stats/stats-append.mjs) | trekbrief.md:1137-1161 | profile, phase_models, profile_source | none |
| trekresearch-stats | ts, question, mode, scope, engine, slug, project_dir, brief_path, dimensions, dimensions_baseline, dimensions_baseline_preserved, effort, conv_turns, empty_turns, unique_sources, agents_local, agents_external, gemini_used, confidence, contradictions, open_questions | lib/stats/stats-append.mjs (trekresearch.md Stats tracking) | trekresearch.md:782-808 | profile, phase_models, parallel_agents, external_research_enabled, profile_source | none |
| trekplan-stats | ts, task, mode, slug, brief_path, project_dir, codebase_size, codebase_files, agents_deployed, deep_dives, research_briefs_used, research_scout_used, critic_verdict, guardian_verdict, outcome | lib/stats/stats-append.mjs (trekplan.md Phase 12) | trekplan.md:1115-1135 | profile, phase_models, parallel_agents, profile_source | none |
| trekplan-stats | ts, task, mode, slug, brief_path, project_dir, codebase_size, codebase_files, agents_deployed, deep_dives, research_briefs_used, research_scout_used, critic_verdict, guardian_verdict, outcome | lib/stats/stats-append.mjs (trekplan.md Phase 12) | trekplan.md:1234-1262 | profile, phase_models, parallel_agents, profile_source | none |
| trekexecute-stats (Phase 9 record) | ts, plan, plan_type, mode, result, steps_total, steps_passed, steps_failed, steps_skipped, failed_at_step | lib/stats/stats-append.mjs (trekexecute.md Phase 9) | trekexecute.md:2892-2914 | profile, phase_models, profile_source | none |
| trekexecute-stats (autonomy events) | ts, event, known_event, payload | lib/stats/event-emit.mjs `emit()` | event-emit.mjs:78-99 | payload.profile, payload.phase_models, payload.profile_source | none |
| trekexecute-stats (PostToolUse Bash) | ts, session_id, command_excerpt, duration_ms, success | hooks/scripts/post-bash-stats.mjs (Bash PostToolUse) | post-bash-stats.mjs:42-54 | none (hook is plugin-level, not profile-aware) | command_excerpt (CWE-212) |
| trekreview-stats | ts, slug, verdict, counts (BLOCKER/MAJOR/MINOR/SUGGESTION), reviewed_files_count, mode, duration_ms | lib/stats/stats-append.mjs (trekreview.md Phase 8) | trekreview.md:628-632 | profile, phase_models, profile_source | none |
| trekreview-stats | ts, slug, verdict, counts (BLOCKER/MAJOR/MINOR/SUGGESTION), reviewed_files_count, mode, duration_ms | lib/stats/stats-append.mjs (trekreview.md Phase 8) | trekreview.md:623-673 | profile, phase_models, profile_source | none |
| trekcontinue-stats | ts, project, next_session_label, status | lib/stats/stats-append.mjs (trekcontinue.md Phase 5) | trekcontinue.md:293-297 | profile, profile_source | none |
| token-usage | ts, session_id, scope, model, tokens_input, tokens_output, tokens_cache_creation, tokens_cache_read, cost_usd, is_estimate, price_table_version | lib/stats/token-usage.mjs `captureTokenUsage` (via hooks/scripts/otel-export.mjs Stop hook, opt-in `VOYAGE_TOKEN_METER`) | token-usage.mjs:buildRecord | n/a (SKAL-2 schema) | session_id (stripped at export) |

View file

@ -2079,17 +2079,49 @@ function schemaRow(id) {
}
// The Phase 9 line_ref was measured, then more prose landed above Phase 9 and
// nothing re-measured it. Pinned to the span it names: heading to closing fence.
test('the trekexecute Phase 9 row\'s line_ref spans the Phase 9 heading to the end of its stdin block', () => {
const ref = schemaRow('trekexecute-stats (Phase 9 record)')[4];
const m = ref.match(/^trekexecute\.md:(\d+)-(\d+)$/);
assert.ok(m, `line_ref "${ref}" is not trekexecute.md:A-B`);
const lines = read('commands/trekexecute.md').split('\n');
const heading = lines.findIndex((l) => /^## Phase 9\b/.test(l)) + 1;
const append = lines.findIndex((l) => /^\s*node \$\{CLAUDE_PLUGIN_ROOT\}\/lib\/stats\/stats-append\.mjs trekexecute\b/.test(l)) + 1;
const fence = lines.findIndex((l, i) => i >= append && l.trim() === '```') + 1;
assert.ok(heading > 0 && append > heading && fence > append, 'Phase 9 heading, stats-append line and closing fence');
assert.equal(ref, `trekexecute.md:${heading}-${fence}`);
// nothing re-measured it. The same drift hit the other command stats rows.
// Each row is pinned to the span it names: its phase heading to the closing
// fence of its stats-append stdin block. The trekreview anchor is the full
// "## Phase 8 — Validate output" so the Phase 8.5 / 8.7 headings never match.
const STATS_ROWS = [
{ id: 'trekbrief-stats', cmd: 'trekbrief', heading: /^## Phase 7\b(?!\.)/ },
{ id: 'trekplan-stats', cmd: 'trekplan', heading: /^## Phase 12\b(?!\.)/ },
{ id: 'trekreview-stats', cmd: 'trekreview', heading: /^## Phase 8 — Validate output/ },
{ id: 'trekexecute-stats (Phase 9 record)', cmd: 'trekexecute', heading: /^## Phase 9\b(?!\.)/ },
];
for (const { id, cmd, heading: headingRe } of STATS_ROWS) {
test(`the ${id} row's line_ref spans its phase heading to the end of its stats-append stdin block`, () => {
const ref = schemaRow(id)[4];
const m = ref.match(new RegExp(`^${cmd}\\.md:(\\d+)-(\\d+)$`));
assert.ok(m, `line_ref "${ref}" is not ${cmd}.md:A-B`);
const lines = read(`commands/${cmd}.md`).split('\n');
const headings = lines.map((l, i) => (headingRe.test(l) ? i : -1)).filter((i) => i >= 0);
assert.equal(headings.length, 1, `exactly one heading in commands/${cmd}.md matches ${headingRe}`);
const heading = headings[0] + 1;
const appendRe = new RegExp(`^\\s*node \\$\\{CLAUDE_PLUGIN_ROOT\\}/lib/stats/stats-append\\.mjs ${cmd}\\b`);
const append = lines.findIndex((l, i) => i >= heading && appendRe.test(l)) + 1;
const nextPhase = lines.findIndex((l, i) => i >= heading && /^## Phase /.test(l)) + 1;
assert.ok(append > heading, `a stats-append line follows the heading in commands/${cmd}.md`);
assert.ok(nextPhase === 0 || append < nextPhase, `the stats-append line sits inside the phase (line ${append}, next phase at ${nextPhase})`);
const fence = lines.findIndex((l, i) => i >= append && l.trim() === '```') + 1;
assert.ok(fence > append, 'the stats-append block has a closing fence');
assert.equal(ref, `${cmd}.md:${heading}-${fence}`);
});
}
// A `## Brief Quality` section belongs to the exhausted and force-stopped
// branches only; the passed-gate branch must not tell the model to write one.
test('trekbrief: the passed-gate branch names no `## Brief Quality`, the exhausted branch still does', () => {
const text = read('commands/trekbrief.md');
const passStart = text.indexOf('**If gate passes:**');
const passEnd = text.indexOf('**If gate fails AND iteration count < the class cap:**');
assert.ok(passStart >= 0 && passEnd > passStart, 'passed-gate branch markers');
assert.ok(!text.slice(passStart, passEnd).includes('## Brief Quality'), 'the passed-gate branch names `## Brief Quality`');
const exStart = text.indexOf('**If gate fails AND iteration count == the class cap (loop exhausted):**');
const exEnd = text.indexOf('### Step 4f', exStart);
assert.ok(exStart > passEnd && exEnd > exStart, 'exhausted branch markers');
assert.ok(text.slice(exStart, exEnd).includes('## Brief Quality'), 'the exhausted branch must still name `## Brief Quality`');
});
test('the autonomy-events row\'s line_ref spans emit() in event-emit.mjs', () => {