Skip to content

finding: check-engine-double-contract.mjs states its DISCOVERED and PINNED population sizes in present-tense prose — 250 doubles is 487 today, 82 PINNED is 321 #9943

Description

@os-steve

Observation only — filed unassigned, not fixed. Found while working #9915, whose scope
was deliberately fenced to the figures --write invalidates.

What

#9915 fixed the prose in scripts/check-engine-double-contract.mjs that restated the
pinned ledger's size, because --write regenerates that ledger and silently
falsifies any copy of its size. That fence left a second, larger population of
self-describing figures in the same file untouched: numbers that describe the
DISCOVERED and PINNED populations the gate computes fresh on every run. Nothing
regenerates those into an artifact, so nothing was ever going to catch them either — and
they have drifted much further than the ones #9915 corrected.

The clearest instance, unwrapCallImpl's scope criterion (around line 646):

// Measured before it was written, over the 250 doubles this gate discovers:// the pair moves exactly 2, both of them #5945's witnesses, and 0 of the 82// PINNED doubles. Widening it is a measurement, not an opinion — re-run that// count before adding a name here.

Measured at origin/main today, from the gate's own output:

delete doubles: 227 in 206 test file(s) — 161 pinned to ObjectQL.delete's dispatch predicate, 66 in the shrink-only baseline.
update doubles: 260 in 236 test file(s) — 160 pinned to ObjectQL.update's dispatch predicate, 100 in the shrink-only baseline.
check-engine-double-contract: OK — 321 pinned, 133 in the DEBT ledger, 2 exempt.

So 250 doubles this gate discovers is 487 today (~1.9x), and 82 PINNED doubles is
321 (~3.9x). Both are written in the present tense (this gate discovers), so they
read as standing properties rather than as the dated measurement the first three words
(Measured before it was written) actually describe.

A second, softer instance is unwrapCallImpl's doc census (around line 478), which opens
every delete/update member whose initializer is a CallExpression, 310 of them, no truncation: and then lists eight callee spellings summing to 310, with 93 and 217
derived from it downstream. An independent approximate re-scan of *.test.ts under the
gate's scan roots counted 341 such members, with two buckets reproducing exactly
(39 and 3) while vi.fn() read 186 against the recorded 163 — so it has drifted in
the same direction. That number is only an approximation: the gate does not export its
own implOf walk, so the census cannot currently be re-derived by anything but a
hand-written copy of the criterion.

Why it might be worth a card

Same argument #9915 made, on a bigger drift. This comment ends re-run that count before adding a name here — it is explicitly an instruction to a future editor, and the numbers
it hands them are the ones they would calibrate against.

There is also a conflation hazard worth naming while someone is in here: the
CallExpression census figure was 310 and the pinned ledger is 310 rows. They are
different populations that happen to coincide, so a mechanical sweep for "prose repeating
the ledger size" flags the census line as a false positive, and a reader can reasonably
take one for the other.

What a fix would have to decide

Not mechanical, which is why this is filed rather than folded into #9915:

  1. Re-running the measurement is a measurement, not a prose edit. The conclusion
    (the pair moves exactly 2 ... and 0 of the 82 PINNED) could come out differently on
    a 487-double corpus, and if it does, the criterion — not the comment — is what needs
    revisiting.
  2. Refreshing the constants reproduces the defect with fresher values (the @objectstack/objectql/core's "268KB metadata protocol" figure is unverified at HEAD — the structural claim holds, the number does not reproduce #9803 /
    PR docs(objectql): drop the unverified "268KB" from the ./core boundary claim (#9803) #9909 lesson). The cheap non-measuring option is to anchor them as past tense with
    a date, the way finding: check-engine-double-contract.mjs hardcodes its own ledger size in 5 prose sites that go stale on every --write, with nothing to catch them #9915 did for the one figure it could not derive.
  3. The census at line 478 cannot be derived by anything today. Exporting the gate's own
    walk so the census can be regenerated would be the structural answer, and is a
    larger change than either.

Scope

Prose only, as filed. No invariant, criterion, exit code, population or output string is
affected at any of these sites — check:engine-double-contract is green at origin/main
with all of them present, and #9915's PR does not touch them.

Context: #9915 · #9680

Generated by Claude Code

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions