---
id: STATE-PFM-QRY-009
title: Workspace data export execution
object: DOM-PFM-QRY-004
product_area: platform
module: queries
revision: 1
status: draft
design_intent: confirmed
implementation_evidence: partially-observed
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
states:
  - name: queued
    meaning: >-
      Admission copied the workspace settings and cutoff into a queued request; no deployed runner
      advances it.
  - name: running
    meaning: >-
      The persistence schema supports in-progress generation, but the corresponding dispatcher and
      job execution are not deployed.
  - name: succeeded
    meaning: >-
      The settlement helper recorded final counts and a manifest digest; package publication is
      separate, unfinished orchestration.
  - name: failed
    meaning: The persistence helper recorded failure details and settled time.
  - name: cancelled
    meaning: >-
      The cancellation helper settled unfinished work; the customer cancellation route is still
      unavailable.
transitions:
  - from: queued
    to: running
    trigger: The mark-running helper is invoked by future orchestration.
    guard: The row is queued; the helper does not check a cluster slot and no dispatcher is deployed.
    side_effects:
      - start time and supplied execution progress metadata are saved
    who: 'system (generation dispatcher, not yet built)'
    provenance: observed
    source: 'services-platform:modules/data-exports/services/persistence/executions.ts:markRunning'
  - from: running
    to: succeeded
    trigger: The completion helper records successful execution.
    guard: The locked row is running.
    side_effects:
      - >-
        settled time, counts and manifest digest are recorded; no package or delivery row is created
        here
    who: 'system (generation job, not yet built)'
    provenance: observed
    source: 'services-platform:modules/data-exports/services/persistence/executions.ts:markSucceeded'
  - from: running
    to: failed
    trigger: The failure helper settles running execution.
    guard: The locked row is queued or running.
    side_effects:
      - 'the supplied failure code, summary and phase are saved'
    who: system (job failure consequence)
    provenance: observed
    source: 'services-platform:modules/data-exports/services/generation/data-export-job-type.ts'
  - from: queued
    to: failed
    trigger: The failure helper settles execution before generation starts.
    guard: The locked row is queued or running.
    side_effects:
      - failure metadata and settlement time are recorded
    who: system
    provenance: observed
    source: 'services-platform:modules/data-exports/services/persistence/executions.ts:markFailed'
  - from: queued
    to: cancelled
    trigger: The cancellation helper is called for queued work.
    guard: The locked row is unfinished; the customer route is unimplemented.
    side_effects:
      - the row is marked cancelled with settlement time
    who: administrator with execute permission (future)
    provenance: observed
    source: 'services-platform:modules/data-exports/services/persistence/executions.ts:markCancelled'
  - from: running
    to: cancelled
    trigger: The cancellation helper is called for running work.
    guard: The locked row is unfinished; the customer route is unimplemented.
    side_effects:
      - the row is marked cancelled with settlement time
    who: administrator with execute permission (future)
    provenance: observed
    source: 'services-platform:modules/data-exports/services/persistence/executions.ts:markCancelled'
invalid:
  - from: succeeded
    to: running
    why: Terminal execution rows cannot be reopened by the state helper.
  - from: cancelled
    to: queued
    why: Cancellation is terminal; the helper rejects a transition from it back into admission.
concurrency: >-
  A partial unique index limits each workspace to one queued or running execution. Admission locks
  settings to serialize competing requests. With no dispatcher and no implemented cancel route, the
  first queued request prevents later admission.
invariants:
  - INV-DOM-PFM-QRY-004-09
  - INV-DOM-PFM-QRY-004-10
  - INV-DOM-PFM-QRY-004-11
  - INV-DOM-PFM-QRY-004-12
evidence:
  - >-
    services-platform at ad3f6a6: modules/data-exports/db/data-export-executions.table.ts;
    services/persistence/executions.ts; services/executions/admit-execution.ts;
    services/generation/data-export-job-type.ts; aws/api/executions.routes.ts; docs/data-exports.md
  - >-
    services-platform at ad3f6a6: docs/proposals/tenant-data-export/11-execution-lifecycle.md,
    20-risks-tradeoffs-decisions.md (decided 2026-10-18)
---

# Workspace data export execution

## The Lifecycle

```mermaid
stateDiagram-v2
  state "queued" as s0
  state "running" as s1
  state "succeeded" as s2
  state "failed" as s3
  state "cancelled" as s4
  s0 --> s1
  s1 --> s2
  s1 --> s3
  s0 --> s3
  s0 --> s4
  s1 --> s4
```

The workspace export lifecycle has persistence support beyond the deployed customer flow. Admission is implemented; generation and customer recovery are not.

## Transitions Explained

State helpers update execution status, times and outcome metadata under a row lock. They do not create packages or orchestrate delivery as a side effect.

## What Cannot Happen

The starting-state checks protect helper calls, but they do not prove a working generation engine.

## Concurrency and Timing

One active-slot admission remains occupied indefinitely at the pinned implementation until staff or later implementation settles it.
