---
id: WF-PFM-DJE-018
title: Purge expired submission keys
trigger: CRM dispatch enters its configured submission-ledger purge hour.
product_area: platform
module: data-job-engine
revision: 1
status: draft
design_intent: confirmed
origin: >-
  services-platform:docs/proposals/api-workload-governance/README.md brief 3.1
  (approved 2026-10-17: a daily purge of the submission ledger older than 30
  days, run by each service's reconciler)
implementation_evidence: partially-observed
inference: []
source_sha:
  services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
  macroservice-libraries: 54536a441935c6e09fdb7f96f0bec71c52ba4e03
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
implements:
  - CAP-PFM-DJE-005
  - CAP-PFM-DJE-001
moves: []
crosses:
  - SVC-PFM-DJE-crm-data-jobs
  - SVC-PFM-DJE-engine
hops:
  - 'n': 1
    actor_or_service: CRM job reconciler
    action: Visit workspace identities in order within the purge pass time budget.
    anchor: 'services-crm:modules/data-jobs/services/jobs/data-job-submission-purge.ts'
    seam: schedule
    on_failure: Log an unsuccessful workspace and continue later work.
    left_inconsistent: Old keys may remain until another pass.
    observer: Reconciler logs.
    provenance: documented
    source: >-
      services-crm:modules/data-jobs/services/jobs/data-job-submission-purge.ts
      (module comment)
  - 'n': 2
    actor_or_service: Engine purge
    action: >-
      Delete ledger entries older than 30 days in transactions of up to 1,000
      rows, capped at 50 transactions.
    anchor: >-
      macroservice-libraries:packages/data-jobs/src/submission-purge.ts:purgeDataJobSubmissions
    seam: sync
    on_failure: Roll back the failed transaction and retry on a later pass.
    left_inconsistent: Committed earlier deletion batches remain removed.
    observer: The response indicates whether the pass has remaining work.
    provenance: test
    source: >-
      macroservice-libraries:packages/data-jobs/src/tests/integration/submission-purge.integration.spec.ts#deletes
      the tenant's rows older than 30 days and keeps the rest, the row exactly
      30 days old included
idempotency: >-
  Removed keys are absent on subsequent passes. A saved cursor and bounded pass
  allow later invocations to continue remaining workspace work.
concurrency: >-
  Purge transactions establish one workspace context at a time under forced row
  security.
branches:
  - Platform has no scheduled caller for this purge.
  - >-
    No implemented sweep enforces the intended 90-day retention of jobs and
    outcome evidence.
waits: []
evidence:
  - >-
    services-crm at a8d1364f: services/jobs/data-job-submission-purge.ts;
    services/persistence/data-job-submissions.ts.
  - >-
    macroservice-libraries at 54536a44: src/submission-purge.ts; README.md#The
    submission ledger's retention.
  - >-
    services-platform at ad3f6a65: no purge caller found under
    modules/data-jobs.
controls: [TC-AVL-001, TC-AVL-004, TC-AVL-005, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-DAT-004, TC-DAT-005, TC-IAM-001, TC-IAM-002, 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-PI-001, TC-PI-002, TC-PI-003, TC-PI-004, TC-PI-005, TC-PRV-001, TC-PRV-002, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-TEN-004, TC-VEN-001, TC-VEN-002, TC-VEN-003]
---

# Purge Expired Submission Keys

## What It Does

CRM visits workspace ledgers and removes old submission keys in bounded transactions. This maintenance does not delete job evidence or enforce its intended retention window.

## The Flow

```mermaid
flowchart TD
  H1["CRM job reconciler"] --> H2
  H2["Engine purge"]
```

## When Something Fails

A failed workspace or exhausted time budget delays deletion rather than invalidating other completed passes. Keys can remain beyond their intended age; Platform keys have no scheduled removal at all.

## Open Design Questions

Job-evidence retention and Platform ledger maintenance remain unimplemented.
