---
id: WF-PFM-TNL-015
title: Reapply recorded deletions after a restore
trigger: Reapply earlier completed deletions to workspaces brought back by database restore.
product_area: platform
module: tenant-lifecycle
revision: 1
status: draft
design_intent: confirmed
origin: services-platform:docs/tenants/tenant-lifecycle-plan.md#§9 Restoring without resurrecting (approved 2026-10-09)
implementation_evidence: observed
inference: []
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
implements:
- CAP-PFM-TNL-018
- CAP-PFM-TNL-017
moves:
- STATE-PFM-TNL-001
- STATE-PFM-TNL-004
crosses:
- SVC-PFM-TNL-tenants
idempotency: Dry run inspects without writes. An already-deleting workspace with an executing request is reported
  rather than given another purge.
concurrency: Workspace reapplication runs sequentially with a transaction per candidate. A failure leaves earlier
  committed candidates intact.
hops:
- n: 1
  actor_or_service: Reapplication script
  action: Require staff and enumerate ledger workspace identities with optional filtering.
  anchor: services-platform:modules/tenants/services/deletion/reapply-deletions.ts:reapplyDeletedTenants
  seam: sync
  on_failure: Stop on access or ledger-list failure.
  left_inconsistent: No restored workspace is changed.
  observer: Job progress and service logs.
  provenance: observed
  source: services-platform:modules/tenants/services/deletion/reapply-deletions.ts
- n: 2
  actor_or_service: Reapplication script
  action: Inspect each ledger entry and workspace, reporting missing, unreadable or already-removing cases.
  anchor: services-platform:modules/tenants/services/deletion/reapply-deletions.ts
  seam: sync
  on_failure: Report the per-workspace error and continue.
  left_inconsistent: Dry run records no new work.
  observer: Job progress and service logs.
  provenance: observed
  source: services-platform:modules/tenants/services/deletion/reapply-deletions.ts
- n: 3
  actor_or_service: Reapplication script (apply)
  action: On apply, force disabled deleting standing and recover a request and purge job within that workspace’s
    transaction.
  anchor: services-platform:modules/tenants/services/persistence/tenants.ts:forceTenantDeletingAfterRestore
  seam: sync
  on_failure: Roll back that workspace on failure and continue.
  left_inconsistent: A restored workspace can be accessible before reapplication because the gate ignores the ledger.
  observer: Job progress and service logs.
  provenance: observed
  source: services-platform:modules/tenants/services/deletion/reapply-deletions.ts
- n: 4
  actor_or_service: Reapplication script (apply)
  action: Start the recorded purge using the normal removal workflow.
  anchor: services-platform:modules/tenants/services/deletion/reapply-deletions.ts
  seam: state_machine
  on_failure: Log the start result and rely on shared job recovery where applicable.
  left_inconsistent: A committed reapplication can await execution recovery.
  observer: Job progress and service logs.
  provenance: observed
  source: services-platform:modules/tenants/services/deletion/reapply-deletions.ts
branches:
- Inspection is the default; apply is an explicit script mode.
waits: []
evidence:
- 'services-platform at ad3f6a65: modules/tenants/services/deletion/{reapply-deletions, deletion-ledger}.ts; scripts/reapply-deletions.ts;
  services/persistence/tenants.ts; docs/tenants/runbook.md.'
controls: [TC-AVL-001, TC-AVL-002, TC-AVL-003, TC-AVL-004, TC-AVL-005, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-AZ-005, TC-AZ-006, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-DAT-004, TC-DAT-006, TC-DAT-007, TC-IAM-001, TC-IAM-002, TC-IAM-003, TC-IAM-004, TC-IAM-005, TC-IAM-006, TC-LOG-001, TC-LOG-002, TC-LOG-003, TC-LOG-004, TC-LOG-005, TC-MON-001, TC-MON-003, TC-PI-001, TC-PI-002, TC-PI-003, TC-PI-004, TC-PI-005, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-VEN-001, TC-VEN-002, TC-VEN-003]
---

# Reapply Recorded Deletions After A Restore

## What It Does

Reapply earlier completed deletions to workspaces brought back by database restore. Dry run inspects without writes. An already-deleting workspace with an executing request is reported rather than given another purge.

## The Flow

```mermaid
sequenceDiagram
  autonumber
  actor Op as Operator
  participant Scr as Reapplication script
  participant Led as Deletion ledger
  participant DB as Restored database
  participant Purge as Purge job
  Op->>Scr: dry run
  Scr->>Led: every deleted workspace
  Scr->>DB: which are back?
  Scr-->>Op: what would be done
  Op->>Scr: apply
  loop each restored workspace
    Scr->>DB: force deleting and disabled, request executing, purge job (one commit)
    Scr->>Purge: start
  end
```

## When Something Fails

Stop on access or ledger-list failure. No restored workspace is changed. Report the per-workspace error and continue. Dry run records no new work. Roll back that workspace on failure and continue. A restored workspace can be accessible before reapplication because the gate ignores the ledger. Log the start result and rely on shared job recovery where applicable. A committed reapplication can await execution recovery.

## Open Design Questions

Restored workspaces remain accessible until reapplication because the gate does not consult the ledger. Script execution proof remains absent.
