Retention
How long things stay, and how they actually go away
A published schedule that a build can fail on, an unsigned row that becomes a hold rather than a deletion, one shared predicate for "not deleted", and a clear statement of what none of it says about your mail.
Two chips, and what they mean
Platform — a control that is built and running in the wider system this mailbox will live inside. Describing it is describing the house, not the room.
Mailbox — a statement about the address itself. Mailbox provisioning is a founder-confirmed step and is currently off, so every mailbox-scoped claim on this site is about what is built, never about a running inbox.
Every mechanism named on this site carries one of the two. That is not decoration: a platform control quoted as if it were a mailbox feature is a true sentence with its scope removed, and that is the most common way a page like this stops being honest.
The bound on this entire page
Everything below describes a MECHANISM: what a table contains, what a function computes, and which way a system falls when it does not know. Nothing here tells you what any rule requires of your organisation, characterises any obligation, or is a legal conclusion of any kind. If you need to know what you are required to keep, the person to ask is your own records officer, and this page is not a substitute for that conversation.
The mechanisms
6 things that exist, and the one that says what they do not cover
Every data class has a published clock, and a build fails if one does not
Platform Built and running
Each class of data carries a retention clock with an anchor and a finite number of days. What makes it a control rather than a document is the assertion beside it: a function walks every declared class, checks that each has a finite clock of at least one day, and separately checks that nothing has been scheduled under a name that is not a real class. The package's test calls it, so a class with no deletion timeframe cannot ship.
That is the difference between a retention policy and a retention schedule. One is a page somebody wrote; the other fails a build.
packages/compliance/src/data-retention-schedule.ts:155 (RETENTION_SCHEDULE) · :455 (assertNoIndefiniteRetention)
Deletion eligibility is computed, not remembered
Platform Built and running
Whether a row may be deleted is derived from its posture at the moment the question is asked, rather than stamped on it once and trusted forever. A deadline is computed from the anchor and the clock; eligibility is a function of the current state.
Computing it each time is the same discipline that appears everywhere in this codebase: a fact that was true in September and is read in February is not a fact, it is a memory.
packages/compliance/src/data-retention-schedule.ts:360 (deletionDeadline) · :405 (isDeletionEligible)
An unverified row falls to a hold rather than to a deletion
Platform Built and running
There is a table of per-state, per-class retention floors. Each row carries a citation string, the date it was last confirmed, and the name of the person who signed it. A row that nobody has signed carries a sentinel in the signer field instead of a name.
An unsigned row does not quietly behave as if there were no floor. It resolves to a fail-safe hold. The system's default when it does not know is to keep the data and wait for a human, which is the direction that cannot cause the irreversible mistake.
Read this next sentence as the scope bound on the whole paragraph: that is a description of how the mechanism behaves. It is not advice, it does not tell you what any rule requires of your organisation, and nothing on this site is a legal conclusion.
packages/compliance/src/state-retention-floor.ts:79 (NEEDS_SME) · :306 (resolveFloor)
Deleted means gone from every read, by construction
Platform Built and running
Tables that support soft deletion share one declared predicate for "live rows only", exported in both the query-builder form and the raw form, plus an explicit list of which tables are tombstoned at all.
One shared predicate is the point. The classic failure is nine queries that filter deleted rows and a tenth, added later, that does not -- and the tenth is a report, and the report is the thing somebody emails outside the building.
apps/api/src/store/retention-tombstone.ts:52 (LIVE_ONLY) · :79 (SQL_LIVE_ONLY) · :90 (TOMBSTONED_TABLES)
The human-readable policy is generated from the same table
Platform Built and running
The readable policy document is built from the same schedule the code enforces, rather than typed separately and kept in step by hand.
Two artifacts describing one rule will disagree eventually, and the one that disagrees is always the one somebody shows an outsider. Generating the document from the enforced table removes the possibility rather than promising diligence.
packages/compliance/src/data-retention-policy.ts:177 (buildDataRetentionPolicy) · :242 (renderRetentionPolicyMarkdown)
What none of the above says about your mail
Mailbox Built, latched off
The five rows above are platform controls over platform data classes. None of them is a statement about how long a message in a Castra mailbox is kept, because no Castra mailbox exists yet -- provisioning is a founder-confirmed step and it is off.
What can honestly be said today: storage comes with a mailbox, the plans on the plans page say how much, and the retention behaviour of the mailbox itself is a decision that has not been made and published. When it is, it will appear here in the same plain words, with the same scope chip, and the chip will say Mailbox.
Saying "our retention schedule covers your mail" would be the easiest sentence on this page to write. It would also be a platform fact with the scope stripped off, which is the specific way honest pages become dishonest ones.
mailbox/pricebook.ts (honest-off) · mailbox/brands.ts:502-533
The best thing in the code
There is a field whose only job is to say "nobody has checked this yet"
In the table of per-state retention floors, every row carries the name of the person who signed it. A row nobody has signed does not carry an empty string or a plausible-looking default. It carries a sentinel value that means, in plain terms, this needs a subject-matter expert and has not had one.
And the resolver treats an unsigned row as a reason to hold rather than a reason to proceed. Not knowing does not degrade into acting as though the answer were the convenient one.
This is a small thing and it is the single most reassuring artifact in the whole area, because it is evidence of a habit that cannot be faked in a sales conversation: somebody wrote down what they did not know, in a place where the software would act on the admission, and accepted that the software would then behave more conservatively than they might like.
The opposite habit -- a blank field that reads as zero, a default that reads as approved -- is how a system ends up deleting something on the strength of a row that nobody ever confirmed.
packages/compliance/src/state-retention-floor.ts:79 (the sentinel) · :289 (isFloorVerified) · :306 (resolveFloor)
The part about your mail
None of the above is a statement about how long your messages are kept
Mailbox Everything on this page above this heading is platform-scoped: schedules and floors over the platform's own data classes. A Castra mailbox is not provisioned, so there is no message store here for any of it to apply to.
What can honestly be said today is short. Storage comes with a mailbox and the plans page states how much. The retention behaviour of the mailbox itself -- how long a message is kept, what happens when an account is closed, what an administrator can and cannot recover -- is a decision that has not been made and published, and inventing an answer for a marketing page would be exactly the wrong way to make it.
When it is decided, it will appear on this page in the same plain words, with a mailbox chip on it, and the sentence you are reading now will be replaced rather than quietly deleted.
If the answer matters to your decision, that is a good reason to write and ask rather than to read anything into the silence.
Elsewhere on this site
The rest of it
Overview
Who this address is for, and what a security claim can honestly mean when a product is not provisioned.
Read it →Who can open what
Permissions, tenancy scope, the access trail, and a hash chain that makes tampering detectable rather than impossible.
Read it →What we will not say
The badge wall we do not have, the words we refuse, and the questions we answer with 'we do not know yet'.
Read it →Plans
Catalog figures for planning a budget. Checkout is not open and nothing here bills.
Read it →