Skip to content

[Proposal]: Optional Bitcoin-anchored proof-of-when for signed Mandates (extension, outside signed bytes) #293

Description

@MarkovianProtocol

AP2 mandates (Intent / Cart / Payment) are verifiable credentials: the signature proves who authorized and what was authorized. The embedded timestamp, though, is asserted by the signer. For chargeback and audit, the contested question is often when: did this mandate exist before the disputed charge, before a price change, before a revocation? A self-asserted clock is weak evidence against a motivated counterparty.

This is distinct from the post-checkout action record in #290 and the settlement-side bindings in #255 / #224. Those record what happened after authorization. The proposal here anchors the authorization artifact itself, and is orthogonal to all of them.

Proposal: attach an optional markovian-provenance/v1 commitment to a mandate as an extension, carried outside the signed bytes so it never affects VC verification. The issuer hashes the canonical mandate, POSTs the hash to an external service, and stores the returned record (a Merkle inclusion in an append-only transparency log whose checkpoints are cosigned by independent witnesses and anchored to Bitcoin). Later, any verifier re-hashes the mandate and checks the anchor with no account. The VC proves who, the anchor adds an independent proof of when.

Honest boundary: this is provenance, not truth. It proves a mandate existed at a point in time, it does not validate the payment, the authority, or the agent's behavior. It is additive, not a replacement for the signature or any settlement attestation, and it requires no change to the mandate schema (an extension field only).

Shape — canonicalization pinned to one frozen profile:

anchored = "sha256:" + hex(SHA-256(JCS(mandate)))

where JCS is RFC 8785, so any stock JCS library re-derives the same digest from the same mandate, this year or in ten. Where a mandate exists as a signed token, the anchor hashes exactly the issuer-signed JWT bytes — the byte string the issuer's signature covers, not a re-canonicalization of the decoded payload, and not the presented token (presentations vary by disclosed subset; the issuer JWT is frozen). The extension states which form was hashed — one input byte form, named, never two. Store {merkle_root, block_height, verify_url} as a mandate extension. Verification is a plain GET https://markovianprotocol.com/anchor/<sha256-hex> returning a JSON verdict — anchored digest, merkle root, block height, pass/fail — no account, no payment.

Repo (Apache-2.0): https://github.com/MarkovianProtocol/markovian-protocol
Site: https://markovianprotocol.com


Edited 2026-07-19: pinned the canonicalization profile to RFC 8785 and the signed-token byte rule (issuer-signed JWT, not the presented token — per the discussion below), replaced the legacy quantsynth endpoints with the current markovianprotocol.com witnessed log, and specified the machine-readable JSON verify response.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions