RUL-017 — No weasel words — blunt engineering vocabulary everywhere

Ruling

Never use weasel words — soft, hedging, or euphemistic vocabulary — in prose, verdict enums, schemas, docs, commit messages, or agent briefs. "A word for psychologists" is not an engineering verdict. Say what a thing IS: PASS/FAIL/BROKEN/FIXED/UNTESTED/UNKNOWN, with numbers.

This covers two distinct failure modes:

  1. Euphemistic verdicts — problematic, issue, suboptimal where failed, bug, wrong is meant.
  2. Epistemic hedging — a guess wearing the clothes of an answer. likely, probably, seems to, I assume.

The second is the more expensive one. "The test is likely failing because X" ends inquiry while sounding like a finding; hours of work get built on it before anyone checks. The required alternative is a fact with its evidence attached (path:line, command output, query result) — or the word unknown, plus a statement of what it would take to find out. Saying "unknown" is honest. Hedging is not.

The term list lives in .claude/weasel-words.txt — one term per line, the single source of truth, shared by the ruling and the hook. Add a term there and it is enforced with no code change.

Evidence

Enforcement

Verification

.claude/hooks/no-guessing-stop.sh is a Stop hook: it reads the model's last turn (thinking text + output text) from the transcript, matches it word-boundary-wise and case-insensitively against .claude/weasel-words.txt, and returns {"decision":"block"} with an instruction to go resolve the question with tools — read the file, run it and read the traceback, query the graph, git show the commit — and restate the claim as a fact with evidence, or as unknown.

The earlier objection to a string-match gate (that it "would false-positive constantly on legitimate technical usage") is answered structurally rather than dismissed:

Verified 2026-07-27 against six cases: plain hedge in output → BLOCK; the same word only inside a fenced block → silent; evidence-bearing prose → silent; hedge in the thinking block only → BLOCK ("i assume", "probably"); multi-word terms → BLOCK ("seems to", "should be fine"); stop_hook_active=true → silent.

Registered in .claude/settings.json under hooks.Stop, alongside forbidden-doubles-stop.sh.