Retention and deletion
Apply explicit policies to streams, project state, evidence, provider data, and security records.
Outcome
Every stored class has an explicit region, encryption, retention, deletion, backup, export, and model provider policy. Project deletion is an idempotent, two-phase reconciliation: optional export remains available before the terminal tombstone, external resources are verified outside the API transaction, and still-referenced evidence is disclosed instead of silently destroyed.
Retention classes
GET /api/retention-policies returns the migration-owned version 1 catalog. Its seven classes are:
| Class | Retention and deletion behavior |
|---|---|
| Transient stream chunks | Memory-only transport data uses a bounded replay window and is not independently backed up or exported. Normalized product events are stored separately. |
| Ordinary project state | Canonical PostgreSQL state lives for the project lifetime, is included in project archives, and reaches a user-facing tombstone only after reconciliation. |
| Immutable evidence artifacts | Create-only bytes live for the project lifetime or a reference hold. Unreferenced objects require verified external purge; referenced evidence and lineage are retained and disclosed. |
| Sensitive source data | Uses the deployment region and selected provider profile. A shorter configured policy may apply, but provider and storage deletion still require verification. |
| Provider prompts and responses | Canonical copies and provider-held copies follow their respective policies. Hidden reasoning is never retained. |
| Audit and security events | Append-only records follow the operator cutoff and remain support-scoped after a user-facing tombstone. |
| Deleted, export-pending data | Remains readable and exportable until reconciliation finishes; backups expire under their configured policy rather than being claimed as immediately erased. |
The catalog does not claim provider zero retention. Make that claim only after verifying the exact account, endpoint, and contract in use.
Prerequisites
- Confirm the exact workspace and project IDs and identify legal, contractual, evidence, or reproducibility holds.
- Stop or disable every project schedule and bring every run and attempt to a terminal state. The request is rejected while scheduled or active execution exists.
- Decide whether the user requires a portable project archive. This decision is explicit:
require_exportorskip_export. - Use a new command ID, a stable idempotency key, and the current project version. A duplicate with the same actor, key, and payload returns the original receipt; key reuse with a different payload is rejected.
Steps
- Send
POST /api/projects/{project_id}/deletion/request. A required export moves the project toexport_pending; otherwise it moves directly todeletion_pending. New project-scoped rows from the app, worker, and gateway are frozen at the database boundary. Trusted worker updates remain available for cleanup reconciliation. - While
export_pending, create and verify the archive, then acknowledge its exact manifest digest withPOST /api/projects/{project_id}/deletion/export-complete. The project remains readable and exportable until this acknowledgement succeeds. - Read
GET /api/projects/{project_id}/deletion. Reconcile every reported blocker, including runtime sessions, sandboxes and leases, pending interactions, external operations, archive imports, and outbox work. Retries keep the same deletion generation. - Build the exact unreferenced-artifact purge plan through the worker boundary. Delete those object bytes from the configured artifact store outside the API database transaction, verify the result, and preserve the purge-plan digest plus cleanup-receipt digest. If the plan changes, rebuild and reconcile it rather than widening the target.
- Send
POST /api/projects/{project_id}/deletion/finalizewith current project/deletion versions, the deletion generation, exact purge-plan digest, object purge status, and receipt digest when a purge was required.
Finalization records artifact counts, retained-reference and purge-plan digests, the cleanup receipt,
and an append-only event. It then transitions the project to tombstoned through a narrowly scoped,
membership-checked database function. The API never deletes object bytes inside this transaction.
Do not describe provider “zero retention” unless the selected account, endpoint, and contract have been verified.
Verify
Verify all of the following:
- The deletion projection is terminal and exposes the recorded cleanup result.
- Project and child rows are hidden from application reads, including direct app-role queries.
- Unrelated workspaces and projects remain readable and unchanged.
- Provider inventories contain no active sandbox, lease, operation, or unreferenced artifact object for the deleted project.
- The number and digest of retained referenced artifacts match the recorded exception.
- Backup copies age out under the configured provider policy. A terminal tombstone is not proof of immediate backup erasure.
Recover
Before finalization, resolve an ambiguous provider response by inventorying the exact scoped resource and retrying reconciliation. Never assume deletion succeeded and never broaden a resource selector. After finalization, canonical tombstone, audit, cleanup, and referenced-evidence records intentionally remain; restoring a user-visible project is not supported. Use database and object-store recovery only for incident response under the backup runbook, not as an undelete workflow.