Skip to content

The host checks per-frame attestations only; a signed result set and its inclusion proofs are consumed by nothing #133

Description

@macanderson

Problem

contextgraph_types::attest defines three constructions (SPEC.md §6.5): a
provenance chain head, a per-frame commitment, and an RFC 6962 Merkle root
over a whole result set with InclusionProofs. The host now consumes the
second. It consumes neither merkle_root nor root_from_proof.

That leaves the headline use case from ADR 0010 unreachable through the host:
"prove this frame was in the answer, without showing me the rest." A provider
that signs its whole answer once — cheaper than N signatures, and the only
construction that supports selective disclosure — gets no credit: every frame
reads as AttestationState::Unattested.

What is needed

  • contextgraph_host::trust learns a result-set shape: one
    ProvenanceAttestation over a merkle_root, plus one InclusionProof per
    frame. Verify the root's signature once, then check each frame's inclusion
    proof against it, and record the outcome as the existing AttestationState
    so the audit does not grow a second vocabulary.
  • The same F9 discipline: a bad root, a bad proof, or a proof from a
    differently-shaped tree degrades the frame to unattested and never removes it.
  • The same bounded-work discipline: cap proof path length (a proof for a tree of
    N leaves has ceil(log2(N)) steps; anything longer is malformed and must be
    refused on its length before any hashing), and verify the root signature once
    per result rather than once per frame.

Constraints found while wiring the per-frame path

  • Attestations reach the host through ContextProvider::query_attested
    (contextgraph-host/src/provider.rs), a defaulted trait method returning
    AttestedQueryResult. A result-set attestation is a second field on that
    struct, not a second method.
  • The wire cannot carry either shape yet — see Carry ProvenanceAttestation on the wire (frames envelope + JSON Schema) #90.
  • InclusionProof::leaf_count is part of the proof precisely so a verifier
    cannot be shown a proof from a differently-sized tree; a host implementation
    that ignores it has the bug the field exists to prevent.

Files

  • contextgraph-host/src/trust.rs
  • contextgraph-types/src/attest.rsmerkle_root, inclusion_proof, root_from_proof
  • contextgraph-host/tests/attestation_composition.rs — where the tests go

Definition of done

  • A host verifying a result-set attestation marks each proven frame
    attested, through the same AttestationState and the same audit field.
  • A test proves a frame with a valid inclusion proof under a signed root is
    attested, and one with a proof from a differently-shaped tree is not.
  • A test proves F9 holds: a malformed root or proof leaves every frame
    served.
  • The root signature is verified once per result, not once per frame, and a
    test or a comment naming the bound says so.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Next cycle

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions