# Design note — draft autosave

**Dated 2026-08-05. Written before the code, per the provenance practice in
[ROADMAP.md](../../ROADMAP.md#proving-independence).**

---

## The job to be done

Somebody writes a long reply. Then the tab closes, the laptop sleeps and wakes
up logged out, the phone rings and the browser gets killed in the background,
or they hit Post and the server says no. In every one of those, the writing is
gone and there is no way to get it back.

That is the whole problem. It is not "let me draft on my laptop and finish on
my phone" — that is a different, rarer job, and solving it is a different
feature.

## Decision 1 — the draft lives in the browser, not the database

`localStorage`, keyed per composer.

The failure being fixed happens **between** the keystroke and the request. A
server-side draft only helps if the browser managed to send it, which is
exactly what a crash prevents; it would need its own save request every few
seconds, and then a story about which of two devices holds the newer draft.

So the draft is written where the typing already is. It survives a crash, a
closed tab, a reboot, and a rejected post, because none of those involve the
network at all.

**What this deliberately does not do:** drafts do not follow a member to
another device, and clearing site data clears them. Server-backed drafts are a
reasonable next step and are written up at the end.

## Decision 2 — restore automatically, and say so

A restored draft that appears silently is two bad outcomes: confusing when
somebody meant to start fresh, and dangerous when they post three-week-old text
without noticing it was not what they just wrote.

A draft that needs a click to restore is friction in the common case, which is
a crash ten seconds ago.

So: **restore into the editor, and show a bar above it** saying when it was
written, with a way to discard it. Nothing is lost, and nothing is hidden.

## Decision 3 — the key includes who is signed in

A shared computer at a library or a family desk must not put one person's
half-written post into somebody else's composer. The key carries the signed-in
member's id, and a draft written by nobody (a guest) is not the same key as one
written by a member.

This is not a security boundary — anything in `localStorage` is readable by
anybody at that browser — it is about not actively handing one person's writing
to the next one who sits down.

## Decision 4 — a draft on an edit form only exists if it differs

Editing an existing post starts with the post already in the editor. A draft
that saved that unchanged content and restored it later would be indistinguishable
from the post itself, and the "you have a draft" bar would appear for no reason.

So on an edit form the draft is only written once the text differs from what
was loaded, and it is discarded the moment it matches again.

## Decision 5 — drafts expire

Fourteen days, checked on read. A draft nobody ever came back to is not useful
after a fortnight, and without expiry `localStorage` becomes a graveyard that
eventually hits the quota and starts failing the saves that *do* matter.

## Decision 6 — saving must never interrupt typing

- Debounced, not per keystroke.
- The quota can be full, and `setItem` throws when it is. That is caught and
  ignored: a failed autosave is a shame, an exception thrown into the editor's
  update handler is a composer that stops working.
- Nothing about the draft blocks or delays submitting.

## Decision 7 — a successful post clears it

The draft is removed when the form submits. If the *server* then rejects the
post, the page comes back with the content still in the field and the draft is
written again on the next keystroke — so a rejection is not a loss either.

## What this does not do

- **No server-backed drafts.** The next step if the browser-only version turns
  out to be the wrong shape: a `drafts` table keyed by member and target, saved
  on the same debounce, with a rule for which copy wins. It needs pruning, and
  it needs an answer for two devices holding different text — neither of which
  is worth building before anybody has asked for cross-device drafting.
- **No draft list.** "Show me everything I started and abandoned" is a
  different feature, and it only makes sense once drafts are on the server.
- **No autosave of the title.** Worth doing, and it is included — but only
  alongside the body, as part of the same draft. There is no separate
  title-only draft.
