This item is about the message only — no explosive, incendiary, or destructive-carrier anything, ever.
Q-Branch · Item A3-3 · Theme: Burn After Reading Slate

BURN AFTER
READING SLATE

Write a note. Get one link. The link opens the note once — or the timer runs out — and then the note is gone. Not hidden. Gone: the store keeps nothing after the burn.

PROTOTYPE · DEMO BELOW RUNS ON localStorage IN THIS BROWSER · REAL SERVICE: burn_server.py (PYTHON STDLIB ONLY) · CRYPTO: WebCrypto AES-GCM 256, RANDOM KEY IN THE LINK FRAGMENT ONLY
✓

Built-in Self-Test — Fixture

Runs automatically on load, against the same localStorage demo store as the panels below: create a test note → open it once (must succeed) → open it again (must show burned) → confirm the stored value never contained the plaintext. This is the demo of the service logic, running in this browser.

⏳ Running self-test…

▼ DEMO OF THE SERVICE LOGIC — in-browser, against localStorage. The real service (below) uses the identical protocol against burn_server.py. ▼

✎ Create a Burn Note (Demo)

Your note is encrypted in this page before anything is stored. Only ciphertext goes into the demo store. The key goes only into the link.

◐ Open a Burn Note (Demo)

Paste a burn link, or open one directly in the address bar — if this page loads with a burn link in its address, it tries to open it below. Opening deletes first, decrypts second: there is no second open.

The real service — burn_server.py

The demo above and the real service speak the same protocol. The difference is only where the ciphertext waits: localStorage in the demo, a small JSON store file on the home server in the real service. In both, the server/store never sees plaintext and never sees the key.

Run it on the home server (Python 3, nothing to install — standard library only). From the folder holding burn_server.py:

python3 burn_server.py --host 127.0.0.1 --port 8765

That binds to localhost only. To reach it from another device on the trusted home LAN only, bind the server's LAN address instead (for example --host 192.168.1.241). Never expose it to the internet. Stop it with Ctrl+C. Its whole state is one file, burn_store.json, beside the script (or pass --store /path/to/store.json).

How the protocol works, step by step:

1. Create: this page generates a fresh random AES-GCM 256-bit key, encrypts the note in the browser, and sends only the ciphertext plus a time-to-live to POST /new. The server files the ciphertext under a random ID with an expiry and returns the ID.
2. The link: the page builds /n/<id>#<key>. The key sits after the # — the URL fragment. Browsers never send fragments to a server, in any request, ever. That is not a promise by this code; it is how URLs work.
3. Open (once): whoever opens the link asks the server for GET /n/<id>. The server returns the ciphertext exactly once, deletes the record, and rewrites the store file without it — then the page decrypts locally with the fragment key.
4. Gone: a second GET /n/<id> returns 410 Gone. So do expired notes: records past their timer are purged on access and on a periodic sweep, and after a burn the ciphertext is gone from the store file itself, not just flagged.
5. What the server can see: ciphertext, an ID, and an expiry time. Nothing else. A stolen store file is a pile of ciphertext with no keys anywhere near it.

Honest limits: anyone holding the full link can open the note (once) — the link is the credential, so carry it like one. Screenshots, copying the opened note, or the reader's own memory are outside any burn system's reach. Metadata (that a note existed, its size, its expiry) is visible to the server operator.