Erasure Receipt · erasure.receipt

Prove a deleted record is actually gone.

A deletion request is easy to answer and hard to prove. You commit the active set as a sparse tree keyed by a per object salt. After deletion the verifier recomputes the absence path for that object against the new root. The object never reaches us and neither does the salt.

30 of 30 local checks pass

This instrument ships with this release. The 30 checks above are the local smoke suite, run in process against a throwaway key with no network calls.

The fight this ends

Your deletion workflow probably ends in an email that says the record was removed. The person who asked has no way to test that, and neither does a regulator reading your response six months later.

The usual evidence is a screenshot of a row that no longer renders. That's a statement about a user interface, not about storage. A soft delete flag looks identical from outside.

This receipt gives the asker arithmetic instead of assurance. At a stated instant, the object was provably absent from the committed set. Put it back and the next receipt says present.

Here is the shape

01

Publish a root

You commit the active set as a sparse tree and sign the root. The receipt carries before_root with its value and tree_depth, plus the prior receipt link that ties it to the signed anchor.

02

Delete, then recompute

After the deletion you anchor after_root. The verifier folds witness_before to prove the object leaf was under the old root, then folds witness_after over the same path to prove the position is now empty.

03

Cover the keys and the copies

key_destruction carries a signed record binding the destroyed data encryption key to the same object_commitment. replica_manifest carries one attestation per replica class recorded at ingestion.

What holds it together

The strong part is the transition, not the absence. ROOT_TRANSITION_MINIMAL checks that the move from the old root to the new one is the removal of that single leaf and nothing else, so you can't quietly rewrite the rest of the set inside a deletion.

Timing is checked in both directions. REQUEST_BEFORE_DELETION, LAST_ACCESS_BEFORE_DELETION, RETENTION_ELAPSED, and DELETION_PRECEDES_AFTER_ANCHOR put the request, the last read, the retention window, and the anchor in an order that can be recomputed.

Coverage is counted, not claimed. REPLICA_COVERAGE_COMPLETE compares the attestations in the manifest against the replica class set committed at ingestion, so a missing class is a refusal instead of a footnote.

Verify one yourself

Verify is open. You pass the receipt, the signed active set root, and the salt opening that lets the verifier recompute the object commitment.

curl -sS -X POST https://thehiveryiq.com/v1/verify/erasure-receipt \
  -H 'content-type: application/json' \
  -d @erasure.json

The object identifier and its salt sit in disclosure, which is what the caller opens to the verifier. No object content goes in, and OBJECT_CONTENT_NON_LEAKAGE refuses a request that tries.

{
  "receipt": {
    "key_id": "did:hive:custodian-key", "algorithm": "Ed25519",
    "signed_body": {
      "receipt_type": "erasure.receipt",
      "erasure_id": "subject-erasure-0117",
      "object": { "salt_commitment": "...", "object_commitment": "..." },
      "ingestion": { "ingestion_commitment": "...", "replica_class_count": 3 },
      "before_root": { "value": "...", "tree_depth": 256 },
      "after_root": { "value": "...", "anchored_at": { "utc": "2030-05-02T11:00:00Z" } },
      "witness_before": { "siblings": ["..."] },
      "witness_after": { "siblings": ["..."] },
      "key_destruction": { "dek_commitment": "...", "method_code": "...", "sig_b64u": "..." },
      "replica_manifest": { "manifest_commitment": "...", "attestations": [ { "replica_class_commitment": "..." } ] }
    }
  },
  "active_set_root": { "signed_body": { "receipt_type": "activeset.root" } },
  "object_salt_hex": "...",
  "disclosure": { "object_id": "tenant-77/subject-4821/document-0007", "object_salt_hex": "..." }
}

A pass returns valid true with the full gates array. A refusal names the gate, so you can see whether the problem was the transition, the key record, or the replica coverage.

What gets checked

The verifier runs every gate in order and stops at the first failure, then tells you which one stopped it. A later gate never reads a field an earlier gate already showed to be untrustworthy.

Every gate the verifier runs, in order (22 gates)
Gate
SCHEMA
ISSUER_KEY_MATCH
ENVELOPE_SIGNATURE
OBJECT_SALT_PRECOMMITMENT
OBJECT_COMMITMENT_RECOMPUTE
BEFORE_ROOT_SIGNATURE
BEFORE_ROOT_RECEIPT_LINK
BEFORE_ROOT_PRECEDES_DELETION
REQUEST_BEFORE_DELETION
LAST_ACCESS_BEFORE_DELETION
RETENTION_ELAPSED
DELETION_PRECEDES_AFTER_ANCHOR
INGESTION_COMMITMENT_RECOMPUTE
BEFORE_ROOT_MEMBERSHIP_RECOMPUTE
AFTER_ROOT_NONMEMBERSHIP_RECOMPUTE
ROOT_TRANSITION_MINIMAL
DEK_DESTRUCTION_SIGNATURE
KEY_DESTRUCTION_BINDING
REPLICA_MANIFEST_SIGNATURE
REPLICA_COVERAGE_COMPLETE
OBJECT_CONTENT_NON_LEAKAGE
BOUNDARY_CONSTANT

Field names come from the published schema: https://thehiveryiq.com/.well-known/schemas/erasure-receipt-v1.json. It ships with this release alongside the routes below, and the developer docs carry the schema catalog.

What this receipt does not say

This is the honesty boundary carried inside every erasure.receipt receipt, verbatim from the signed body.

This receipt attests only that one salted object identifier commitment recomputes as a member of a signed pre deletion active set root, recomputes as a non member of a post deletion root over the same disclosed witness path, carries a signed data encryption key destruction record bound to that same commitment, and carries a signed replica manifest whose per replica destruction attestations cover the replica class set recorded at ingestion, all under the stated deterministic procedure and ordering allowances. It does not establish that the active set enumerated every copy of the object that ever existed, that the replica manifest enumerates every replica, backup, snapshot, cache, or export that held it, or that no offline or hidden copy was taken before the deletion. It does not establish that the object was ever admitted to the active set in the first place, that the reported destruction methods rendered any storage medium unrecoverable, or that the key and replica custodians are complete, honest, or diligent. It does not establish erasure of derived data, aggregates, embeddings, logs, or backups outside the manifest, and it decides no contractual, statutory, regulatory, evidentiary, or legal consequence, allocates no risk, fault, responsibility, liability, loss, or remedy, and authorizes no action, payment, sanction, denial, or remedy.

Hive never holds the underlying data

Hive never receives the corpus, the deleted object, the raw meter data, the analysis inputs, or the control inputs. Every value is a commitment the holder computed locally, and all this service can do is recompute the arithmetic between those commitments and refuse when it does not hold.

Endpoints

RouteWhat it does
POST /v1/mint/erasure-receiptIssue an erasure receipt over commitments you computed locally. Needs Authorization: Bearer HIVE_TYPED_MINT_TOKEN and fails closed without it.
POST /v1/verify/erasure-receiptRecompute the membership, the absence, the key record, and the replica coverage. Open, no auth.

Where this sits

An erasure receipt speaks about one object in your own set. When the argument is about a number somebody billed you instead, the meter witness is the instrument for that.

The other four instruments in this release: corpus commitment, meter witness, analysis replay, control replay. For the receipt that fixes a recording instead of a computation, see capture commitment. For the written papers, see papers.

Patent pending. Hive Civilization, The Hivery, Inc.