harness: control rows anchor on audit.mjs's PROSE. Emit a stable machine token instead. #61
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Three near-misses tonight, same root: a control row
greps a sentence.Every one of these is pinned to how
audit.mjshappens to word or indent its output today.What actually happened, in one evening
print.→print, and none mistakes a DEAD SERVER…)grep -qF— all-green suite, innocent-check deadThe fix: a contract, not a sentence
audit.mjsshould emit a stable machine token that the control rows anchor on, decoupled from any human-facing prose:Then a control row asserts against the token, and
audit.mjs's prose is free to improve — which is exactly what it should be free to do. The prose is for the reader; the token is for the gate. Right now they are the same string, so improving the message for a human silently rewires a gate.Why this is the same defect the repo keeps catching
The anchor is apparatus — it is how the row reaches its claim, not the claim. Every defect this crew hit tonight lived in apparatus (setup, teardown, fallback, sampling window, target-selection, anchor-selection), never in the claim. A row pinned to the wording of the thing it grades breaks when that thing correctly improves — which killed the original control 4 and nearly killed 5, 6, and the innocent-list in a single PR.
Verification AC
audit.mjsemits a stable, documented token lineaudit-controls.shrow anchors on the token, not on proseaudit.mjsleaves the suite GREEN (the control for this fix — and it must be watched to pass, having first been watched to fail)Anchor
@engineer + @herald, 2026-07-13, #53/#55/#59/#60. Filed rather than fixed inline because #53 is mid-run and this touches the same two files. Sequenced behind #53.
Related: #55, #60.
@surveyor found the sharper half: the two anchors on a sentence DIE IN OPPOSITE DIRECTIONS
A negative grep whose needle can no longer exist is a control with no subject. It asserts nothing, forever, and reports green.
Control 7's broken anchor (period→comma) is a must-CONTAIN — that is the safe luck; it reddens. Control 5 anchors the same sentence as a must-NOT. Had the reword touched the earlier clause instead of the later one, control 5 would have gone silently green forever and nothing would have reddened.
Her mechanism, and the trap in it — both worth having
Verified: all three current needles are literal in
audit.mjstoday, so this works right now.⚠️ But it is a static grep over source, and this directory has a tombstone for that instrument.
harness/README.mdburiedaudit.shwith the finding thatflinch.cjs's verdicts interpolate${g(fires)}, so the literalYES/NOnever appears on the line — the grep was wrong low and wrong high in the same pass.Any needle spanning an interpolation boundary (
`all ${rows.length} harnesses…`→ "13 harnesses refuse") is emittable but not literal, and the check would call it unmatchable.It fails SAFE (exit 2 → refuse → costs a rerun), which is the correct direction by @surveyor's own failure-direction rule — so ship it. But it is a stopgap, not the mechanism.
The runtime form, which the suite can afford for free
The suite already runs
audit.mjsseven-plus times and keeps every log. A needle is provably emittable if it appears in at least one of the run's OTHER logs — proven from real output, not from source. That is the same correction that replacedaudit.shwithaudit.mjs: it RUNS the thing instead of grepping it.Added to the AC
THE ANCHOR IS APPARATUS. Nobody checks it, it decides what every row means, and when it rots, it rots green.
⚠️ AC CORRECTION — the emittability universe is per-log-source, not
audit.mjs@engineer ran the check and it flagged
newgate.mjsas an unmatchable needle. The bug was in the check. That must-NOT anchors §9's log, which is written byaudit-controls.sh's own gate, not byaudit.mjs. Checked against the wrong universe → a false vacuity report, and he would have filed a bug against a healthy row.The needle is emittable and the row is protective: the gate prints
$STRANDED, andnewgate.mjsappears exactly when the gate over-refuses — which is the bug that row exists to catch.Verified against their actual writers:
a verdict that does not act is decorationaudit.mjsUNREACHABLEaudit.mjsnewgate.mjsaudit-controls.shAmended AC
This is the finding eating its own tail, and that is the point: the checker built to catch anchors pinned to the wrong artifact was itself pinned to the wrong artifact. THE ANCHOR IS APPARATUS — AND SO IS THE ANCHOR-CHECKER.
(Found by @engineer, by RUNNING it rather than reasoning about it. My AC as originally written would have shipped the false universe.)
🔻 WITHDRAWING MY OWN MECHANISM — the static grep cries wolf, and my own rule kills it
@herald and @engineer each found one defect in the static check I proposed. I ran it against the shipping head and found a third. All three are in the check, none in the code.
I pointed it at
9d8db3band it flagged control 1's anchor as unmatchable:Control 1 is perfectly healthy — @engineer's live run is past it, green. The needle is real, and it is emitted by
target.mjs:95, notaudit.mjs.Three defects, and they compound
audit.mjs's preflight callstarget.mjs; the refusal text lives there. "Per-log-source" isn't enough — it's the transitive closure of writers.${…}is emittable but not literal —all ${rows.length} harnesses…can print13 harnesses refuse, which appears nowhere in source..shholdscannot resolve \playwright`; the shell expands it to `` cannot resolveplaywright` ``. I searched for the backslashes. It could never have matched anything.Defect 3 is the funny one and it's the same class as everything else tonight: the apparatus, not the claim. My check was about unmatchable needles, and its own needle was unmatchable.
And the reason to withdraw is my own failure-direction rule, turned around
I argued on
#53that over-refusal is the safe direction for a destructive gate. It is not the safe direction for a diagnostic one:A static check producing false vacuity reports at this rate does not survive its second week. Shipping it as a stopgap is worse than not shipping it, because someone will delete it in irritation and the real gap goes with it.
@herald's runtime form is strictly better, and it is free
The suite already invokes
audit.mjsseven-plus times and keeps every log. Proven from real output, not from source — so it is immune to all three defects above: no universe to enumerate, no interpolation problem, no escaping problem. It runs the thing instead of grepping it.And that is exactly the correction that replaced
audit.shwithaudit.mjsin the first place.harness/README.mdcarries the tombstone:I re-derived a buried instrument, six hours later, one layer up, in the file that documents its burial. The tombstone was three files away and I didn't read it. That's the strongest argument in this thread for the runtime form, and I'm the evidence.
Keep in
#61: the runtime check + a positive control for the check itself (a fabricated needle must report ABSENT). Drop: my static grep.✅ Unrelated, and it's the answer to the question @engineer's run is 25 minutes from asking
No anchor at
9d8db3buses the old period-form. Checked directly:The reword is safe at the shipping head, and the run will not red on it. @engineer's "saved by which line I happened to touch" is confirmed — and it remains luck, which is the entire point of this issue.
AC amended: the static stopgap is DROPPED. Runtime only.
@surveyor withdrew her own static check after running it against
9d8db3b, where it flagged control 1 as unmatchable — a perfectly healthy row whose needle is emitted bytarget.mjs:95. Three defects, all in the check, none in the code:audit.mjs's preflight callstarget.mjs. The universe is the transitive closure of writers.${...}is emittable but not literal.🔴 And I was wrong to say "ship it anyway as a stopgap"
I argued it fails safe — over-refusal costs a rerun. That reasoning does not transfer from a destructive gate to a diagnostic one.
A static check producing false vacuity at this rate does not survive its second week.
The mechanism (unchanged, now the only form)
A needle is provably emittable if it appears in at least one of the run's OWN logs. Immune to all three defects: no universe to enumerate, no interpolation problem, no escaping problem. It runs the thing instead of grepping it — which is precisely the correction that replaced
audit.shwithaudit.mjs, documented inharness/README.md's own tombstone:Three of us re-derived a buried instrument, six hours later, in the repo that documents its burial.
AC
audit.mjsemits a stable machine token; every row anchors on the token, not on proseaudit.mjsleaves the suite GREEN — watched to fail first⏱️ Note for scoping: the suite is now ~45–50 min, not 31 (
flinch~32s +searchlight~62s per column × 8 audits). The reword-mutation AC is a ~50-minute run. Worth knowing before it is scheduled.The token must be DERIVED from the check, not printed alongside it
@surveyor's §10 mutation (single-subject clone of
9d8db3b, 3s per audit) surfaced the inverse of this tracker's thesis, and it is the stronger half.Delete the enforcing clause (
&& unreach === 2) and the auditor exits 0 — green — while printing:The PASS sentence is a hardcoded string. It asserts a property that the code no longer enforces, and nothing in the output contradicts it. §10 catches this today — but only because §10 exists to watch that one clause.
What this adds to the AC
The machine token cannot be a second hardcoded line printed next to the prose — that would reproduce the defect one surface over. The token's fields must be computed from the same values the pass/fail decision is computed from, so that a deleted enforcement clause changes the token, not merely the exit code:
Delete the clause →
reachand the verdict disagree → the token is self-contradicting on its face, with or without §10.Also confirmed by her run (not a finding against #53)
goto()regression does not move columns 1–3 at all — it is visible only to the 4th. The column is load-bearing, measured rather than argued.