.claude/ instruction surface — designDate: 2026-08-18 Branch: claude/hil-doc-audit
hil-operator.md told an operator two incompatible things at once: one rule forbade pre-holding a board lock because hil_test.py self-locks, while a rule added in the same revision made the lock the thing that keeps concurrent operators off each other's hardware — so an operator following the second would take a hold that made its own run fail fast against it. Both statements were fixed before this branch was folded, so neither survives in history; what survives is the lesson that nothing checks these files against the code they describe.
That is not an isolated slip. A scan of the 36 repo paths cited across .claude/ flags 8 that do not resolve. Five are legitimate — placeholders (docs/changelog/X.Y.Z.md, src/portable/x/dcd_x.c, a test_*.py glob), a generated file (examples/cmake-build-pvs/compile_commands.json), and a per-host gitignored config (test/hil/local.json, whose absence the skill already handles). Three are drift: usbtest/SKILL.md:24,50 cites src/usb_descriptors.h and src/tusb_config.h, which are example-relative but read as repo paths, and :101 cites tools/usb/testusb.c, a Linux kernel path presented like a repo file.
Cross-references are in better shape: every agentType in a workflow resolves to an agent in .claude/agents/, every .claude/skills/<name> referenced by an agent or workflow exists, and the workflow scripts call only harness functions that exist. The drift is in prose claims about behavior — the class that made hil-validate parallelize at the wrong layer, on top of a hil_test.py that already schedules boards across host controllers under per-controller permits (hil_lock.py:7,133-134; hil_test.py:2249,2419).
In: .claude/agents/*.md (7), .claude/workflows/*.js + check.sh (7), .claude/skills/*/SKILL.md (16) and their 8 helper scripts, and the repo CLAUDE.md. ~4,700 lines (2,874 of prose, the rest helper scripts and etm-trace/boards.md).
Out: docs/superpowers/** (historical records — correcting them rewrites history rather than fixing what a future session executes), .claude/settings*.json and hooks, the memory index, and any behavior change to the scripts themselves.
Only falsifiable classes get a verdict. Guidance (“bias toward caution”) is checked solely for contradiction with the classes below.
| Class | Settled by | Example |
|---|---|---|
| Path | ls/find, with the base dir made explicit | src/tusb_config.h — example-relative, reads as repo-relative |
| Interface | argparse/grep in the named source | -b is action='append' (hil_test.py:2249) |
| Behavior | reading the implementing code, cited file:line | “permits are in-process semaphores” (hil_lock.py:7) |
| Number | the constant's definition | FLASH_PARALLEL=4 (hil_lock.py:133) |
| Rig state | read-only ssh ci.lan probe | bus map, probe uids, sudoers entries, installed tools |
| Cross-doc | diffing the same rule's two statements | hil-operator.md:18 vs :37 |
file:line. Leave alone.A claim with no code backing is not a cut candidate when it is earned rig knowledge: an observed hardware quirk, a failure mode paid for in rig downtime, a workaround whose rationale lives only in the incident that produced it. Code is authoritative about code; experience is authoritative about hardware, and the hardware does not document itself.
Consequences:
file:line, verbatim claim, class, what source would settle it, and a flag for suspected hard-earned evidence. Agents return no judgments, so nothing arrives as a verdict that would have to be unwound.ssh ci.lan for rig state (ls, --help, which, lspci, lsusb, hil_lock.py status, sudo -l, uname -r — no locks, no flashing, no uhubctl, no recovery). Nothing acted on is taken on an extractor's word.hil-operator failure lived.check.sh on every workflow; bash -n and py_compile on all 8 helper scripts; the four test/hil suites; pre-commit run --all-files.| # | Cluster | Lines |
|---|---|---|
| 1 | .claude/agents/*.md (7 files) | 313 |
| 2 | .claude/workflows/*.js + check.sh | 659 |
| 3 | hil, hil-pool-check | 223 |
| 4 | usb-kernel-recover, usb-kernel-debug + 2 scripts | 253 + scripts |
| 5 | target-debug, esp-target-debug | 496 |
| 6 | usbtest, usbmon, usb-sniffer + usbcap.sh | 382 + script |
| 7 | etm-trace + boards.md + 2 scripts | 203 + files |
| 8 | build-doc, code-size, pvs, make-release, read-doc, pre-pr + 2 scripts | 345 + scripts |
| 9 | CLAUDE.md | 139 |
Commits split by surface (agents / workflows / skills / CLAUDE.md) so review stays tractable, on claude/claude-doc-audit. A findings report covering every REFUTED claim with its citation, and every earned-knowledge-vs-code disagreement found in pass 2.
A refuted claim whose code is the wrong half does not get a silent code edit: it becomes a handoff doc under docs/superpowers/followup/, per the repo's deferred-work rule.