Accepted adr-003 · 2026-09-25

An Attestation Is a Fact That Never Expires; How Long It May Be Used Is the Consumer's Profile, Measured From verified-at by the Verifier's Clock

Context

Attestations neither expire nor are revoked (backlog bl-006). The axiom verification-needs-only-public-material fixes what any answer may cost: an attestation is checked offline with the authority's public key alone, and a revoked key leaves what it attested valid. Deleting cannot invalidate: the store has no delete, the consumer keeps its copy, and a gap in the signed chain is detected. A revocation list would make every verification ask the authority. Measured 2026-09-25: the attestation already carries its time inside the signed payload — code/schemas/protocol.ncl requires exactly one `verified-at:<instant>` in every attestation's scope (the authority's clock when it verified the person's signature, protocol.ncl:349-377, with its rejected cases in the oracle), beside exactly one `act:<act>`; `signed-at:<instant>`, at most one, is the signer's own clock and "proves no instant" (protocol.ncl:353). code/crates/signatio-verify/src/payload.rs signs `signatio-attestation-v1`, the subject digest and the sorted scope; `signatio_verify::verify` takes no clock. What no one declares is how long an act, once attested, may still be used: that is a property of what the consumer enforces, and it differs by consumer and by act.

Decision

AN ATTESTATION CERTIFIES A PAST FACT, AND A FACT DOES NOT EXPIRE. That a person holding these hats signed this digest, verified by the authority at verified-at, stays true and stays verifiable offline for as long as the key that attested it is pinned. The authority never refuses, deletes or revokes an attestation by its age.

HOW LONG IT MAY BE USED IS THE CONSUMER'S, IN ITS PROFILE. An act of a profile may declare `max_age_seconds`, a positive integer: the longest an attestation of that act may be used after its verified-at. An act that declares none has no age limit. The window is part of the profile the consumer registers and pins, so it is covered by profile_digest: a consumer that changes a window changes the digest it pinned, and the provider's test copy and the consumer's both check it.

THE AGE IS MEASURED FROM verified-at, BY THE VERIFIER'S CLOCK. verified-at is the authority's instant, inside the signed payload and required by the contract; signed-at is the signer's and proves no instant, so it never measures an age. The verifier compares its own clock with verified-at: older than the act's window, the attestation is refused for that use — STALE, never INVALID, since its signature still verifies; a verified-at later than the verifier's clock is refused too.

VERIFICATION STAYS PURE. signatio_verify::verify keeps taking no clock; the age is a separate check that receives the instant from its caller and the window from the pinned profile, and asks no one. The verify crate keeps linking no network client and no library able to sign.

THE SIGNED FORMAT DOES NOT CHANGE. No field is added to the attestation and the payload keeps its domain signatio-attestation-v1: every attestation already issued carries the verified-at it is aged from.

Constraints

Alternatives considered