# Overclaim confession — lane f4 (wifi-pqc failure lab), site-program 2026-09

Written 2026-09-04, at the close of the lane. Every item is measured and carries the path that
settles it. Nothing here is softened, and nothing is included because it is flattering: the estate's
whole argument is that a stranger can check us, and this file is the part of that argument that costs
something. Read it before anything we claim.

---

## I. The two things that were only found because a check was made to fail first

**1. The guard I added to catch my own retracted number would have reported clean over it.**

A number this lane published — "the claim checker refuted **3 of 8** material claims on the Kyber
reference" — was wrong. The figures are **2 of 8** on that reference, 1 of 9 on its sibling and 0 of
7 on the formally verified implementation, and the fix was to add an entry to the repository's retraction guard so the
wording could never come back. The rule of this program is to watch a new check fire before trusting
it. It did not fire where it mattered. With the guard's global correcting-context list the entry
**saw 7 occurrences and reported 2**, and the three it missed were the only three that were live:
`tools/lane_register.py:404`, `lane_register.json:1112`, `LANE_REGISTER_2026-09.md:95`.

The reason is worth stating exactly, because it generalises. The guard treats a retracted phrase as
harmless when a *correcting marker* appears within 700 characters — that is how a retraction ledger
can quote the thing it retracts. One of those markers is the word `REFUTED`. The register row that
carried the defect is a claim-checker row, and its own tally reads `REPRODUCED 5, PARTIAL 4,
REFUTED 1`. **The defect contained the word that means "this text is a correction", so the defect
was read as its own correction.**

This is the second time this exact hole has been found in that one file. Its docstring already
records that `is measured` was removed from the marker list because the stale sentence it was meant
to correct *began* "Binding is measured". A correcting-context rule is a hole generator. Entries may
now carry their own markers, chosen so none can occur in that entry's defect, and both runs are kept:
`out/s14_stale_globalcorr.txt` is the run that missed it, `out/s14_stale_perentry.txt` the run that
caught it, and `tests/test_stale_retraction_kyber.py` plants both directions.

**Had the order been "fix, then add the check", the check would have passed, the number would have
been fixed in one place, and the guard would have reported a clean tree over the two copies still
carrying it.**

**2. Making a checker RUN the printed recipe found that the recipe did not run.**

The content package prints a verification recipe for a stranger: `make clean && make check` inside
the certificate bundle. The package's own check does not read that string, it executes it, from a
fresh copy, negative controls first. It exited **2**:

```
cc -std=c99 -Wall -Wextra -Werror -pedantic -O2 src/farkas_check.c -o bin/farkas_check
./verify.sh
make: ./verify.sh: Permission denied
```

The outbox builder wrote bytes and dropped the file mode. Three shipped executables — `verify.sh`
and `pce` in the verifier bundle, `bin/pco` in the renamed proof-carrying optimiser — were written
**100644 out of 100755 sources**. The bundles were byte-identical to the working originals, they
passed every content check, they were on the approved push list, and the first command a stranger
would run died on all three.

The previous step had verified `verify.sh` and reported it green. It ran it **in the source tree**,
where the executable bit was set — not in the bundle it had just built. **Content equality is not
equality, and a verification of the wrong copy is not a verification.** Fixed at the builder; both
re-verified from fresh copies (6 of 6 controls, acceptance count 1 of 6; `./bin/pco version` exits 0).

---

## II. Every place in this thread where a check stopped an overclaim, naming the check

| # | what would have shipped | what stopped it |
|---|---|---|
| 1 | "3 of 8 material claims refuted on Kyber", in every dataset card and on the site | Rebuilding the claim-BOM card **from** `artifacts/claimbom/*.bom.json` instead of transcribing the sentence. The correct figures are 2 of 8, 1 of 9, 0 of 7. |
| 2 | A retraction guard reporting a clean tree over three live copies of that number | The rule that a new check must be **watched failing** before it is trusted (section I.1) |
| 3 | A certificate bundle whose first command dies with "Permission denied" | `tools/check_site_package.py` check 7, *the printed recipe was followed*, which runs the recipe rather than printing it (section I.2) |
| 4 | The operator's home directory path, `/Users/<redacted>/...`, inside a public dataset of prover transcripts. **The account name is redacted here, and the redaction is itself part of the confession**: this file is rendered verbatim on a public page, and an estate does not publish the owner's home directory in order to prove that it once published the owner's home directory. What leaked was a machine path, and that is the whole fact — which account the laptop had adds nothing a reader needs and hands over something they should not have. | `oss/tools/check_surface.py` check 8, *no internal leaks* |
| 5 | An internal client name in the open-source reconciliation report | `oss/tools/check_surface.py` check 8, *no internal leaks* |
| 6 | Mechanism-private artifacts inside a published bundle | `oss/tools/check_surface.py` check 9, *no private paths, digests or names* — which refused this lane's **own** verifier bundle on its first run |
| 7 | **This confession naming two private paths.** The first version of this file cited a patent-shape working note and a private specification by path, inside the file that gets published verbatim | `tools/check_site_package.py` check 4, *I8 by content* — which scans every string in the package whether or not it is flagged public |
| 8 | **This confession restating "3 of 8"** with no correction adjacent to it — **twice, in both versions of this file**, the second time on the last build of the lane | `tools/check_site_package.py` check 8, *no retracted phrase restated* |
| 9 | **The ledger entry describing the fix** restating "kyber 3 of 8" with no correction adjacent — the entry now reads 2 of 8 — found today, at the last gate run of the lane | `tools/check_stale_retractions.py`, on its own |
| 10 | A package that does not validate, because a ruling said `url: null` and the schema types `url` as a string | Testing the ruling against the validator instead of implementing it. Absence is an absent key. |
| 11 | "`pqc-sizes window` exits 0 on an empty window" | Re-measuring the exit code **without a pipe**. Through a pipe, `$?` is the pipe's. It exits 1. |
| 12 | A mutation control that "passed" because the tool crashed with a traceback, exit 1, rather than because it detected the mutation | Printing the raw exit block before recording the verdict |
| 13 | A payload-verifier boundary mislabelled, because the rule keyed on whether an exit code was *valid* rather than whether it was the *expected* one | The same raw-block discipline; it would have hidden the exact boundary the contribution exists to state |
| 14 | Six of ten sealed predictions recorded as target failures when they were bugs in **my own tools** — a key read at the wrong depth, a prover flag never passed, float division where integer division was meant, a harness that failed to compile with exit 127 read as a refutation | The rule that a divergence is a finding about the instrument until proven otherwise |
| 15 | A commit count published as a property of the work rather than as a fact about one minute | Rebuilding twice and watching the number move (85, then 87). This repository's own record, R22, says a push count is a moving fact and not a limit. |

**Item 16 has no check in the right-hand column, and that is the point.** While writing section III of
this file I measured the coverage of my own number-pinning check and found it exempted **49 of the 64
figures** in the package's graded sentences — including the `2` and the `8` of "2 of 8 material
claims", the exact number this lane got wrong. A pin that skips the figure the whole retraction was
about is not a pin. Nothing caught this. It was caught by the requirement to state a filter's recall
cost **as a number**, which is a different instrument from a check, and a better one on this occasion.
The exemption is now 23 tokens instead of 42, coverage is **59 of 64 figures**, and the tightening
produced **zero** new failures — meaning every figure the wide set was hiding had been in its receipt
all along, and the width bought nothing but a weaker check.

**Item 17, same class.** The generator read one figure as `ip3.get("n_checks") or ... or 24`. The
fallback never fired, and it was still the defect the generator exists to prevent: a typed number
waiting for the day a key moves, which would then be silently wrong and would still pass the pin,
because the number it invented would be the number it checked. It now raises instead.

---

## III. Every filter I wrote that suppressed signal along with noise, with the cost as a number

| filter | why it exists | recall cost, measured |
|---|---|---|
| `GENERIC_BASENAMES` in the surface denylist | The literal-name leg fired on the words `SPEC.md` and `vectors.json` and refused this lane's own bundle | **2 of 11** private artifacts lose the literal-name leg (a private specification and its vector file, both generically named). They keep the path leg and the byte-digest leg, and a planted control proves the digest leg still refuses that specification's bytes under any filename. A published file that names it *in prose* is no longer caught. |
| Per-entry correcting markers on the retraction entry | The global markers include the word inside the defect (section I.1) | This entry recognises **5** markers where the global list has **20**. A genuine correction phrased in any of the other 15 idioms will be reported as a live defect. I chose a false-positive risk over a false-negative one; that is a judgement, not a measurement. |
| Splitting the file denylist for prose | Applying it whole would refuse the seal paths that the receipt rule *requires* beside every graded claim | **2 of 10** rules are not enforced on the package's text. Measured against the finished package, the excluded rules would have flagged **17** occurrences, all of one admission-engine name that the register's own limits carry and the envelope must publish unsoftened. The engine source is not published; the two file-name rules for it stay enforced. Both exclusions are printed inside the checker beside the reason. |
| The number-pin exemption | Dates and standard identifiers are not measurements | Was **49 of 64** figures unchecked (23% pinned). Now **5 of 64** (92% pinned). See item 16 above. |
| The `out/` carve-out in the retraction test | The guard reads its own transcripts of a defect as the defect | Of **69** live rows today, **4** are in source files and **65** are inside receipts of runs that *caught* something. The test asserts only that no source file restates the figure. The 65 are not asserted about at all. |
| Withholding private filenames from copied register cells | A limitation may be published; the private artifact's name may not | **7** filenames withheld across **6** of 108 envelope rows. Every limitation is stated in full, only the filename is withheld, and the count is published inside the envelope itself rather than left to be noticed. |

**The `out/` carve-out has a second cost that is mine.** The retraction guard's live count went from
**13 to 69** in one step, because the previous step committed four transcripts of the guard's own runs
into the tree the guard scans. Every future run inflates it further. That is the documented behaviour
of this class (a guard's record of a defect read as the defect), amplified by my own decision to keep
the receipts. Keeping them is right — the first wrong run's receipt is evidence — and the growth is a
real defect in how this guard and its receipts coexist. It is recorded, not fixed, because fixing it
means changing what the guard scans, and a check is not edited to make a number look better.

---

## IV. The numbers in the content package I am least sure of, and the exact experiment that settles each

| number | why I doubt it | the experiment that settles it |
|---|---|---|
| The adaptive-cap gate's "19 of 19 breaks" | The committed artifact says 19 of 19; running it today says **18 of 19**, red on no-starvation. The harness's 15 bad cases all redden no-starvation alongside their own check, so the committed count may be a sum over co-reddening cases rather than 19 independent ones. | Run each of the 19 breaks **in isolation** and record which redden no-starvation on their own. If fewer than 19 do, the committed count was never 19 independent breaks and the register title is wrong, not merely stale. |
| Self-attestation, 824 of 954 criteria | Regenerating gives 816 of 956, because 39 more artifacts exist than when it was committed. Both runs are honest; neither is stable. | Pin the artifact set by checking out a named commit into a clean tree, run the boundary tool twice, and publish the pair with that commit. A floor that moves with the tree is a floor for one tree. |
| "2 of 8 material claims refuted" on the Kyber reference | It is corrected, but it is still **unsealed**: the run predates the seal discipline here, and the claim list is an input the instrument chose. The package says so in the row rather than dressing it up. | Freeze a claim list and a materiality rule in a sealed prediction **before** the target repository is read, then re-run. Until that exists this row is a demonstration, not an indictment. |
| The envelope's provable margin, about 2^-16.5 | The hash-query budget and the pseudorandom-function assumption are **sealed inputs, not measurements**. The signature term is symbolic because no anchor for it exists in this tree. | Recompute with the buyer's own query budget through the tool's `--q-h-log2` flag, and add a core-SVP anchor for the signature scheme. Adding it can only make the envelope larger, never smaller. |
| Every live-or-absent status in the artifacts section | A registry answer is a fact about one date. **This changed under me during this lane**: the networks domain was unregistered when I inventoried it and is registered now. | Re-run the surface instrument. It carries the timestamp of the run the package used, and every row states the date it was true on. |
| The beacon on-air reduction, 13.55x | The on-air byte reduction is stable across runs; the CPU intervals beside it move with host load. | Quote the on-air figure only, from its own artifact. The CPU figures need a quiet host and a stated load, and this lane has neither. |
| "24 of 24 interoperability checks pass" | The library versions are **recorded, not sealed**: on a host with different libraries the contract reproduces against *those* libraries and the version strings move. | Re-run on a second host with pinned upstream tarballs and compare the version fields, not just the pass count. |

---

## V. The errors this program's own orchestrator made, which belong in the estate's record and not only in mine

These are not mine and I did not catch most of them. They are here because an honesty section that
only confesses downward is an advertisement.

1. **A census answered from thirteen recalled names instead of an enumeration of the trees**, and
   reported as "zero publishes in this program" and "one package on the index". Both halves were
   wrong. The enumeration found **nine** of the estate's packages published, eight predating this
   program and one published by it. This is the "do the whole list, never a sample" rule, violated by
   the instrument that grades the lanes on that rule. A lane caught it. **My own instrument can
   corroborate only 2 of the 9 and is blind to the other 7**, because its list holds 45 named surfaces
   and the enumeration walked 94. A sample that agrees with a census is not a census, and mine is a
   sample.
2. **A concurrency fix declared done that was not.** Making each write atomic did not make a
   read-modify-write atomic. Seven lanes' state records were silently erased and four turns died after
   running and being paid for. A lost update announces nothing; that is what makes it the worst class.
   The control now reproduces it: 1 of 7 survive under the old pattern, 7 of 7 under the new.
3. **A ruling that could not validate.** Artifacts under an organisation that does not exist were to
   carry a null address; the schema types that field as a string, so the ruling made the package
   invalid. Two lanes measured it and omitted the key instead. The ruling was wrong and the lanes were
   right.
4. **Four smaller ones that touched this lane**: telling a lane its publish guard was fixed when it
   was not; asserting a branch had never been pushed when it was pushed on eight of nine lanes, which
   this lane disproved by reading its own remote; propagating this lane's "3 of 8" into 28 note files;
   and validating a stranger-verifier claim from a developer's environment with the tools already on
   the interpreter's path — which is the same defect as running a reproduce command that reads a file
   we wrote.

---

## VI. What a buyer's engineer finds in the first hour that we did not mention

1. **The repository is private, and nothing in this program is reachable.** The public surface is
   eleven repositories and two datasets frozen on 2026-08-18. Everything built since sits on an
   unpushed branch.
2. **Nothing is installable.** Four Python names and one JavaScript name are built, package-checked
   and **absent from both indexes**; a sixth name is a third party's. No page prints an install line
   for any of them, which is honest and also means there is no fast path to trying the work. The
   organisation the bundles were built for **still does not exist on either index today**, measured
   this afternoon, even though the domain was bought this morning.
3. **No third party has run any of it.** The externally-validated count is **zero**. The conformance
   kit, the remediation test vectors and the protocol certificates have been offered to no working
   group and executed by nobody outside this estate. Every "graded" claim here is graded by *our*
   instrument against *their* published text.
4. **One gate is red today and one check has a false positive nobody fixed.** The adaptive-cap gate
   fails 18 of 19. A surface check flags a quoted line in a diff that records a dead link being
   *removed*. Neither is hidden; the second is not fixed because fixing it means editing a check.
5. **Five of twelve research seals diverged.** Every one is written up as a negative result with the
   bar it missed, but a reader who counts before reading sees five failures, and should.
6. **A gate outside this lane's own set fails.** The kit's status-versus-receipts gate reports **5
   contradictions and 13 unreceipted claims** against this register — identically before and after the
   last two steps, so it is nobody's regression, and it is also nobody's fix. It says some rows claim
   to have run while their own stored receipt says the command failed.
7. **The formal results are model-relative, everywhere, and say so.** A symbolic prover's RESIST is a
   statement about a model of a simplified protocol, not about deployed code. The machine-checked
   bounds are over modelled event lists. The impossibility results are over declared abstractions. An
   engineer looking for a claim about a specific access point's source code will not find one here.
8. **The raw evidence is private.** Thirteen packet captures, a 70-megabyte event stream and the
   mechanism-detail artifacts stay out. Only hashes, counts and semantics are published. That is
   deliberate, and it means several numbers on the page cannot be recomputed from what is published —
   only checked for internal consistency.
9. **The largest single claim on the page is the smallest one.** The hero is an inequality between two
   published constants: a signature is 3,309 bytes, a management frame carries 2,304. It needs none of
   the above to be true. Everything else does.

---

## VII. Two self-check passes

The instruction was two passes minimum, on the grounds that this estate's record says one was never
enough. It did not assume two are either, and neither do I: both passes found something, which is
evidence that a third would too.

**Pass one, against the requirements.** Checked this file against what it was asked to contain, item
by item. It found section II item 16 — that the number-pinning check exempted 49 of 64 figures — which
existed only because the instruction demanded a *number* for each filter's recall cost, and the number
had never been computed. Tightened to 59 of 64, measured, zero new failures.

**Pass two, against the tree.** Re-ran every gate and re-read every claim in this file against its
receipt. It found four things. The generator's `or 24` fallback (item 17), now a hard failure. A
statement in the previous version of this file that the networks domain was **unregistered**, which
was true when written and is false now: the domain resolves today, the two organisations still do
not, and I re-probed all three rather than trust either version. The claim "8 of 9 surface checks"
needed the ninth named, not counted. And the retraction guard fired on the ledger entry describing the
fix, which is item 9 in section II and was found by the gate run, not by me.

**What a third pass would look for, since I am asserting two is not obviously enough.** Every number
in this file that I copied from an earlier step rather than recomputing this turn; the 65 unasserted
retraction rows inside receipts; and whether the checks I wrote this week have controls that would
still fire if the thing they check were rewritten rather than deleted.
