From b0aafc41e71f9244d592b142f0e7ff7e46264021 Mon Sep 17 00:00:00 2001 From: Eva <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@buzz.block.builderlab.xyz> Date: Thu, 20 Aug 2026 10:24:08 -0400 Subject: [PATCH] docs(nip-fi): classify every revalidation dependency and reread status at final admission The equivalence catch-all sent every unclassified field to identity-class byte-equality, but the provenance class named only snapshot version and verification-key identity. The remaining revalidation_dependencies members -- binding, lifecycle, local-policy, and resource versions; status source and version; proof and replay witnesses; the confidential JWS handle -- defaulted to byte-equality, making "changed dependencies require current revalidation to an equivalent result" unsatisfiable on any version bump and the concurrent-enrollment recompute never equivalent. Both readings failed closed; this was an availability and interoperability defect. The repair classifies every revalidation_dependencies member: bounds-class if it is a deadline, provenance-class otherwise, with the identity-class catch-all narrowed to assertion-content fields. Provenance-class ignoring is conditional on successful current revalidation, so it is safe only for members final admission actually rereads -- and the reread list at final admission named status nowhere, while the per-use check already checks status versions. Under the guards as literally written, demoting status to provenance-class would have let final admission admit with upstream status inactive: the one dependency the residual-revocation bound exists to close. Status joins the final-admission reread list. Verified by a bounded model of the composed system in two encodings (strict = inferred guards, literal = written guards only), 8748 reachable states per arm: baseline classification reads 0 authority extensions / 127 unsatisfiable in both encodings; the reclassification without the status reread reads 64 extensions under the literal encoding, all rooted in status_active=False; with the status reread, 0 extensions and 0 unsatisfiable in both encodings. Controls: a deadline demoted to provenance-class is detected (128 states, still detected against the fixed reread set), and a per-member sweep is structurally blind to the status defect -- only promoting a predicate's whole detector group exposes it. Delegated leases carry their own dependency list in NIP-FI-DELEG and were not remodelled; this classification governs the direct-path equivalence rule it amends. Co-authored-by: Eva <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@buzz.block.builderlab.xyz> Signed-off-by: Eva <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@buzz.block.builderlab.xyz> --- docs/nips/NIP-FI.md | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/docs/nips/NIP-FI.md b/docs/nips/NIP-FI.md index 8c6425bec9..cca673c6c0 100644 --- a/docs/nips/NIP-FI.md +++ b/docs/nips/NIP-FI.md @@ -383,22 +383,27 @@ Two verified assertion results are **equivalent** when: 1. identity-class fields are byte-equal: `iss`, `sub`, asserted-key presence and value, canonical claims/capabilities, `assertion_policy_id`, and `transport_contract_id`; -2. each bounds-class deadline is live now and is no later than its prepared - value; and +2. each bounds-class deadline — every `authority_deadlines` member, the + key-snapshot hard deadline, and any status deadline — is live now and is no + later than its prepared value; and 3. provenance-class fields — snapshot version, verification-key identity, - cache metadata, ordering, and retrieval time — are ignored after successful + status source and version, binding, lifecycle, local-policy, and resource + versions, proof and replay witnesses, the confidential JWS handle, cache + metadata, ordering, and retrieval time — are ignored after successful current revalidation. -Any new or unclassified field belongs to the identity class. A fresher assertion -cannot silently extend a prepared decision. [FI-TRACE-PREPARED-STALE] +Every `revalidation_dependencies` member is bounds-class if it is a deadline +and provenance-class otherwise. Any new or unclassified assertion-content field +belongs to the identity class. A fresher assertion cannot silently extend a +prepared decision. [FI-TRACE-PREPARED-STALE] Final admission atomically rereads binding, tombstone, revocation, enrollment, -policy, resource, replay, receipt, and invalidation witnesses; recomputes the -complete decision; claims applicable proof replay identities; creates an -eligible proposed binding; and appends its request-bound receipt and required -authorization evidence. All commit or none. A concurrent identical enrollment -may recompute as the same `existing` binding; conflicting enrollment commits at -most one winner. [FI-TRACE-CONCURRENT-ENROLLMENT] +policy, resource, status, replay, receipt, and invalidation witnesses; +recomputes the complete decision; claims applicable proof replay identities; +creates an eligible proposed binding; and appends its request-bound receipt and +required authorization evidence. All commit or none. A concurrent identical +enrollment may recompute as the same `existing` binding; conflicting enrollment +commits at most one winner. [FI-TRACE-CONCURRENT-ENROLLMENT] A failed admission rolls back all authority mutation. The application operation runs only after committed authorization. If it cannot share the transaction, a