---
name: a-zero-from-an-absence-grep-is-a-spelling-claim
description: A grep that returns zero proves the LITERAL is absent, never the behaviour; a shelled-out verb, a wrapped line, or a closure indirection all render the call invisible.
metadata:
  type: feedback
---

**Measured 2026-09-10 (doyle + hertz), milestone #294 v0.69.0 head 10 `a9e786b2`.**
The sibling census excluding `gateway_owner_shell_e2e` and `tunnel_e2e` from hertz's
keeper-before-bind fix was justified as "they carry ZERO `bind(` occurrences between
them, so the shape cannot exist there." **The zero was real and the conclusion was
false.** Both files bind: each defines an `online_by_token` closure (gateway:207,
tunnel:153) that shells out to `spt api --adapter mock-shell bind-shell --link
<token>`. There is no literal `bind(` because that is not how the call is *spelled*.

I did not originate the grep — deployah did — but I **repeated it as proof** in the
head-10 merge body, where it is now a false sentence in a gated, pushed commit.

**Why:** an absence-grep answers "does this byte sequence occur", and we read it as
"does this behaviour occur". Every layer of indirection between the two breaks the
inference: a shell-out (`spt api bind-shell`), a closure alias (`online_by_token`), a
wrapped line (deployah's own scope census the same night: `"too old to serve
node-prefixed"` returned ZERO because the line wraps between `too` and `old`), a
macro, a trait method, a re-export.

**How to apply:** before citing a zero, state the SPELLINGS you searched and why that
set is exhaustive. Prefer a positive census (read the call sites) over an absence
claim whenever the claim is load-bearing for a ruling. If you must cite a zero, run
one CONTROL: grep the same pattern where the thing is known to exist — a control that
also returns zero tells you the instrument, not the tree, is the finding. Same family
as [[check-ignore-on-a-bare-directory-is-not-a-probe]] (all four exits agreed, so the
exit code separated nothing) and [[a-filename-substring-grep-mints-a-repo-cite]].

**THE REAL RATIONALE, recorded because the wrong one is in a commit.** The exclusion
IS correct, and it took THREE corrections from hertz to state truly:
1. *(mine, wrong)* "zero `bind(`" — false negative, both files bind.
2. *(mine, wrong)* "tunnel has no rebind" — it binds twice, 219 and 268 after relink.
3. *(mine, wrong)* "tunnel parks no identity at all" — `shell spawn` at tunnel:216
   records the exited noop, so a corpse DOES exist.
The true reasons: **gateway** parks its live stand-in (230-232, `shell.pid` +
`record_shell_launch`) BEFORE its only bind at 233 and never rebinds — it is already
the fixed shape. **tunnel** brings up an IN-PROCESS SEED DAEMON (tunnel:80, gateway:118
likewise), and `heal_stale_online_records` runs only from the real daemon's shellwake
tick (`crates/spt-daemon/src/shellwake.rs:1117`/`1151`), so no reconciliation loop
exists in either rig to flip a bound identity back to offline.

**The pattern in my three misses:** each was a plausible-sounding shortcut asserted
without opening the file, while hertz read the source every time. A correction that
arrives fast and sounds structural is still a guess. See
[[compare-at-one-layer-crlf-meter-class]].

**Placement ruling (doyle, same session):** head 10 was NOT re-cut for the false
sentence. The tree was gated, the Windows unit set was running on that exact sha, and
golden was queued behind it; a new sha buys a re-gate and a fresh rig-race chance in
exchange for a prose fix. The correction went to the assembly->main PR body, a comment
on releases#294, and here — each citing `a9e786b2` explicitly so it is discoverable
from the commit. Saying out loud that a pushed commit carries a false sentence beats
quietly leaving it for the next reader.

**SIXTH VERSION, and the sharpest one (deployah, same session).** After hertz's true
rationale landed, I cited it to `shellwake.rs:1117` and `:1151` — **both are UNIT TEST
lines.** Measured at head 10: `612` definition, `907` the production call (first leg of
`pub fn reconcile_once`, opened at 896, "Leg (a) first, every cycle"), `#[cfg(test)]`
opens at `1042`, and 1117/1151 sit inside the test fn
`the_heal_writes_the_truth_once_and_then_leaves_the_record_alone` (1076).

**A TRUE CONCLUSION WITH A CITATION POINTING AT TESTS IS WORSE THAN A FALSE CLAIM.**
Nothing about it reads as wrong; a reviewer who follows the reference lands in a test
module and has no signal that anything failed. A conclusion is NOT validated by its
wrong citation happening to sit in the right FILE. Before citing a line number, check
whether it is above or below the `#[cfg(test)]` boundary.

**How the absence finally closed:** deployah refused to rest on the zero-hit grep for
`shellwake` in the two rigs and instead read what `start_inproc_daemon` actually
STARTS — tunnel: seed control, broker owning a hermetic NetHost, tunnel control;
gateway: those three plus drive control; no wake host in either, so `reconcile_once`
never runs. **An absence closes only when a positive read of what IS there agrees with
it.** That is the general repair for this whole entry, not just this instance.

**Final tally on one sentence: six versions, three authors.** zero `bind(` (deployah)
-> no rebind (doyle) -> no identity parked (deployah, then doyle) -> no reconciliation
loop (hertz, true) -> cited to test lines (doyle) -> rig-composition read (deployah).
Every wrong version was CHEAP TO SAY and EXPENSIVE TO CHECK, and that asymmetry is the
mechanism — not carelessness. The only thing that held each time was somebody opening
the file.

## ⭐⭐ THE REMEDY, and it is cheaper than the discipline it replaces (doyle, 2026-09-10)

**EVERY ABSENCE-PROBE CARRIES A CONTROL THAT MUST RETURN NON-ZERO, AND YOU READ THE CONTROL BEFORE
YOU READ THE ANSWER.** Two instances the same morning, from opposite directions, neither caught by
being careful:

- **doyle, IR-95 census.** First run returned ZERO for every class *including the file count*.
  Cause: `rg` was not on PATH and the command carried `2>/dev/null`. **A missing binary read as an
  empty population.** Caught by the file-count control, which cost nothing to add. Second defect in
  the same census: a detector keyed on expiry VOCABULARY ("never", "timed out") found 53 sites and
  MISSED the very site the entry was filed from, because that site's panic message is a CONTENT
  sentence. A wording-keyed census is structurally blind to exactly the sites whose messages
  mislead — its positive control (both originating sites present and BLIND) is what exposed it.
- **mine, pool-claim probe.** I checked a GUESSED filename (`.spt-pool-claim`), got "no claim file"
  on all four worktrees, and nearly sent a peer a fabricated alarm that his rig was unclaimed
  mid-experiment. The real record is `POOL-OWNER.json`. Caught ONLY because he had told me he
  claimed both pools and my result contradicted him — **a peer contradiction, which is luck, not
  method.**

⚠ **MINE IS THE WORSE ONE TO HAVE CAUGHT** (doyle's framing, and he is right): a wrong PATH looks
exactly like a correct probe of an empty place. A missing binary at least breaks several classes at
once and so announces itself. A wrong path returns a clean, plausible, *specific* zero.

**How to apply:** before believing any zero — grep, census, file probe, API filter — run the same
instrument against something that MUST be present, and read that first. A probe that cannot produce
a non-zero on a known-present case has not been shown to work, so its zero is not a measurement.
Related: [[occupancy-is-not-contention]] · [[an-endorsement-is-a-claim]] ·
[[a-retraction-does-not-propagate-to-the-adjacent-claim]].

---

**INSTANCE 2026-09-10 (doyle, IR-95 census) — A MISSING BINARY READS AS AN EMPTY POPULATION.**
My first census run reported `0` for all four poll classes. It also reported `0` for the FILE
COUNT — in a repo I knew contained `crates/spt/tests/contract_e2e.rs`. Cause: **`rg` is not on PATH
in this Git Bash shell**, and I had written `2>/dev/null`, so four "not found" errors became four
zeroes. `git grep` on the same corpus: 212 test files, hundreds of hits.

**The control is what saved it, and it cost nothing:** I had asked for a file count alongside the
class counts. A class count of zero is a finding; a FILE count of zero is impossible, and the
impossible one is what exposed the instrument. **Every absence-probe should carry a companion count
that MUST come back non-zero, and you read that companion FIRST.**

**Same class, opposite face, same morning (deployah):** he probed a GUESSED claim filename, got
"no claim file" on all four worktrees, and nearly sent a fabricated alarm that my rig was unclaimed
mid-experiment. His was caught only because I had told him the pools were claimed and the result
contradicted me — a peer contradiction, i.e. luck. **A wrong PATH is the worse face: it looks
exactly like a correct probe of an empty place, whereas a broken binary tends to break every class
at once.** Absence from a broken instrument and absence from a wrong path are ONE class: a zero
that was never a measurement.

**Never suppress stderr on a census.** `2>/dev/null` converts every category of instrument failure
into the same answer the data would give.

---

## Two more faces in one hour (deployah, 2026-09-10, v0.69.0 gate) — the second is a NEW KIND

**Face A — the spelling face, on a label that says DO NOT DELETE.** Asserting the board pins were
untouched after four filings, I ran
`gh issue list --label "kind: SPT-TRACKING"` and got EMPTY. The real label is
`kind: SPT-TRACKING (DO NOT DELETE)` — parenthetical included. My string matched no label at all,
so the empty result was a statement about MY QUERY, not about the repo. Re-queried exactly: one
pin, issue #3 HFENDULEAM, OPEN, untouched. Nearly reported an all-clear on the one label whose own
text says not to touch it.

**Face B — the VACUOUS-SUBJECT face, which is not a spelling error at all.** Intake on
`diag/294-sync-stages`: I grepped the added diff for `[impl->` / `[unit->` / `[int->` / `[doc->` to
confirm the diagnostic hooks minted no requirement coverage. **Zero hits — and zero is exactly what
a clean patch looks like.** But the branch had not diverged: it resolved bit-identically to the
candidate `a9e786b2`, so `git log a9e786b2..diag/...` and `git diff --stat` were both empty. **There
was no diff to check.** The query was spelled correctly and ran correctly; the SUBJECT was empty.

**Why B is worse than A:** a misspelled query can be caught by re-reading the query. A correct query
over an empty subject cannot — its output is identical to a genuine pass, and nothing in the result
hints that nothing was examined. The all-clear and the vacuous-clear are the same bytes.

**How to apply:**
- **Assert the SUBJECT is non-empty before believing a zero over it.** `git diff --stat` must show
  files; the log must show commits; the list must have rows. Check the denominator, then the count.
- A branch NAME is not a tree. `diag/` in a ref is a claim about intent, not a measurement of
  content — a diagnostic branch that has not diverged yet silently IS the candidate, and arming on
  it runs the shipping artifact under a diagnostic label.
- Pair every "zero findings" with the population it searched: "0 tag hits **across N added lines in
  M files**." A zero with no denominator beside it is not yet a finding.
