docs(wording): reframe alerts and report from verdict to inquiry (tiltak 2)

BRIEF-vurdering-v2.md tiltak 2: "design for the investigator, not the
validator". The hook alerts stated short conclusions a reader can only
accept or dismiss ("Rapid-fire: N consecutive fast interactions",
"possible stuck/spiral", "Consider a break").

Each alert in tool-tracker.mjs now follows the form the read-dominant
edit-ratio message introduced in 2c9e2de — observation, the counter-signal
that changes how to read it, then what to check:

- burst: names the interval and that edits were among the calls, and asks
  whether each change was verified before the next
- edit ratio: carries the read percentage and asks what the remaining
  calls are doing and whether the approach is converging
- soft warning: closes on framing instead of prescribing a break
- hard warning: asks the model to name its observations and ask what they
  reflect; the required stop action is unchanged

commands/interaction-report.md gains the same rule for Observations and
trend reporting, plus an explicit "investigator, not validator" tone rule
and a "report the difference, not a label for it" rule.

Wording only — thresholds, heuristics, data model and required actions
are untouched. README examples and threshold-basis cells updated to match.

Tests first (Iron Law): 6 new/updated assertions on message text in
tests/tool-tracker.test.mjs and tests/interaction-report.test.mjs, red
before the change. node --test tests/*.test.mjs: 269 pass, 5 fail — the
pre-existing perf wall-clock cases only.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013U8ZH25KiMtts89yWRuVWD
This commit is contained in:
Kjell Tore Guttormsen 2026-08-13 21:10:39 +02:00
commit 86c3eae30c
6 changed files with 168 additions and 25 deletions

View file

@ -5,7 +5,7 @@
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { execSync } from 'child_process';
import { mkdtempSync, rmSync, writeFileSync } from 'fs';
import { mkdtempSync, rmSync, writeFileSync, readFileSync } from 'fs';
import { join } from 'path';
import { tmpdir } from 'os';
@ -196,3 +196,21 @@ test('report-reader stdout surfaces v1.2 field names (SC-12)', () => {
assert.ok(stdout.includes('legal'), 'stdout missing legal domain in breakdown');
assert.ok(stdout.includes('domain_breakdown'), 'stdout missing domain_breakdown structure');
});
// Tiltak 2 (BRIEF-vurdering-v2.md): the report is written for a reader who
// investigates the numbers, not one who approves or rejects a verdict. The
// tone rules must say so explicitly, and the Observations template must carry
// the context + check form rather than a bare conclusion.
test('interaction-report.md instructs an investigative, non-verdict report', () => {
const cmd = readFileSync(
join(import.meta.dirname, '..', 'commands', 'interaction-report.md'), 'utf8');
assert.ok(cmd.includes('Investigator, not validator'),
'tone rules missing the investigator framing');
assert.ok(cmd.includes('never in a conclusion about the user'),
'tone rules do not forbid concluding about the user');
assert.ok(cmd.includes('report both values and the delta'),
'tone rules do not require reporting the difference over a label');
assert.ok(cmd.includes('what to check'),
'Observations template does not ask for something to check');
});