{
  "schema": "rootz.node.claims.v1",
  "node_id": "polygon-node-1",
  "service_version": "0.2.0",
  "generated_at": "2026-09-23T17:52:09.335Z",
  "claims": [
    {
      "id": "boot_state",
      "asserts": "this box booted with these PCR values",
      "evidence": "TPM2_Quote over PCR 0,4,7 bound to a caller-supplied nonce",
      "depth": "measured",
      "window": "from the quote until the next boot",
      "values": {
        "0": "15FC51ABA533EC0FEAF06B18D935B449ADBFB63FD93184C532F8536CB530B79B",
        "4": "A310CA0F568D1195EF34A6C1DAFAB31F4B8B5DA81C9822AB297050DEBF95E87A",
        "7": "3871E64D63D489742C44ABE29EF014039523413BD54EE5955B2ECF00FB7E3EEF",
        "10": "717D04FDFDC7A97620943DD7A337FE180ED26CF17B7919E8CEB73FB6DB3E387B"
      }
    },
    {
      "id": "key_residency",
      "asserts": "the signing key is inside this TPM and cannot leave it",
      "evidence": "TPM2_Certify by the attestation key; fixedtpm|fixedparent",
      "depth": "measured",
      "window": "until the key is destroyed"
    },
    {
      "id": "machine_identity",
      "asserts": "which OCI instance and tenancy this is",
      "evidence": "OCI instance identity certificate: leaf verified against the intermediate (cryptographic), and the intermediate must name the expected regional root as its issuer (a DN check, not a key check). NOT verified to the regional root — IMDS does not serve it (root.pem, ca.pem, chain.pem all 404) and this node has never held it. The intermediate itself cannot be pinned: Oracle mints a fresh one per issuance (measured: rotated 38 minutes apart on 2026-09-15).",
      "depth": "relayed",
      "window": "about two hours — captured at signing time and carried, never fetched later",
      "instance_ocid": "ocid1.instance.oc1.iad.anuwcljrpte74yyc55bm356ftfcxb4ziof7jvnn6vb52tpvnanldif2yjxyq",
      "tenancy_ocid": "ocid1.tenancy.oc1..aaaaaaaa6kmqiaqt3wz7uuhcao3ppxqlwqyrxenkxbufkurxytj5bggpwlba"
    },
    {
      "id": "response_bytes",
      "asserts": "these exact bytes were returned",
      "evidence": "signature over sha256 of the wire bytes, never a re-encoding",
      "depth": "measured",
      "window": "permanent once signed"
    },
    {
      "id": "request_binding",
      "asserts": "this answer is bound to that specific request",
      "evidence": "the response commits to a hash of the whole signed request — caller address, nonce, timestamp, audience",
      "depth": "measured",
      "window": "permanent once signed"
    },
    {
      "id": "caller_identity",
      "asserts": "the caller is this address",
      "evidence": "secp256k1 recovery from the request signature; the address is recovered, never trusted from the envelope",
      "depth": "measured",
      "window": "request TTL, 5 minutes"
    },
    {
      "id": "index_completeness",
      "asserts": "this index answer is complete for this key and range",
      "evidence": "chunk commitment with sorted keys; absence proved by bracketing neighbours",
      "depth": "measured",
      "window": "a chunk is immutable once built",
      "scope": "complete only within the declared key_space"
    }
  ],
  "does_not_claim": [
    {
      "id": "genuine_hardware",
      "statement": "that the TPM is genuine hardware",
      "because": "it is a software TPM (oci-vtpm-swtpm) with no EK certificate; a quote alone proves some TPM said so, and only the instance certificate binds it to a real machine"
    },
    {
      "id": "runtime_integrity",
      "statement": "that the node was intact at runtime",
      "because": "PCRs are extended at boot and frozen after; measured boot says what loaded, not what happened in memory afterwards"
    },
    {
      "id": "chain_client_measured",
      "statement": "that the chain client is measured",
      "because": "PCR 0/4/7 cover firmware, boot chain and Secure Boot state; bor is a userspace binary and is not in the measured set"
    },
    {
      "id": "provider_vouches",
      "statement": "that the cloud provider vouches for our integrity",
      "because": "the instance certificate carries identity fields only — no measurement, no PCR. A compromised guest keeps receiving valid certificates."
    },
    {
      "id": "chain_truth",
      "statement": "that the chain data is true",
      "because": "truth of the ledger is consensus; this attests custody of a read"
    },
    {
      "id": "revocation_authoritative",
      "statement": "that a revocation answer is authoritative unless coverage was demanded",
      "because": "the absence proof is sound and a stale range is refused — but only when the caller sets require_coverage_through. A caller who does not set that bound can receive an honest answer over an old range, and \"not revoked as of six months ago\" is honest and wrong."
    },
    {
      "id": "node_honesty",
      "statement": "that this node is honest",
      "because": "a node that lies consistently produces a consistent index; that is what N>=2 is for, and only when failures are independent"
    },
    {
      "id": "confidentiality",
      "statement": "that the exchange is confidential",
      "because": "signatures carry integrity, authenticity, freshness and request-binding; they do not carry secrecy. Request and response travel in the clear."
    },
    {
      "id": "tamper_proof",
      "statement": "that anything here is tamper-proof",
      "because": "tamper-evident is a different and smaller claim"
    }
  ],
  "agent_guidance": [
    "START AT GET /skill — it is the operating manual for this node and it is short.",
    "Call node_attestation before relying on any other answer.",
    "Every answer carries depth and window. Do not discard either.",
    "AN EMPTY RESULT IS NOT AN ANSWER. \"no events\" and \"I have not indexed that range\" are different, and this node says which. A coverage refusal means UNKNOWN, not zero.",
    "For an absence that matters — revocation, in particular — pass require_coverage_through. A stale \"none found\" is honest and wrong.",
    "A refusal is a result. Prefer it to a plausible answer you cannot check.",
    "Do not trust our signature because we say it is sound. GET /verify for the preimage rule and /verify/vectors.json for frozen vectors, and reproduce them yourself. NOTE: payload.hash is base64url while certifiedKeysetDigest is hex — the same algorithm in two encodings, and mistaking one for the other looks exactly like a broken signature."
  ],
  "self_reliance": [
    {
      "on": "the chunk store re-derives every root before serving and refuses on mismatch",
      "status": "in_use"
    },
    {
      "on": "the indexer refuses a range that can still reorganise, on checkpoint finality",
      "status": "in_use"
    },
    {
      "on": "a timed-out scan halves and retries, never skips",
      "status": "in_use"
    },
    {
      "on": "an absence over a stale range is refused rather than answered",
      "status": "in_use"
    },
    {
      "on": "our own agents treat a failed lookup as unknown rather than zero",
      "status": "designed"
    }
  ],
  "assurance_level": "L1",
  "assurance_note": "L1 — attested transport, anchored to a cloud instance identity. Not L2; that needs silicon-rooted attestation.",
  "key_spaces": {
    "rootz.v6.datawallet.notes": {
      "describes": "all notes written to a data wallet",
      "keyed_on": "data wallet address",
      "chunk_size": 100000
    },
    "rootz.v6.datawallet.byWriter": {
      "describes": "every note a given writer has authored, across all wallets",
      "keyed_on": "writer address",
      "chunk_size": 100000
    },
    "rootz.v6.datawallet.created": {
      "describes": "every data wallet a given wallet created",
      "keyed_on": "creator address",
      "chunk_size": 100000
    },
    "rootz.v6.identity.created": {
      "describes": "identities created by a given wallet",
      "keyed_on": "creator address",
      "chunk_size": 100000
    },
    "rootz.v6.messages": {
      "describes": "the Blockchain LAN channel — messages by sender",
      "keyed_on": "sender address",
      "chunk_size": 100000
    },
    "rootz.v6.rivets": {
      "describes": "rivet public-key registrations",
      "keyed_on": "rivet address",
      "chunk_size": 100000
    }
  },
  "endpoints": {
    "json_rpc": "POST /",
    "index_query": "POST /index/query",
    "index_keyspaces": "GET /index/keyspaces",
    "index_coverage": "GET /index/coverage?key_space=",
    "mcp": "POST /mcp",
    "health": "GET /healthz",
    "claims": "GET /.well-known/rootz-node/claims",
    "skill": "GET /skill — how to use this node, as markdown. Read it before the endpoints.",
    "verify": "GET /verify — the exact preimage rule for our envelopes",
    "verify_vectors": "GET /verify/vectors.json — frozen test vectors; reproduce these before writing verification code"
  }
}