ATTEST CASE PACK — a site's signed visit records for third-party review
=======================================================================

index.html          START HERE — a self-contained offline record browser. It
                    verifies every signed record in your browser, opens with a
                    day-by-day strip of the whole exported window (coverage,
                    interruptions, observations), and renders each visit's
                    timeline. No install, no network.
manifest.json       Every visit's receipt hash, state, and worker stance.
visits/<id>/        Per-visit bundle.json + the media bytes it references.
attestations/       Site-level signed receipts: coverage certificates, period
                    digests, prior exports, this deployment's own verification
                    acts (pack_verification — the audit, audited) — and any
                    key_rotation pivots, each signed by the retiring key
                    endorsing its successor.
verify_case.py      Offline verifier. Run:  python verify_case.py .
                    Pass --key <base64> to pin the expected issuer key —
                    without it the issuer is self-declared by the pack. A
                    pinned pre-rotation key still verifies: the signed
                    rotation chain links it to the manifest's issuer.
verify.html         Zero-install verifier — open in any browser and drop the
                    pack files in. Same checks, pure JavaScript, works offline.
                    Also checks the media bytes index.html can only list.
verifier_manifest.json  A signed receipt pinning the sha256 of every verifier
                    shipped in this pack. A forged pack that doctors its own
                    verifier to print VERIFIED is caught — only the
                    deployment's key can sign the real manifest.
log_checkpoint.json   Present when the deployment publishes a transparency
                    log: a signed Merkle tree head plus an inclusion proof
                    for every issuer-signed receipt in this pack — evidence
                    that these records were committed to the deployment's
                    published append-only log. Its `chain` list embeds prior
                    signed heads (up to 32) so two exports reconcile offline:
                    `attest diff` walks the signed `extends` bridges
                    hop-by-hop instead of trusting enumeration.

WHAT A VALID VERIFICATION PROVES
- Each bundle.json is byte-identical to what was signed, and every appended
  review is hash-anchored to its original receipt.
- manifest.json's receipt hashes match the signed originals — the case summary
  cannot quietly describe different records than the signed ones.
- If log_checkpoint.json is present, every issuer-signed receipt in the pack
  proves inclusion in the deployment's transparency log at the checkpoint's
  committed size — a valid signature on an uncommitted receipt still fails.
- Media files match the sha256 digests in each record's evidence list.
- If the deployment rotated its signing key, the rotation receipts are signed
  pivots: the retiring key endorsed each successor, so records on both sides
  of the transition verify under one signed chain — a key that appears in
  the pack without a signed endorsement link is rejected, never trusted.

WHAT IT DOES NOT PROVE
- Identity. Signatures authenticate records, not who appears in media.
- Attendance or time worked. Observations are events, not presence.
- Absence. A silent window means nothing was observed — not that nobody came.
- The worker's person. Worker statements arrive through scoped links; they are
  the worker's account, recorded — not a verified identity.

The private signing key stays with the deployment. The issuer public key in
manifest.json verifies this pack; compare it to a key obtained out-of-band to
rule out a pack that swapped keys.

HOLDING TWO EXPORTS?  `attest diff packA.zip packB.zip` compares them:
appended records are normal drift, but a vanished record, an altered signed
field (named field-by-field), or a same-size transparency-log fork is flagged.
The same compare runs in the browser: drop both packs onto verify.html at
once — each verifies on its own merits, then their signed membership is
diffed and the two log heads are reconciled ("both verify" and "both
identical" are different claims).
