Skip to main content

LineageHeadReceipt

Struct LineageHeadReceipt 

Source
pub struct LineageHeadReceipt {
    pub receipt_version: String,
    pub registry_did: String,
    pub lineage_id: LineageId,
    pub head_ctx_id: CtxId,
    pub head_version: u32,
    pub head_status: String,
    pub as_of: DateTime<Utc>,
    pub signature: Signature,
}
Expand description

A registry-signed lineage-head receipt (RFC-ACDP-0011): the registry’s attestation that, as of as_of, the head of lineage_id was head_ctx_id at head_version with head_status.

CLOSED schema (acdp-lineage-head-receipt.schema.json, additionalProperties: false): every member is signed, so an unknown member changes the preimage and is rejected at parse time. The signing construction reuses RFC-ACDP-0010 §5 verbatim — JCS of the object minus signature, SHA-256, signature over the ASCII bytes of "sha256:<hex>" — with receipt_version acting as the in-preimage domain separator.

Unlike RegistryReceipt, head receipts are ephemeral: the head moves on every supersession, so a registry mints a fresh receipt (fresh as_of) per /current response (RFC-ACDP-0011 §6).

Fields§

§receipt_version: String

MUST be exactly LINEAGE_HEAD_RECEIPT_VERSION ("acdp-lhr/1").

§registry_did: String

The attesting registry’s DID — did:web:<authority> where <authority> is the registry’s serving authority (RFC-ACDP-0011 §4, did:web-only as RFC-ACDP-0010 §4).

§lineage_id: LineageId

The attested lineage (RFC-ACDP-0001 §5.6).

§head_ctx_id: CtxId

The ctx_id of the head version. Its authority MUST equal the method-specific identifier of registry_did (lineages are single-registry, RFC-ACDP-0004 §5.3).

§head_version: u32

The head’s body.version (≥ 1).

§head_status: String

The head’s registry-derived status at as_of (RFC-ACDP-0004 §4). Never superseded — a superseded version is never the head — and never retracted (RFC-ACDP-0013 §8.3: a retracted version is never served as head); in practice active or expired. Kept as the raw wire string so byte-for-byte comparison with the served registry_state.status is exact (RFC-ACDP-0011 §7 step 5).

§as_of: DateTime<Utc>

Registry response-time clock when the head claim was evaluated. Canonical millisecond-precision RFC 3339 UTC, always serialized with exactly three fractional digits (RFC-ACDP-0001 §5.3).

§signature: Signature

Registry signature over the receipt preimage — same envelope and same receipt signing key as RFC-ACDP-0010 §4/§5.

Implementations§

Source§

impl LineageHeadReceipt

Source

pub fn from_value(value: &Value) -> Result<Self, AcdpError>

Parse a head receipt from the JSON value carried in crate::body::FullContext::lineage_head_receipt, enforcing the closed schema plus the RFC-ACDP-0011 §4 semantic invariants (§7 step 1): exact receipt_version, head_version ≥ 1, head_status pattern and never superseded, did:web-only registry_did, canonical millisecond as_of byte form.

Source

pub fn preimage_hash_of_value(value: &Value) -> Result<ContentHash, AcdpError>

Compute the preimage hash from the RAW wire JSON of a head receipt (the value minus signature, canonicalized as received). Verifiers MUST hash the receipt exactly as received — same raw-JSON rule as RegistryReceipt::preimage_hash_of_value.

Source

pub fn validate_as_of_form(value: &Value) -> Result<(), AcdpError>

Validate the §4 byte form of the raw as_of: canonical millisecond-precision RFC 3339 UTC with exactly three fractional digits and a literal Z.

Source

pub fn preimage_hash(&self) -> Result<ContentHash, AcdpError>

Compute the receipt’s signature preimage hash from the struct. Used at MINT time; verifiers should prefer Self::preimage_hash_of_value over the raw wire JSON.

Source

pub fn verify_signature_with_key( &self, registry_pub_ed25519: Option<&[u8; 32]>, registry_pub_p256_sec1: Option<&[u8]>, ) -> Result<(), AcdpError>

Verify the receipt signature against a known registry public key (pure — no DID resolution; the client feature’s verify_lineage_head_receipt_value resolves the registry DID and calls this).

Source

pub fn verify_signature_against_hash( &self, hash: &ContentHash, registry_pub_ed25519: Option<&[u8; 32]>, registry_pub_p256_sec1: Option<&[u8]>, ) -> Result<(), AcdpError>

Like Self::verify_signature_with_key but over an already-computed preimage hash — pair with Self::preimage_hash_of_value for raw-JSON verification.

Source

pub fn cross_check_registry_binding( &self, serving_authority: &str, capabilities_registry_did: &str, ) -> Result<(), AcdpError>

RFC-ACDP-0011 §7 step 3 — registry binding (pure):

  • registry_did equals did:web:<serving_authority> — the authority the response was actually fetched from;
  • registry_did equals capabilities.registry_did;
  • the DID portion of signature.key_id equals registry_did;
  • the authority component of head_ctx_id equals the method-specific identifier of registry_did (lineages are single-registry).
Source

pub fn cross_check_lineage( &self, requested: &LineageId, ) -> Result<(), AcdpError>

RFC-ACDP-0011 §7 step 4 — lineage binding: lineage_id MUST equal the lineage the consumer requested (on /current) or the accompanying body.lineage_id (on full retrieval), byte-for-byte.

Source

pub fn cross_check_head( &self, served_ctx_id: &CtxId, served_version: u32, served_status: &Status, on_current_endpoint: bool, ) -> Result<(), AcdpError>

RFC-ACDP-0011 §7 steps 5 / 5b — head binding against the accompanying response.

on_current_endpoint = true for GET /lineages/{id}/current, where the receipt MUST describe the very head being served (step 5 byte-match, fixture lhr-002). On full retrieval the step-5 match applies when head_ctx_id equals the retrieved ctx_id; otherwise the receipt claims the retrieved context is stale and step 5b’s consistency rule applies (head_version strictly greater, served status superseded — or retracted on a registry also advertising acdp-registry-lifecycle, per the RFC-ACDP-0013 §7.2 precedence).

Source

pub fn check_as_of_skew( &self, now: DateTime<Utc>, max_clock_skew: Duration, ) -> Result<(), AcdpError>

RFC-ACDP-0011 §7 step 6 — as_of sanity against the consumer’s clock: millisecond-truncated (RFC-ACDP-0001 §5.3) and not in the future beyond max_clock_skew (RECOMMENDED 120 s). A future-dated as_of is a forged freshness claim (fixture lhr-004).

Note this is the verification half only. Staleness (an old but honest as_of) is consumer freshness policy (§6) — evaluate it separately via Self::age_at.

Source

pub fn age_at(&self, now: DateTime<Utc>) -> Duration

The receipt’s age at now — the input to the consumer’s §6 freshness policy (RECOMMENDED maximum: 300 seconds). Negative when as_of is ahead of now (bounded by the step-6 skew check).

Trait Implementations§

Source§

impl Clone for LineageHeadReceipt

Source§

fn clone(&self) -> LineageHeadReceipt

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for LineageHeadReceipt

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for LineageHeadReceipt

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Serialize for LineageHeadReceipt

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.