Document snapshots & verification

Lock the current state of a vault into a hash-verified record, prove what was disclosed, and let buyers verify themselves.

A snapshot freezes the documents in a UnitVault at one moment in time. After that moment, even if the seller edits or deletes files, the snapshot stays put — and the platform issues a SHA-256 fingerprint that lets anyone (seller, buyer, court) prove what the document set looked like on that date.

This is the difference between a marketplace that stores documents and one that attests to them.

When a snapshot is taken

Two ways:

  1. Manually — the seller clicks "Create snapshot" on the vault page and writes a title and reason.
  2. Automatically on first publish — when a listing reaches PUBLISHED for the first time, Haubot's background job creates an AUTO_ON_FIRST_PUBLISH snapshot. This means every listing that goes live has at least one timestamped record of what was disclosed at launch, without anyone needing to remember to make one. Auto-snapshots are visibility SELLER_ONLY by default — sellers decide later whether to expose them.

Snapshots are immutable. The only thing you can change later is visibility, which controls what buyers see — never the contents.

Visibility levels

When you create or edit a snapshot, pick one of three levels:

  • Seller only. Only you and Haubot staff can see the snapshot exists. Default for auto-snapshots and most manual ones.
  • Buyer summary. Buyers see a trust panel on the listing — date locked, file count, snapshot hash — but not the file list. Useful when you want to advertise that documentation is sealed without disclosing what's in it.
  • Buyer full. Buyers see the snapshot's file list (still filtered to what their access level lets them see), and can download a filtered package ZIP. INTERNAL_ONLY files never appear here even on this level.

You can change visibility at any time. Doing so is recorded as SNAPSHOT_VISIBILITY_CHANGED in the audit log; the snapshot's content and hash are untouched.

The proof model

Every snapshot has a manifest_hash. It's the SHA-256 of a canonical JSON document listing every file in the vault at snapshot time, with each file's own SHA-256 content hash, plus the snapshot's metadata (createdat, vaultid, listing_id, version).

The canonical JSON is built deterministically:

  • Top-level keys in alphabetical order
  • Files sorted by (category, file_id)
  • Timestamps in UTC ISO-8601 with second precision
  • Every field included, even when null
  • No whitespace

The same input always produces the same bytes, which means the same hash. If you take a fresh copy of the snapshot's manifest and re-hash it on your own laptop, you should get the same value. If you don't, something has been altered.

Verification flows

Seller verifying integrity

On the snapshot row in the dashboard, the Verify button does two things:

  1. Per-file verify (in the snapshot details drawer) re-streams the original file from storage, recomputes its SHA-256 and compares against the value recorded at snapshot time. Green if they match, red if they don't.
  2. Whole-snapshot verify rebuilds the canonical manifest from the frozen snapshot rows in the database, recomputes its SHA-256, and compares against manifest_hash. This catches any tampering with the snapshot rows themselves.

If both pass, the snapshot is intact. If either fails, the dashboard shows the mismatch — the file or the manifest has changed since the snapshot was taken.

Buyer verifying independently

When a snapshot has buyer visibility, the buyer sees:

  • The snapshot date and short hash on the listing page.
  • A copy-full-hash button.
  • For BUYERFULL snapshots, a "View files" drawer with each file's contenthash.
  • A "Download package" button (when authenticated).

The downloaded package is a ZIP with:

  • manifest.json (or filtered_manifest.json for buyer-filtered exports)
  • README.txt with verification steps in plain English
  • documents/ with the files the buyer is entitled to

To verify by hand, the buyer runs sha256 on the manifest file. The result must match the hash on the listing page (or, for filtered exports, the filtered package hash printed in the README and back-anchored to the original snapshot hash). They can also sha256 each file in documents/ against the hashes inside the manifest. If all match, the package is exactly what was sealed.

Comparing a snapshot to "now"

The dashboard's Compare button on a snapshot shows a diff against the live vault:

  • Added — files in the vault now that weren't there at snapshot time
  • Removed — files that were in the snapshot but have since been deleted
  • Changed — same file_id on both sides but at least one tracked field differs (filename, content hash, access level, category, description)
  • Unchanged — identical on both sides

Use this when you've made changes and want to see what's drifted from the locked record. The snapshot itself isn't modified — Compare is read-only.

Audit log

Every snapshot operation writes to the vault's audit log. Visible actions:

  • SNAPSHOT_CREATED — with source MANUAL or AUTO_ON_FIRST_PUBLISH
  • SNAPSHOT_VIEWED — buyer or owner opened the trust panel
  • SNAPSHOT_INTEGRITY_VERIFIED — re-hashed the manifest
  • FILE_INTEGRITY_VERIFIED — re-hashed a specific file's content
  • SNAPSHOT_MANIFEST_EXPORTED — raw manifest pulled
  • SNAPSHOT_PACKAGE_EXPORTED — full ZIP package pulled
  • SNAPSHOT_VISIBILITY_CHANGED — visibility flipped (with from/to)

Sellers see this log on a per-snapshot basis. Staff can see it across the platform during incident investigation.