{"issuer":"scry.moreright.xyz","sig_alg":"ed25519","attestation_pubkey_b64":"LvuPBMbKKyoNEuyvLf7f+rbyjK67vBcWy9MDwaRINGE=","verify":"sig = ed25519(pubkey, canonical_json(payload minus sig, scope and attested)); canonical_json is sorted-keys, separators (',',':'), no spaces. `sig`, `scope` and `attested` are all response-layer fields added after the signature and are NOT covered by it.","not_covered_by_sig":["sig","scope","attested"],"other_signed_objects":{"vow_chain_entry":"ed25519 over  sig_domain + '\\n' + json.dumps(entry_without_sig, sort_keys=True, separators=(',',':'))  — `sig_domain` is also a field of the entry, and is 'scry/vow-entry/attested/v1' for a PAID report-in and 'scry/vow-entry/sandbox/v1' for a free one. The domain is what stops a free entry being presented as a paid attestation: a verifier that assumes the attested domain cannot validate a sandbox entry. Verify against GET /pubkey.","vow_countersig":"ed25519 over json.dumps(body, sort_keys=True, separators=(',',':')) where body = {vow_id, vow, sandbox, sealed, issuer, attestation_pubkey_b64[, operator]} — the fields fixed at registration. `vow` is the record's own vow object, except that a SEALED vow carries text_sha256 in place of text. seq/chain_head are deliberately NOT covered: they change with every report-in, and the chain's own entry_hash/prev_hash attest them. Verify against GET /pubkey."}}