The upload gate refuses any photo that would leave too little room to build the keepsake, and the archive needs both halves at once — so it demands `2.2 x media + 10 GB reserve + 1.5 GB headroom`. Every gigabyte of photos therefore costs about 3.2 GB of disk budget, and usable media works out at `(disk - 11.5 GB) / 3.2`. On a 30 GB volume that is only ~5.8 GB of photos. Measured, not theorised: a 945-photo wedding (8.74 GB of real files) stopped after ~780 photos with 24.98 GB free — the gate wanted 25.91 GB on a disk that was 79% empty. Uploads ended for want of an archive nobody had asked for yet. `KEEPSAKE_ENABLED=false` drops the archive term, leaving only `DISK_RESERVE_BYTES` — the one question still live without an archive, which is whether Postgres can still write. That turns the same 30 GB volume into ~20 GB of usable media. Verified against the exact disk state that ended the run: the photo that returned 413 with the keepsake armed is accepted with it off. The headroom term goes with it, deliberately. It exists only to keep this gate strictly ahead of the EXPORT PREFLIGHT, and with no keepsake there is no preflight to stay ahead of. Boot-time immutable, like COMMENTS_ENABLED: flipping it mid-event would move the gate under uploads already accepted against the old one. Releasing the gallery and minting download tickets are refused while it is off, and the host dashboard hides the release control rather than offering a button that answers 403 — a new `keepsake_enabled` field on `GET /host/event` carries that. The gate and the host's low-disk banner now share `upload_gate_required_free`. They were already two expressions of one threshold, and the banner exists to fire BEFORE the gate closes; applying the switch to only one of them would warn the host about a limit that can no longer fire, or stay silent past one that can. Tests pin the lead in both modes. The cost is real and worth stating plainly: there is no downloadable gallery at the end, so guests keep only what they save from the feed. Prefer a bigger disk where you can — ~45 GB holds this library with the keepsake intact. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
16 KiB
16 KiB