Six states, and what each one publishes
Where a member stands, what that publishes, and what is kept on disk either way.
| State | Publication | Storage |
|---|---|---|
| Never touched consent | Never published (opt-in is forward-only) | Kept, until the retention sweep; the only sweepable class |
| Opted in | Messages from the opt-in moment on publish, minus gaps, deletions, rejections, quarantine | Kept |
| Revoked, pending choice | Everything hidden the instant of revocation (derived, never a flag) | Kept; no default for a destructive decision |
| Revoked, hide | Hidden | Retained; restorable by the member alone |
| Revoked, delete | Hidden immediately | Destroyed per message; held items deferred until the hold releases |
| Consent gap | Messages sent while revoked never publish, even after restore | Kept |
Forward-only, both ways
Opting in is forward-only: it publishes what a member sends from that moment and never a word from before it. Revoking is the mirror image and takes effect at the instant, because publication is derived on every read rather than stored as a flag on a message.
The two revoked states are a real choice, and the system refuses to make it for anybody: hide keeps the messages and lets the member restore them, delete destroys them per message. There is no default for a destructive decision.
The gap that never closes
A consent gap is the case people forget. Messages sent while revoked never publish, even if the member opts in again later: the gap is permanent, so restoring consent cannot quietly publish what was said while it was withdrawn.
The operator cannot consent for anybody
The console page shows who is opted in and offers no control to change it. Members grant and revoke, and the replies they get are the legal notice.
Read-only — consent is granted and revoked exclusively by members via /publish and /unpublish
The operator can see who is opted in and read the counts, and cannot grant or revoke for anybody. That is not a missing feature: consent that an administrator can grant on a member's behalf is not consent, and the page is read-only so the question never arises. What a member sends is the whole mechanism, and the replies they get back are the legal notice.
You're opted in. From now on, the messages you post in this group may appear on the public web archive. This applies only to messages you send from this point onward - nothing you posted earlier. You can opt out at any time by sending /unpublish, which also removes your messages from the archive.
You're opted out. Your messages will not appear on the public web archive, and any of your messages that were published have been removed from it. You can opt in again at any time by sending /publish (only messages you send after opting in will be published). I will ask next whether to keep your messages hidden or destroy them for good.
What is deleted when nobody agreed to it
The one place the system destroys content on its own: what it reaches, what it leaves behind, when it runs, and why it ships switched off.
| What is swept | Non-bot rows older than the bound whose sender appears nowhere in the consent system (an allow-list, not a deny-list), with no hold, report, or pending destruction, plus her own paired replies to exactly those rows |
| What a tombstone keeps | Room, member id, timestamp and kind, so counts, deletions and capture idempotency stay correct |
| What a tombstone clears | Text, links, search body, raw JSON and the media path, with the media file unlinked in the same transaction. A tombstone still holding content is unrepresentable, enforced by a schema check |
| Trigger | Nightly at local midnight, self-rescheduling, and deliberately not at boot |
| Automatic | Only when switched on: sweeping ships OFF. A failed pass logs, reaches the dashboard, and re-arms |
| The bound | 24 hours to 1 year, default 24 hours, with a floor of twice the memory cap of 12 hours |
An allow-list, not a deny-list
The sweep is an ALLOW-LIST and that is the whole safety of it. It removes content from rows whose sender appears NOWHERE in the consent system: never opted in, never revoked, never asked. A member who has interacted with consent at all, in either direction, is outside its reach entirely, and so is anything under a hold, a report or a pending destruction.
What survives is a tombstone, and the page says exactly what that means rather than leaving a reader to guess whether "deleted" means gone.
The content is gone. The fact that a message existed is not.
Off until somebody turns it on
Sweeping ships OFF. Nothing is removed on any deployment until an operator switches it on, and the manual pass says plainly that it cannot be undone. When it is on it runs nightly at local midnight and reschedules itself, deliberately not at boot: a destructive job that fires whenever a process restarts is a destructive job nobody can predict.
A tombstone that still held content would be unrepresentable: the schema refuses the row. built
Check
migrations/070
The bound, and its floor
The bound runs from 24 hours to a year and ships at 24 hours, with a floor of twice the memory cap so a sweep can never remove something she might still be holding in a live conversation. The page counts what is waiting, what has already been swept, and when the next pass runs.
This is the one place the system destroys content without anybody asking it to, and it is off by default for that reason. Read the bound before switching it on: what it removes is everything from people who never answered the consent question at all.
The core keeps its own, and ships keeping it for ever
Clearing the archive is not clearing everything: the messaging core has its own retention, and its default is to keep.
The archive is not the only copy. The messaging core keeps its own store, with its own retention, applied to every hosted profile, and it ships keeping items FOR EVER. An operator who sets the sweep and stops there has cleared one copy and left the other.
The core's setting is retroactive, which the console says in its own words rather than leaving to be discovered.
This takes effect immediately, not just from now on.
What a member's revocation reaches, and what the archive publishes at all, is the archive plugin's subject; this page owns the sweep and the states. What she can see of a thread while replying is bounded separately, on the memory page.