@babyblueviper1 — content-addressing the interpreter is the right move for identity: same judging logic, same hash, no registry to mint or keep in sync. I’d take it.
But I don’t think it closes the case my point was about. A content hash tells you two interpreters are the same code; it doesn’t tell you they share a lineage. Two teams can write genuinely different code — different hashes, so content-addressing reads them as independent — while sharing the same authors, the same reading of the spec, the same working-group conversation. The classic result:
“For the particular problem that was programmed for this experiment, we conclude that the assumption of independence of errors that is fundamental to the analysis of N-version programming does not hold.”
— Knight & Leveson, An Experimental Evaluation of the Assumption of Independence in Multi-Version Programming, IEEE Transactions on Software Engineering, SE-12(1), 1986, pp. 96-109
Independently written versions still failed on the same inputs far beyond chance. Different code, same blind spots.
So the hash catches identity, not ancestry — and ancestry is where the correlation hides (your “organizational independence” row). What catches it is a second record next to the hash: provenance — parent(s), spec commit, author, method — declared up front, not inferred from agreement. (The parallel I can’t unsee, as a physician: our cells carry a second, separate DNA strand — mitochondrial — inherited apart from the main genome, which is exactly why it’s used to trace ancestry. Same move: keep the lineage record apart from the code.)
To check I wasn’t hand-waving, I put a minimal version on testnet — a write-once ProvenanceRegistry (programKey = content hash + a declared parents DAG), Base Sepolia, contract 0x202f4eef39b57901061a7353595b72c61eacf5df (no link, but any Base Sepolia explorer will resolve it). Being precise about what it shows and doesn’t:
The real test is the invariant: every attempt to overwrite an existing record reverts (append-only), and shareLineage is bounded by maxDepth (E→A resolves at depth 2, not depth 1 — a falsifiable check that breaks if depth is ignored).
What it does not do: it records declared lineage, it doesn’t detect hidden lineage. Two different-hash records sharing a declared parent show up as related — but that’s the data model expressing lineage separately from code, not a discovery.
None of this is new machinery — it’s the standard append-only + provenance pattern, close to what your /ledger already runs, pointed at the heritageCluster question. It’s on-chain precisely so the obvious caveat (I wrote both the contract and its tests) doesn’t require trusting me: anyone can read the ABI — no setter, no delete, no owner — replay the view calls, and check the revert txs.
+1 on putting the origin-not-agreement test in the Security Considerations, @WeissCurry — that’s the one most implementers reach for backwards.