diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 0deb446..49f7506 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -288,6 +288,32 @@ and circles (see Owner decisions). | A post's `replies` and `context` | **Publish public threads.** Public and unlisted posts name their `replies` and `context` collections, which list only the public and unlisted replies PrivaPub holds; followers-only, circle, direct and local-only posts never do. | | FEP-8fcf followers synchronisation | **Send digests.** A delivery to a server that the persona's followers there would get carries a `Collection-Synchronization` header: a digest of the persona's followers on that server only, and where that server reads that partial list. | +### Owner decisions on media, backups and archives (2026-10-07) + +The owner asked for media and file handling (posted and profile) to be audited for soundness, and for a backup and +restore system (JSON mostly, plus the files). + +| Question | Decision | +|---|---| +| What backups cover | **The whole server and a per-persona archive.** The server backup holds every collection as canonical Extended JSON and the media files (hard links); a persona's archive, in Mastodon's account-archive layout, can be restored into a persona. | +| Who runs them | **The CLI, a nightly schedule and the administrator's page, which can also restore.** This approves the `/clientapi/admin/backups` endpoints in production (download for the password, restore for the password and the host typed out). | +| Protection | **Plain archives, protected by file permissions** (`/var/lib/privapub/backups`, 2770, files 0640). No encryption. | +| Consistency | **Production's mongod becomes a one-member replica set** (`rs0`), so a backup reads every collection at one instant. `setup.sh` converts it, which needs a planned restart of mongod. | + +**Done 2026-10-07 (committed, not deployed):** +- media: files live exactly as long as something holds them (trash with a day's grace, janitor), finite focal points, + pictures checked before they are decoded, audio and video bounded and processed off the request, a bounded media + proxy, scheduled posts' media reserved, profile pictures as rows with `DELETE`, edits that reach the post, storage + counted, and `PrivaPub admin media audit [--fix]` for what came before; +- the server backup and restore: nightly, before each deploy (replacing mongodump) and from the page; a restore runs at + boot and never undoes a protective act (`tools/pasture/scenarios/restore.sh`, 19 checks, then `town.sh check` 2454/2454); +- a persona's archive, exported and imported (`tools/pasture/scenarios/persona-archive.sh` imports a real Mastodon + archive: 156 posts, nothing delivered). + +**At the next deploy, in this order:** `setup.sh` (the replica set, the backups directory, the runner in www-data's +group, the nginx locations), the deploy, `PrivaPub admin media audit` and, once its report is read, `--fix`; and the +owner's word on deleting the old pre-deploy dumps, which hold statistics salts. + ## Libraries (researched; no maintained .NET ActivityPub library exists, so Letterbook and Iceshrimp.NET both wrote their own) | Area | Choice |