Skip to content

Carry ProvenanceAttestation on the wire (frames envelope + JSON Schema) #90

Description

@macanderson

PR #87 defines ProvenanceAttestation and the constructions behind it, but no envelope transports it — a provider that signs a frame has nowhere to put the signature, so the feature is currently reachable only by out-of-band agreement.

Needed:

  • A place in the frames envelope for per-frame attestations and/or one result-set Merkle root attestation. Per F6 it stays detached: beside the frame, never inside it, so re-signing and key rotation never perturb the content-addressed identity.
  • The matching schema/contextgraph-envelope.schema.json definitions.
  • A wire example under examples/, which GOVERNANCE.md requires as the witness for a normative change.
  • Decide whether a signed result set carries inclusion proofs inline or a host derives them from the frames it received.

Additive within contextgraph/1 (new optional members), so no family bump.

Definition of done

  • ContextQueryResult carries the attestation, so it travels on every binding (stdio, HTTP, in-process) rather than only where an Envelope is built.
  • Per-frame evidence is a list of entries that each name the (provider_id, frame_id, content_digest) identity in full, never a parallel array indexed by position.
  • A single result-set attestation over the RFC 6962 Merkle root is representable.
  • Nothing added is required: an unsigned result serializes byte-for-byte as it did before, and a consumer that ignores the new members still parses a signed envelope. Covered by a test for each direction.
  • The attestation never appears inside a ContextFrame (F6) — asserted on the serialized bytes, not on the struct layout.
  • schema/contextgraph-envelope.schema.json defines the new members and their types, and python3 schema/validate-examples.py exits 0.
  • A signed wire example ships in both examples/reference-messages.json and examples/full-stdio-session.ndjson, and the reference-serialized vectors gain an attested line.
  • Every signature and Merkle root shipped in this repository is recomputed and cryptographically verified by a test, against a published example key — not asserted.
  • A witness test fails without the change and passes with it, checked by reverting the implementation.
  • The inclusion-proof decision (inline vs host-derived) is made and its reasoning recorded in an ADR under docs/adr/, with the ADR listed in the docs/GUIDE.md decision log.
  • SPEC.md states the wire carriage normatively, with new requirement anchors appended (never renumbering F1–F10).
  • CHANGELOG.md records the change under ## [Unreleased].
  • docs/protocol-surface.md's ContextQueryResult snippet matches the Rust type.
  • No protocol family bump: the change is additive within contextgraph/1.
  • cargo fmt -- --check and cargo clippy -p contextgraph-types -p contextgraph-conformance --all-targets are clean, and the touched crates' tests pass.

Metadata

Metadata

Assignees

No one assigned

    Labels

    triageAwaiting the triage agent: sizing + priority (SCR-005)

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions