{"service": "iTechSmart ProofLink public verification spec", "bitcoin_anchoring": "Beyond the SHA-256 hash-chain and Ed25519 signatures, each receipt is also submitted to OpenTimestamps and a growing share is upgraded to a confirmed Bitcoin block-header attestation once the OTS calendars aggregate into a mined block. We never mark a receipt bitcoin_anchored without real block inclusion. See GET /api/anchors for the live confirmed count, the anchored share, and sample receipts with block heights you can check on any block explorer (or validate the .ots proof at opentimestamps.org).", "what_is_in_the_ledger": "The ledger mixes autonomous remediations (self-heals + platform fixes), platform scans, background telemetry heartbeats, and other operational receipts. GET /api/stats -> provenance_summary reports each category honestly; every category is hash-chained the same way.", "ledger_order": "The raw ledger array is newest-first; array order is the true chain order. /api/export returns oldest-first.", "eras": {"v3 (schema_version \"3.0\", receipts sealed 2026-07-01 onward)": {"canonical_bytes": "Hex-encoded canonical JSON of the FULL receipt payload: every stored field EXCEPT canonical_bytes, signature, hash_sha256. Encoding: json.dumps(payload, sort_keys=True, separators=(\",\", \":\"), ensure_ascii=False).encode(\"utf-8\"). The payload INCLUDES prev_hash, chain_position, id, timestamp, category, subject, action, actor, outcome.", "hash_sha256": "SHA256(canonical_bytes) as lowercase hex.", "signature": "Ed25519 over the raw canonical_bytes (not the hex string, not the hash). Fields: algorithm, public_key (32-byte hex), value (64-byte hex), signs=\"canonical_bytes\".", "prev_hash": "hash_sha256 of the previous (next-older) ledger entry; \"\" for genesis. Covered by the hash and signature, so chain order is tamper-evident.", "id": "Caller-supplied stable id or uuid4 hex[:16]; covered by the signature.", "verify": "All four checks must pass: (1) SHA256(canonical_bytes)==hash_sha256, (2) canonical re-derivation matches, (3) Ed25519 verifies, (4) prev_hash equals previous entry hash_sha256."}, "v2 (schema_version \"2.0\", legacy)": {"canonical_bytes": "Hex canonical JSON of all fields except canonical_bytes, signature, receiver_attestation. NOTE: hash_sha256 was computed over a pre-signing snapshot of the entry and is NOT recomputable from the stored receipt; prev_hash was NOT covered by the signature. Treat v2 signatures as authenticity of the signed payload only.", "signature": "Ed25519 over raw canonical_bytes, same key."}, "v1 (schema_version absent, legacy)": {"note": "Unsigned. hash_sha256 was computed over a pre-storage snapshot and is not recomputable from stored data. prev_hash is a pointer only. These receipts predate the v3 hardening and are preserved unmodified (no history rewrite)."}}, "optional_fields_v3": {"_note": "Additive, forward-only optional fields introduced 2026-07-02. Present ONLY on receipts that set them; absent by default. Each is a normal top-level payload field, so it is inside canonical_bytes and covered by hash_sha256 + the Ed25519 signature (no special handling \u2014 the reference verifier above already validates them). Receipts without these fields are unchanged and verify exactly as before.", "compliance_tags": "list[str] of control IDs the receipt attests to, e.g. [\"NIST 800-53 AU-2\", \"EU AI Act Article 12\", \"CMMC AC.L2-3.1.1\", \"HIPAA 164.312(b)\"]. Free-form strings; no fixed vocabulary is enforced. Because it is inside canonical_bytes, a compliance tag cannot be altered without breaking the hash and signature.", "supersedes": "str receipt id that THIS receipt corrects or replaces. Supersession is forward-only: the newer receipt points BACKWARD at the older id, and the older receipt is NEVER mutated (its hash/signature stay valid, chain order is preserved). The reverse link (superseded_by) is NOT stored in history \u2014 GET /api/verify/<id> derives it at read time by scanning for receipts whose supersedes == <id>, and returns it as a top-level response field (outside the signed receipt payload so re-derivation is unaffected).", "learned_from": "list[str] of prior receipt ids this receipt learned from. Used by the learning_receipt category to close the LEARN loop provably: the citing receipt is cryptographically bound to the ids of the receipts that informed the model/policy change."}, "categories": {"_note": "The `category` field is free-form and every category is hash-chained the same way. The entries below are documented conventions so producers and consumers agree on payload shape; they require no special verification.", "config_change": "Infrastructure config mutation (sealed by the netmiko connector). details payload: {device, change_type, before_hash, after_hash, diff_summary}. May carry compliance_tags and/or supersedes.", "learning_receipt": "A model/policy update. Carries learned_from (list of prior receipt ids that informed the change) plus details describing what changed. Closes the LEARN loop of the autonomous remediation pipeline.", "platform_fix": "An autonomous or operator platform change/remediation."}, "public_key_hex": "21102eaa68ea9ed42c05a2253aa953d33c59b5348ff8659018146e59fb061b97", "public_key_fingerprint_sha256": "54a2116e9cea5f51d6db61c4701d62fd3a0cf670b3004c89a5278eeb5507643f", "public_key_source": "Embedded in every v3 receipt (signature.public_key); cross-check against this endpoint and any exported receipt.", "fetch_receipts": "GET /api/export?from=0&to=1000 (paginated, oldest-first) or GET /api/verify/<receipt_id_or_hash_prefix>", "reference_verifier_python": "import json, hashlib\nfrom cryptography.hazmat.primitives.asymmetric import ed25519\n\nEXCLUDE = (\"canonical_bytes\", \"signature\", \"hash_sha256\")\n\ndef verify_v3(receipt, prev_entry_hash=None):\n    canon = bytes.fromhex(receipt[\"canonical_bytes\"])\n    assert hashlib.sha256(canon).hexdigest() == receipt[\"hash_sha256\"], \"hash mismatch\"\n    payload = {k: v for k, v in receipt.items() if k not in EXCLUDE}\n    rederived = json.dumps(payload, sort_keys=True, separators=(\",\", \":\"),\n                           ensure_ascii=False).encode(\"utf-8\")\n    assert rederived == canon, \"canonical re-derivation mismatch (field tampered)\"\n    sig = receipt[\"signature\"]\n    pub = ed25519.Ed25519PublicKey.from_public_bytes(bytes.fromhex(sig[\"public_key\"]))\n    pub.verify(bytes.fromhex(sig[\"value\"]), canon)  # raises on bad signature\n    if prev_entry_hash is not None:\n        assert receipt[\"prev_hash\"] == prev_entry_hash, \"chain link broken\"\n    return True\n\n# usage: receipts = GET /api/export?from=N&to=N+1000 (oldest-first)\n# for i, r in enumerate(receipts[1:], 1): verify_v3(r, receipts[i-1][\"hash_sha256\"])\n"}