# TIMEVOLT portable receipt v1

Wire profile: `urn:timevolt:receipt:v1`. Schema: `receipt.schema.json`. This version
is frozen with a SHA-256 manifest after its recorded-fixture checks. Earlier
alpha submission and legacy Bitcoin proof readers remain available unchanged in
their respective formats. They are not silently reinterpreted as v1.

Only the **staging** emitter is enabled. All live examples use synthetic work.
The `production` environment label is reserved; its presence does not establish
trust or enable production issuance. A receipt is a self-contained JSON document,
at most 4 MiB, with no duplicate keys or non-finite/unsafe numbers. Signature
canonicalisation uses the existing restricted JCS-compatible string/object/array/
safe-integer representation. Unknown fields fail validation.

## Commitment, membership and privacy

`record_id` remains SHA-256 over `TIMEVOLT/record/v1\0` and the canonical four-field
core record. The device keeps the optional `record` opening; the service never
receives its digest, nonce or references in normal use. An optional fingerprint-only
`application_manifest` is the existing release recipe profile, committed by the
subject digest. A blind evidence response omits both local fields. Adding them is
a device operation, not a service endpoint accepting a full receipt.

Each batch sorts unique record IDs and adds one fresh random padding leaf at the
end. User leaves are SHA-256(`00 || record_id_bytes`); padding is SHA-256(`02 ||
32_random_bytes`). Each parent is SHA-256(`01 || left || right`), duplicating an odd
last node. Thus even a one-record batch sends a padded aggregate root, not a user
commitment. `membership` gives the zero-based index, total including padding and
bottom-up sibling hashes. Padding cannot be presented as a user record. Readers
recompute both root and its final 65-byte preimage.

## Independent authority evidence

`batch.timestamps` retains every successfully validated DigiCert/Sectigo response
(both in the normal dual-success case). An unavailable/invalid provider does not
erase the other's valid token. Both authorities are attempted for every batch.
`response_der` is standard padded base64 of the entire RFC 3161 response. Each entry
records the batch request's independent `nonce_hex`; this is not a record-opening
nonce. `batch.root` is the SHA-256 message imprint, not a per-user hash.

Validation requires granted/grantedWithMods, no failure flags, SHA-256 imprint,
matching request nonce, accepted policy OID, CMS content-type/message-digest and
signature, signer identity, ESS SigningCertificate/SigningCertificateV2 (including
hash and issuer/serial when present), exclusive critical timestamping EKU, and a
valid certificate path to a reader-pinned root. Cross-signed copies of a pinned
anchor use its pinned self-signed subject/public key for the trust path; original
embedded certificates remain available for ESS references.

The pins are DigiCert Trusted Root G4, SHA-256
`552f7bdcf1a7af9e6ce672017f4f12abf77240c78e761ac203d1d9d20ac89988`, and
Sectigo Public Time Stamping Root R46, SHA-256
`4941b001b8a97e961b7817c9d9e960ec4b056bfc915a8c1aabf6ef6b3ac046a5`.
Accepted policies are respectively `2.16.840.1.114412.7.1` and
`1.3.6.1.4.1.6449.2.1.1`. New pins/policies require an explicit reviewed reader update;
a receipt cannot supply its own trust anchor. Embedded certificates are validated
at the signed generation time, preserving old evidence after ordinary expiry.
The reader preserves the raw authority time/accuracy and checks certificate-time
boundaries at sub-millisecond precision. It does **not** establish current or
historical revocation status; revocation/preservation qualification remains separate.

`Dated` requires at least one fully valid authority token. Included invalid tokens
cause rejection; they are not ignored merely because another token is valid.

## OpenTimestamps and Bitcoin

`batch.ots` is padded base64 of a standard detached OpenTimestamps version-1 proof,
with SHA-256 file digest equal to the padded batch root. No extra hash of that
root is substituted. The constrained v1 reader supports SHA-1, RIPEMD-160, SHA-256, Keccak-256, append, prepend,
reverse and hexlify operations, bounded forks, Bitcoin attestations and pending
calendar attestations. Unknown attestations confer no trust; unsupported operations
fail closed. Pending calendar acknowledgments are not Bitcoin proofs.

The staging worker submits to Alice and Bob and merges upgrades while retaining
old proof versions. Only configured calendar hosts may receive upgrade requests;
untrusted pending URLs cannot redirect the worker. Upgrade lookups use batch-derived
commitments, never record IDs. `calendar_submissions` records the two accepted
calendar requests; those entries are service assertions bound by the snapshot,
not independent calendar signatures.

A complete path embeds an 80-byte mainnet `batch.bitcoin.header`. The reader checks
the OTS digest reaches that header's Merkle root, its double-SHA-256 block hash,
target encoding/network limit and proof of work. OTS height is a lookup claim,
confirmed only by an independent live source. A header alone does not validate
Bitcoin consensus history, active-chain membership or confirmation count.

`Permanent` requires valid independent time, a complete Bitcoin path, two accepted
calendar submissions and matching active-chain/six-confirmation observations from
mempool.space and blockstream.info. Each source contributes its URL, observation
time, block height/hash, active hash at that height and tip hash/height. A changing
tip during a check is retried; missing/disagreeing evidence grants no Permanent
status. Reorganised saved evidence remains available with an appended correction.

Required Bitcoin sentence:

> Bitcoin inclusion proves that this commitment was included in the identified block; the block timestamp is miner-provided and does not establish an exact UTC creation time.

## Signed snapshots and corrections

The service issuer public key is raw Ed25519 in lowercase hexadecimal. Each signed
envelope contains `body`, SHA-256 key ID and standard-base64 64-byte signature.
Signatures cover the UTF-8 domain separator followed by canonical body bytes.

- Snapshot domain: `TIMEVOLT/evidence-snapshot/v1\0`. The body binds record ID,
  canonical batch hash, status, observations, time, sequence, previous snapshot hash
  and latest correction hash. Historical snapshots are immutable in storage.
- Correction domain: `TIMEVOLT/status-correction/v1\0`. Corrections bind record ID,
  sequence, previous correction hash, old/new status, reason, time and observation
  hash. Corrections append; no old receipt/snapshot is rewritten or erased.

The reader validates the complete saved correction chain and snapshot head. Its
issuer identity is trusted only against a separately supplied pin, never because
the file declares a key. Offline verification reports **saved evidence checks out**,
not current chain membership. An old saved copy cannot discover a later correction
or prove that a newer snapshot does not exist. The online app fetches retained
evidence by commitment, without account or subscription, and shows appended entries.

Optional browser chain checks go directly to a source selected by the user. They
show source and observation time before/after the action, send only block lookups
and the browser's IP, and never proxy through Timevolt. A read-only Esplora adapter
may point to the user's own node; wallet RPC credentials are never requested.

## Frozen bytes and implementation boundaries

`FORMAT_MANIFEST.json` pins this specification and schema. A substantive wire change
requires a new profile/version; algorithm validators may receive explicit security
updates while continuing to explain their supported historical policies.

Staging uses the isolated Python/SQLite harness and pinned PKI.js/ASN.1 dependencies,
with a self-contained browser reader. This format freeze does not declare the
Rust/PostgreSQL production implementation, revocation/preservation operation,
independent storage or public issuance qualified. No API account, subscription,
original file or Timevolt server is needed to check saved complete evidence.
