---
id: STATE-PFM-LLM-003
title: Captured content lifecycle
object: DOM-PFM-LLM-001
product_area: platform
module: llm
revision: 1
status: draft
design_intent: confirmed
origin: >-
  D-1 (Andrew, 2026-10-18): every request's redacted request and response are captured and kept ninety days
  (services-platform:docs/proposals/llm-observability/11-decisions.md#Decision record).
implementation_evidence: observed
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
states:
  - name: pending
    meaning: No capture result has been recorded for this body.
  - name: captured
    meaning: The row refers to a redacted body written to object storage.
  - name: skipped
    meaning: The runtime had no configured evidence store.
  - name: failed
    meaning: 'Redaction, serialization or storage failed.'
  - name: purged
    meaning: A content read found the captured object absent or the stored state already indicates removal.
transitions:
  - from: pending
    to: captured
    trigger: The runtime writes a request or response body.
    guard: An evidence store exists and the body write succeeds.
    side_effects:
      - 'Redact secrets, preserve ordinary text, then record the object reference and expiry.'
    who: LLM foundation runtime
    provenance: observed
    source: 'services-platform:modules/llm/services/evidence/evidence-store.ts:captureEvidence'
  - from: pending
    to: skipped
    trigger: Capture runs without an evidence-store configuration.
    guard: No evidence store is available.
    side_effects:
      - Record skipped and emit a debug entry.
    who: LLM foundation runtime
    provenance: observed
    source: 'services-platform:modules/llm/services/evidence/evidence-store.ts:captureEvidence'
  - from: pending
    to: failed
    trigger: 'Capture encounters redaction, serialization or write failure.'
    guard: The capture helper catches an exception.
    side_effects:
      - Log safe failure metadata and return failed so processing may continue.
    who: LLM foundation runtime
    provenance: observed
    source: 'services-platform:modules/llm/services/evidence/evidence-store.ts:captureEvidence'
  - from: captured
    to: purged
    trigger: Expiry or workspace removal deletes the stored object.
    guard: A later read finds no object; the stored captured marker need not change.
    side_effects:
      - Answer purged without rewriting the request row.
    who: 'The evidence bucket''s lifecycle rule, or the organization deletion participant'
    provenance: observed
    source: 'services-platform:modules/llm/services/evidence/evidence-access.ts:readInvocationEvidence'
invalid:
  - from: captured
    to: pending
    why: >-
      The ordinary runtime has no reset-to-pending path; this is a flow limitation rather than a
      compare-and-set prohibition.
  - from: failed
    to: captured
    why: 'Failed capture has no configured retry, although capture persistence itself is not a lifecycle guard.'
  - from: purged
    to: captured
    why: Deleted bodies have no application restore operation.
concurrency: >-
  The runtime writes each body under its request-specific key and records metadata afterward. Failed metadata
  persistence can leave an unreferenced object. Reads translate pending to skipped; expiry is determined by
  storage policy rather than a synchronized database transition.
invariants:
  - INV-DOM-PFM-LLM-001-09
evidence:
  - >-
    services-platform at ad3f6a6: modules/llm/services/evidence/evidence-store.ts, evidence-redaction.ts,
    evidence-access.ts, tenant-evidence-objects.ts; services/persistence/invocations.ts:recordPayloadCapture;
    db/llm-invocations.table.ts (LLM_PAYLOAD_CAPTURE_STATUSES, LLM_EVIDENCE_RETENTION_DAYS);
    aws/resources/llm-evidence.s3.ts; services/maintenance/tenant-participant.ts.
---

# Captured content lifecycle

## The Lifecycle

```mermaid
stateDiagram-v2
  pending --> captured
  pending --> skipped
  pending --> failed
  captured --> purged
```

## Transitions Explained

Request and response capture progress independently. Admission refusals leave both pending. Capture failure is recorded without guaranteeing evidence exists. Purged can be a read-time answer while the row still says captured; deletion of an organization removes its dependent rows before its object versions.

## What Cannot Happen

The database requires an object reference for captured status. The runtime provides no capture retry or restore flow, but the metadata writer does not enforce a formal transition graph.

## Concurrency and Timing

The body and its reference are separate writes. The retention timestamp and ninety-day bucket policy express the same configured duration but do not establish simultaneous expiry. Noncurrent-version expiry is measured separately by object storage.
