Retention arrives in procurement as one question with an expected one-number answer. How long do you keep our documents? The number gets written into a settings field, the field gets a tooltip, and everyone moves on. Twelve months later someone asks where a specific passport scan went, and the honest answer is that nobody modelled the question the number was pretending to answer.
A document retention policy is not a duration. It is a set of clocks that start on different events, an override that outranks all of them, and a receipt that has to survive the thing it describes. The duration is the part that fits in a settings page, which is exactly why it is the part that gets built first and the part that fails last.
Our piece on the document AI control plane treats retention as one of several policies a control plane has to resolve per tenant. This one goes inside that policy: what the clock is keyed on, what suspends it, and what has to remain after the document is gone.
One number is the wrong shape
A single tenant-wide retention period assumes the documents are interchangeable. They are not. An identity document collected to open an account, the signed agreement that opened it, the invoice paid against it, and the extraction output derived from all three sit under different lawful bases, answer to different regulators, and have different reasons to still exist next year.
Give them one clock and you pick which one to get wrong. Set it short enough for the identity document and you delete the contract before the dispute window closes. Set it long enough for the contract and you hold biometric-adjacent data years past the purpose that justified collecting it. Neither failure shows up in testing, because both look like the setting working.
The fix is unglamorous: retention is configured per document class, and the classes are the ones the business already uses in its records schedule. If the schedule the legal team maintains has nine categories and the product offers one field, the product has not implemented the policy — it has implemented a number that the policy will contradict.
The clock starts on an event, not on the upload
This is the detail that quietly breaks otherwise correct implementations. Most retention rules worth having do not run from the day a file was ingested. They run from an event: the contract terminates, the account closes, the claim is settled, the employee leaves. Seven years after termination is a different date from seven years after upload, and for a document uploaded at the start of a ten-year relationship it is a different date by a decade.
A system that only knows ingestion time can express only one of those, and it will express it confidently. Every stored document therefore needs two things beside its class: the retention trigger it is waiting on, and the state of that trigger. Documents waiting on an event that has not happened are not overdue and are not exempt — they are pending, and a purge report that cannot show the pending bucket separately from the retained bucket is hiding the population most likely to be wrong.
The practical test: ask the system to answer "why is this document still here?" for one file. If the answer is a duration, the model is incomplete. If it is a rule, a trigger, a trigger state and a computed date, it is a policy.
A legal hold is a suspension, not a longer period
The most common way legal hold gets built is as a very large retention value. It demos correctly and it is wrong in four ways at once.
- It loses the reason — a hold exists because of a matter, and the matter is what eventually releases it. A number carries no matter.
- It cannot be scoped — real holds cover a subject, a date range and a set of document classes, not a tenant. A per-document duration override forces the scope to be flattened at the moment it is applied, so it cannot be re-evaluated as the matter's scope changes.
- It does not outrank a deletion request — a hold has to survive a customer-initiated erasure, and a system that expresses hold as retention will happily let a shorter, explicitly requested deletion win.
- It has no release — releasing a hold is an event with an actor and a timestamp that a regulator may ask about. Editing a number back down is not that event, and leaves nothing to show.
Modelled properly, a hold is its own record that references documents rather than modifying them. It is placed by someone, under a named matter, with a scope; it suspends every schedule it touches; it is released by someone, and both the placement and the release are part of the audit trail. The document's retention rule never changes. It just stops being the thing that decides.
Deletion has to leave evidence behind
The awkward requirement at the centre of the whole design is that you must delete the document and keep the proof that you deleted it. Those are opposite operations on the same object, and the only way through is that the proof is not made of the document.
A deletion record that is worth having names the document by its identifier and class, the rule that fired, the computed date, what triggered the computation, which derived artifacts went with it, and when. It does not contain the extracted values, the page text, a thumbnail, or the filename if the filename was the person's name. A deletion log that quotes the data it deleted is a copy of the data with a misleading title, and it is discoverable.
This is a different problem from the one in machine unlearning, which asks whether a model that trained on a document can be made to forget it. That question is about weights and embeddings and is genuinely hard. This one is about the stored artifact and its derivatives in the pipeline, and it is merely detailed — which is why it gets skipped.
Four places the schedule does not reach
Every implementation deletes the primary object. The gap is always downstream.
- Backups and snapshots — a restore that predates the purge resurrects the document. Either the backup window is shorter than the shortest retention period, or restores run through a re-application of the schedule. Saying "backups are excluded" is a defensible answer; not knowing is not.
- Derived artifacts — page images, OCR text, extraction JSON, search index entries, cached previews. Each is a copy of the content under a different name, and each needs to be enumerated in the deletion path rather than assumed to be covered.
- What already left — webhook payloads delivered to the customer, exports they downloaded, reports sent by email. These are outside the boundary and cannot be recalled. That belongs in the policy as a stated limit, not as an omission the customer discovers.
- The audit trail itself — it is subject to its own retention, usually longer, and it is the one record that must outlive the document. It is also the one place where the "no personal data in the log" rule earns its keep.
Where those copies physically live is a separate decision, and one we covered in data residency. A schedule that is correct in one region and unenforced in another is a schedule with a hole in it.
The race nobody models
The purge job runs overnight. The hold is placed at nine the next morning. What happened to the documents that came due at two?
If hold state is evaluated when the schedule is computed rather than when the deletion executes, the answer is that they are gone and the hold is decorative. The deletion path has to re-check hold state at the moment it acts, atomically with the delete, and refuse. This costs a lookup per document and removes an entire category of incident.
The second half is admitting the case that cannot be fixed. A hold placed on a document that was lawfully purged last week cannot bring it back, and the system should say exactly that — hold placed, N documents matched, M already deleted under rule R on date D — rather than reporting a clean success. Whoever placed the hold needs to know that number today, not during discovery.
A soft-delete quarantine window between "due" and "unrecoverable" makes this survivable, at the cost of holding data slightly longer than the schedule says. That is a real trade-off with a real answer, and the answer belongs in the policy where a customer can read it.
The five-line review
- What is each document class's clock, and which event starts it?
- What suspends that clock, who can place the suspension, and how is it released?
- When a document goes, which derived copies go with it — and which deliberately do not?
- What does the proof of deletion contain, and is any of it the data that was deleted?
- Who would notice if the purge job silently stopped running?
The last one is the tell. Retention is the rare control that fails by doing nothing, and doing nothing produces no error, no alert and no user complaint — only a slowly growing population of documents that should not exist. A retention setting is easy to ship. A retention policy is a set of clocks, an override that outranks them, and a receipt that outlives its subject.
