Theory

Trigger tampering yourself — TAMPER DETECTED

The caveat said this signature is tamper-evident. Do not take that on faith — trigger it. This whole step is hands-on; there is no new code.

1. Note the healthy state. Upload a document (or open one you already have) and view it. The banner is green: Integrity verified — the stored file still matches the SHA-256 recorded at upload. That is checkIntegrity re-hashing the bytes on disk and finding they match file_hash.

2. Tamper with the stored file. Find the blob on disk and change one byte. Its name is the storage_key:

$ psql "$DATABASE_URL" -c "select filename, storage_key from documents;"
$ printf 'x' >> uploads/7f3a9c1e0b2d4f6a8c5e1b3d7f9a2c4e   # append one byte

3. Reload the page. The banner is now red:

⚠ TAMPER DETECTED. The stored file no longer matches the SHA-256 recorded at upload.
  recorded at upload:  4a7d1ed414474e4033ac29ccb8653d9b...
  file right now:      9c1f77a2b4e6...

Nothing about the row changed — file_hash is the same number it always was. What changed is the recomputed hash of the bytes. The app re-derives the truth on every view; it never trusts the stored copy. That is why the tamper is visible at all.

4. Restore it and watch it clear. Undo the change (remove the byte, or re-upload) and reload — the banner goes green again. The check is live, not a stored flag.

5. Sign it while tampered — on purpose. Tamper again, open a signing link, and sign. It lets you — and the signed state records the altered hash, the one the signer actually saw, with the red banner still shown. This is the honest position: the app records evidence of what was signed; it does not prevent signing a changed file, and it never pretends the signature is more than a fingerprint. A signer who signs past a red banner did so knowingly, and the record says exactly which bytes they signed.

That is the difference between tamper-evidence and tamper-prevention, and between this and a qualified signature — felt, not just read.