Deletion Semantics — Cross-Implementation Test

dataset · v1.0 · 2026-08-26 · 41 files · CC BY 4.0

A recorded removal and a never-landed write are observationally identical at the consumer boundary. Exposing the absence assertion on a machine-readable discovery surface is necessary and sufficient to separate them.

Fulfils the cross-test offered on knowledge-catalog#207. Three artifacts, none modified, none authored by the same party. Read FINDINGS.md first (v1.1, 2026-09-03: §8 reads the producer’s own repair live at 55e6493 — separable, necessary, reconciliation-distinguished, one keying finding); reproduce from clean clones with reproduce.sh; every pin is in source-lock.json. Tests the 111-case corpus next door.

The three artifacts

artifactrole
producerremember-okf-sample-bundle ea18185fremember/0.2 emitted shape — log, store, manifest, tombstones
consumerthroughline c512e8b9 · never_landed.pyassertion-consistency checker
corpusdeletion-conformance-fixture111 cases at v2.1, used in runs 01–07; v2.2 added six cases in response to this test; v2.3 (2026-09-03) annotates the producer’s shipped repair and adds two reconciliation cases

The collision

Three records, one convention. A created and present. B created, then removed — tombstone records presence, date, reason, successor. C creation asserted, never landed.

current consumer     A → present    B → never_landed    C → never_landed    B and C COLLIDE
repaired consumer    A → present    B → removed         C → never_landed    B and C DIVERGE

The producer recorded the removal faithfully. The consumer correctly reported a claim with no landing. The information is destroyed in the gap between them: the removal lives in tombstones.md prose, and the machine-readable index references no tombstones at all. Neither implementation is at fault.

Necessity and sufficiency

Lift the absence record into the machine index and add one consumer lookup — before calling a claim never-landed, ask whether an absence record survives for that identity — and B and C diverge, with A and the claim counts undisturbed. Strip the record while leaving the prose tombstone fully intact, and they collide again. The requirement is therefore not to record the removal, which the producer already did.

Normative form. A surviving absence assertion must be exposed on a machine-readable discovery surface that ordinary consumers consult. Preserving the same information only in prose is insufficient. Not “put tombstones in .manifest.json” — that is one producer's carrier, not a format primitive.

Translation receipts

Rendering the corpus into the producer's shape twice — strict, refusing anything requiring a key the emitter does not define, and forced, translating everything — produces the same clean downstream verdict by opposite means.

strictforced
source cases111111
expressible1111
refused untranslatable1100
preserved11
coerced0110
dropped4451
fabricated0110
downstream verdictcleanclean

The checker cannot distinguish the two runs; the receipt can, and its fidelity warning cannot be detached from the green result. Absence of an alarm is not evidence of preservation. refused is kept distinct from coerced: a translator that declines to represent what it cannot carry preserves integrity; one that silently forces it does not.

Stated limits

Representation portability is 1 of 111 while checker portability holds on two flags — different properties. The corpus under-represents the case the finding turns on: every expressible case is presence=removed, and exactly one never_landed case exists. The --id-key failure mode is a property of stores whose filenames diverge from stable ids, so a fixture on stem-named stores never exercises it. An earlier exploratory figure of 671 breaks reconciles exactly as 451 dropped + 110 coerced + 110 fabricated — the measurement became more discriminating; the quantity did not change.

Files

reports/FINDINGS.md12 KBThe argument, with every number sourced to a captured run. commands/reproduce.sh2 KBFull reproduction from clean clones of both third-party artifacts. sources/source-lock.json2 KBPinned commits, URLs, retrieval dates, and every command-line parameter. receipts/strict.json1 KBHonest translation: 1 expressible, 110 refused, nothing fabricated. receipts/forced.json2 KBLossy translation: 110 fabricated, 451 dropped, fidelity warning attached to the green verdict. profiles/forced-break-profile.json62 KBEvery field-level break, by case and category. translator/translate.py7 KBThe shape translator, strict and forced modes. translator/receipt.py4 KBReceipt generator with the fidelity ladder: preserving / partial_refusal / lossy. translator/repair.py4 KBMinimal absence record and the repaired consumer. MANIFEST.json1 KBDataset record. SHA256SUMS4 KBHash surface, 41 files.
Credit: the --id-key resolution path and the empty-log guard are @andrewcrenshaw's contributions to @inkxel's checker; the checker and the bundle are their work. This package composes them and adds the translation, the receipt, the fixture, and the repair test. Both published baselines reproduce exactly here — a third independent reproduction of each.