{
  "algorithm": "Ed25519",
  "key_custody": "Generated by the GAIP runtime and held only in GAIP's runtime database; excluded from backups; no person has been shown it. RETIRED keys stay listed so older signatures still verify; a key retired with retired_reason COMPROMISED is listed for transparency and must not be trusted.",
  "keys": [
    {
      "alg": "EdDSA",
      "created_at": "2026-10-01T09:28:00.069668Z",
      "crv": "Ed25519",
      "kid": "70ae8f5c793b4f5a",
      "kty": "OKP",
      "status": "ACTIVE",
      "use": "sig",
      "x": "sFij-KoqUO5ZCg40lL3WqPZ9yJg1B19Gupg1XfR5Is8"
    }
  ],
  "kid_rule": "kid = first 16 lower-case hex characters of SHA-256 over the raw 32-byte Ed25519 public key.",
  "message_rule": "Ed25519 (RFC 8032) signature over the ASCII bytes '<purpose>:<digest>' where digest is the lower-case hex SHA-256 named by purpose (any 'sha256:' or '0x' prefix removed).",
  "price_gbp": 0,
  "proof_boundary": "A valid signature shows GAIP's runtime key signed that digest. It does not prove the truth of the recorded event, legal identity, ownership, value or outcome. It is not a qualified electronic signature, seal or timestamp.",
  "purposes": {
    "gaip.accuracy_pair.receipt_sha256.v1": "pair_sha256 of a Second Look vendor-submitted accuracy pair (SHA-256 over the canonical JSON of the record without receipt_id, observation_id, pair_sha256, its signature fields and the handle binding; accuracy_pairs.py). It records what the vendor submitted beside what the page showed when GAIP read it, never a finding about the assistant or the shop.",
    "gaip.act.entry_sha256.v1": "entry_sha256 of a GAIP act log entry (gaip.act.v1: SHA-256 over the canonical JSON of the entry without receipt_id, observation_id, entry_sha256, its signature fields and any cosigner; act_log.py). It records that an agent submitted the entry at the stated time and, where shown, what a public page showed when GAIP read it; never that the act happened as described.",
    "gaip.agent_commerce_check.receipt_sha256.v1": "receipt_sha256 of a GAIP agent-commerce check receipt (SHA-256 over the canonical JSON of the receipt without its signature fields; agent_commerce_record.py). It records what a shop's own file said when GAIP read it, never GAIP's view of the shop.",
    "gaip.compliance_export.sha256.v1": "export_sha256 of a compliance-record export (SHA-256 over the canonical JSON of the export without its signature fields; compliance_record.py). GAIP's own daily readings of a consenting shop's product page, never a statement about any price or deadline.",
    "gaip.digest_manifest.root_sha256.v1": "digest_manifest.root_sha256 of a GAIP evidence pack, incident bundle or receipt export.",
    "gaip.disclosure.entry_sha256.v1": "entry_sha256 of a GAIP disclosure record (the chained record_sha256 of its History Spine row; disclosures.py). It records what the disclosing agent stated, never GAIP's view.",
    "gaip.disclosure_ack.entry_sha256.v1": "entry_sha256 of a recipient's acknowledgement of a GAIP disclosure record (the chained record_sha256 of its History Spine row; disclosures.py).",
    "gaip.erc8004.response_hash.v1": "responseHash of an ERC-8004-shaped validationResponse export (SHA-256 over JCS).",
    "gaip.evidence_export.bundle_sha256.v1": "bundle_sha256 of a GAIP evidence bundle (gaip.evidence-bundle.not-as-described.v1: SHA-256 over the canonical JSON of the bundle without its signature fields; evidence_export.py). It records what GAIP recorded at the times shown, never who is right.",
    "gaip.host_owner_verification.challenge_sha256.v1": "SHA-256 over the canonical JSON of {challenge, host_key} for a site owner's host-timeline verification; the owner's token is derived from this signature (host_timeline.py).",
    "gaip.inhand.control_change_sha256.v1": "change_sha256 of one change to a person's In Hand controls (rules, pause, an agent confirmed or blocked, someone you trust added, removed or looking): SHA-256 over the canonical JSON of the change row's commitment.",
    "gaip.inhand.decision_commitment_sha256.v1": "commitment_sha256 of one In Hand gate answer: SHA-256 over the canonical facts plus a random salt kept in the person's encrypted record (DP-R1). It records what the agent asked, which of the person's rules applied and what In Hand answered, at the stated time.",
    "gaip.inhand.hook_answer_sha256.v1": "answer_sha256 of an In Hand gate answer to the In Hand hook: SHA-256 over the canonical JSON of {decision, nonce, tool_use_id, tool_input_sha256, connection_id, tool, declared_sha256}.",
    "gaip.inhand.weekly_report_sha256.v1": "report_sha256 of one Agent Minder weekly report: SHA-256 over the canonical JSON (sorted keys, no spaces) of the frozen document. It records what the person's helpers told Agent Minder or asked it about in that week and what Agent Minder answered, as built at the stated time; never that anything a helper said happened.",
    "gaip.mandate_check.receipt_sha256.v1": "receipt_sha256 of a GAIP Mandates checked-at receipt (SHA-256 over the canonical JSON of the receipt without its signature fields; agent_mandates.py).",
    "gaip.order_capture.receipt_sha256.v1": "receipt_sha256 of an order-time capture receipt (SHA-256 over the canonical JSON of the receipt without receipt_id, observation_id, receipt_sha256 and its signature fields; order_capture.py). It records what the shop's public product pages showed when the order was received, not who is right.",
    "gaip.permission_answer.answer_sha256.v1": "answer_sha256 of a gaip_check_permission answer (SHA-256 over the canonical JSON of the answer without its signature fields).",
    "gaip.preference_check.receipt_sha256.v1": "receipt_sha256 of a GAIP Preferences checked-at receipt (SHA-256 over the canonical JSON of the receipt without its signature fields; agent_preferences.py).",
    "gaip.recall_check.recall_sha256.v1": "recall_sha256 of a recall-check receipt (SHA-256 over the canonical JSON of the receipt without receipt_id, observation_id, recall_sha256 and its signature; recall_check.py).",
    "gaip.record_answer.answer_sha256.v1": "answer_sha256 of an answer from the record by date (tenure, names, keys, permissions, prices): SHA-256 over the canonical JSON of the answer without its signature fields; record_routes.py).",
    "gaip.record_extract.extract_sha256.v1": "extract_sha256 of a gaip_record_extract extract of GAIP's record (SHA-256 over the canonical JSON of the extract without its signature fields).",
    "gaip.record_sha256.v1": "record_sha256 of one GAIP History Spine record (the per-record hash-chain digest).",
    "gaip.revocations.document_sha256.v1": "document_sha256 of a GAIP revocations feed page, status list or revoked-since answer (SHA-256 over the canonical JSON of the document without its signature fields; revocations.py). It shows what GAIP published and when, nothing about effect.",
    "gaip.second_look.offer_sha256.v1": "offer_sha256 of a Second Look \"offer seen\" receipt (SHA-256 over the canonical JSON of the receipt without receipt_id, observation_id, offer_sha256 and its signature fields; second_look.py).",
    "gaip.serve.entry_sha256.v1": "entry_sha256 of a GAIP Served entry (the chained record_sha256 of its History Spine row: the serve, a fetch, the acknowledgement or the retry; served.py). It records what GAIP delivered and what the endpoint answered.",
    "gaip.signoff.entry_sha256.v1": "entry_sha256 of a GAIP sign-off record (the chained record_sha256 of its History Spine row; witness.py witness_signoff). It records a role's stated decision, never GAIP's.",
    "gaip.statement.statement_sha256.v1": "statement_sha256 of a GAIP monthly statement (SHA-256 over the canonical JSON of the statement's core: period, continuity_ref, totals, lines, chain_head and the sentence; statements.py).",
    "gaip.switch_pack.pack_sha256.v1": "pack_sha256 of a GAIP switch pack (gaip.switch-pack.v1: SHA-256 over the canonical JSON of the pack without its signature and per-call fields; switch_pack.py). GAIP's own export of the entries bound to one handle, with its public keys and the verifier steps; it binds no other provider and says nothing about any act.",
    "gaip.witness_finding.finding_sha256.v1": "finding_sha256 of a GAIP Deals finding record (SHA-256 over the canonical JSON of the record without its signature fields; deals.py).",
    "gaip.x402_sar.receipt_id.v1": "receipt_id of an x402 SAR v0.1 export (SHA-256 over JCS of the SAR core fields)."
  },
  "rotation": "A rotation adds a new ACTIVE key and keeps the old one listed as RETIRED with retired_at and retired_reason (ROTATED or COMPROMISED). Receipts are signed when they are read, so the same receipt read after a rotation carries a signature by the new key; a signature by a RETIRED key still verifies against this set unless retired_reason is COMPROMISED. For a few minutes after a rotation some answers may still carry the previous key's signature.",
  "schema_version": "gaip.receipt-keys.v1",
  "signing_available": true,
  "unavailable_reason": null,
  "verify_hint": "Find the key whose kid equals signature.kid, base64url-decode x and sig, rebuild '<purpose>:<digest>' and check the Ed25519 signature."
}