---
id: DOM-PFM-OPS-001
title: Background Job
product_area: platform
module: operations
revision: 1
status: draft
realises: CON-PFM-OPS-001
design_intent: proposed
implementation_evidence: observed
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  macroservice-libraries: 54536a441935c6e09fdb7f96f0bec71c52ba4e03
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
owned_by: SVC-PFM-OPS-jobs
readable_by: []
lifecycle: STATE-PFM-OPS-001
custom_fields: none
identity: >-
  Use kind and job identity to locate a run; the unique submission identity identifies one submitter intention
  within its kind.
attributes:
  - name: kind
    kind: enum
    required: true
    computed: false
    notes: The kind owner registers the type; cross-service readers can display kinds not registered in Platform.
  - name: status
    kind: enum
    required: true
    computed: false
    notes: 'The five statuses are pending, running, succeeded, failed and cancelled; the final three settle the run.'
  - name: progress
    kind: number
    required: true
    computed: true
    notes: >-
      Step-derived or declared progress remains between zero and one hundred, with reporting checks preventing
      regression.
  - name: submission identity
    kind: text
    required: true
    computed: false
    notes: A nonsecret submitter token identifies one intention within the kind.
  - name: requester
    kind: reference
    required: false
    computed: false
    notes: The initiating person is absent for system-created work.
  - name: scope
    kind: reference
    required: false
    computed: false
    notes: Optional customer and workspace references determine monitor reach.
  - name: 'requested, started, last activity and settled times'
    kind: date
    required: false
    computed: false
    notes: >-
      Request and activity times exist at submission; start and settlement times are nullable until those
      events.
  - name: last step and its status
    kind: reference
    required: false
    computed: true
    notes: The most recent step report supplies the summary reference and status.
  - name: execution handle
    kind: text
    required: false
    computed: false
    notes: Reconciliation and cancellation use the orchestration reference; public job responses omit it.
  - name: failure summary and reference
    kind: text
    required: false
    computed: false
    notes: A safe operator explanation is paired with a reference for diagnostic lookup.
  - name: retry lineage
    kind: reference
    required: false
    computed: false
    notes: A new retry points back to its predecessor.
  - name: cancellation request
    kind: text
    required: false
    computed: false
    notes: 'Cancellation records the requesting person, time and a reason limited to five hundred characters.'
  - name: steps
    kind: collection
    required: true
    computed: false
    notes: 'Submission records all catalogue steps as queued, with attempts and outcomes added during execution.'
  - name: history
    kind: collection
    required: true
    computed: false
    notes: Ordered events retain progress and the published definition used by this run.
  - name: subject
    kind: computed
    required: false
    computed: true
    notes: Presentation uses owner-supplied wording or a resolved workspace or customer name.
  - name: kind label and owning application
    kind: computed
    required: true
    computed: true
    notes: 'The common catalogue supplies labels, with a readable fallback for unknown kinds.'
  - name: requester notices
    kind: collection
    required: false
    computed: false
    notes: Separate success and failure notice rows retain claim attempts and delivery results.
relationships:
  - to: DOM-PFM-OPS-004
    cardinality: one workspace activation job to many workspace applications
    ownership: The related owner maintains the link; the provisioning job’s last step writes the core application rows
    cross_service: false
  - to: DOM-PFM-OPS-003
    cardinality: one licensing change to one access-refresh job
    ownership: The related owner maintains the link; a licensing write submits the refresh job owned by Security
    cross_service: false
invariants:
  - id: INV-DOM-PFM-OPS-001-01
    statement: One submission identity can identify only one job within a kind.
    enforced_at:
      - service
      - database
    provenance: observed
    source: >-
      macroservice-libraries:packages/jobs/src/persistence/job-persistence-columns.ts:jobRootConstraints
      (submission_uidx); macroservice-libraries:packages/jobs/src/engine/job-engine.ts:createJob
  - id: INV-DOM-PFM-OPS-001-02
    statement: 'Only the five declared job statuses are valid, with settlement time present exactly for final status.'
    enforced_at:
      - database
    provenance: observed
    source: >-
      macroservice-libraries:packages/jobs/src/persistence/job-persistence-columns.ts:jobRootConstraints
      (status_check, settled_check)
  - id: INV-DOM-PFM-OPS-001-03
    statement: >-
      Final jobs and steps cannot acquire another outcome; late reports for settled jobs are logged without
      changing them.
    enforced_at:
      - service
    provenance: test
    source: >-
      macroservice-libraries:packages/jobs/src/engine/job-engine.spec.ts#refuses settling an already terminal
      job
  - id: INV-DOM-PFM-OPS-001-04
    statement: >-
      Progress is bounded in the database; step reporting rejects earlier activity times and decreasing
      progress.
    enforced_at:
      - service
      - database
    provenance: test
    source: >-
      macroservice-libraries:packages/jobs/src/engine/job-engine.spec.ts#refuses progress that would move
      backwards
  - id: INV-DOM-PFM-OPS-001-05
    statement: 'A step report commits its step record, event and job summary together.'
    enforced_at:
      - service
    provenance: observed
    source: 'macroservice-libraries:packages/jobs/src/engine/job-engine.ts:applyStepTransition'
  - id: INV-DOM-PFM-OPS-001-06
    statement: >-
      The writer allocates increasing event sequences, with database uniqueness and positivity checks;
      ordinary engine paths do not edit history.
    enforced_at:
      - database
      - service
    provenance: observed
    source: >-
      macroservice-libraries:packages/jobs/src/persistence/job-persistence-columns.ts:jobEventConstraints
      (sequence_uidx, sequence_check); jobEventColumns;
      macroservice-libraries:packages/jobs/src/persistence/job-family-repository.ts:nextSequence
  - id: INV-DOM-PFM-OPS-001-07
    statement: Reconciliation cannot retain success when any step is running or retrying.
    enforced_at:
      - service
    provenance: observed
    source: 'macroservice-libraries:packages/jobs/src/engine/job-engine.ts:settleJobFromReconciliation'
  - id: INV-DOM-PFM-OPS-001-08
    statement: Every registered kind declares a business failure effect or explicitly declares no effect.
    enforced_at:
      - service
    provenance: test
    source: >-
      services-platform:modules/jobs/tests/unit/job-failure-consequences.spec.js#declares a failure
      consequence, or states there is none, for every registered kind
  - id: INV-DOM-PFM-OPS-001-09
    statement: >-
      The documented execution-input obligation excludes secrets and customer content, although arbitrary
      domain inputs are not inspected by the engine.
    enforced_at: []
    provenance: documented
    source: 'services-platform:docs/jobs.md#What may cross the asynchronous boundary'
  - id: INV-DOM-PFM-OPS-001-10
    statement: Retry requires a final predecessor of a retryable kind and creates a separate linked job.
    enforced_at:
      - service
    provenance: test
    source: >-
      macroservice-libraries:packages/jobs/src/engine/job-engine.spec.ts#refuses to create a retry of a kind
      that is not retryable
  - id: INV-DOM-PFM-OPS-001-11
    statement: Each job and outcome has at most one notice row; delivered and suppressed rows reject new claims.
    enforced_at:
      - database
      - service
    provenance: observed
    source: >-
      services-platform:modules/jobs/db/job-notices.table.ts (job_notices_outcome_uidx);
      modules/jobs/services/persistence/job-notices.ts:claimJobNotice
  - id: INV-DOM-PFM-OPS-001-12
    statement: Job API responses omit the orchestration handle and row version.
    enforced_at:
      - api
    provenance: test
    source: >-
      services-platform:modules/jobs/tests/e2e/jobs.e2e.spec.js#never puts the execution handle or the row
      version on the wire
physical:
  - job_notices
  - cross_job_query (view)
  - cross_job_steps (view)
  - cross_job_events (view)
  - >-
    each family’s <kind>_jobs, <kind>_job_steps and <kind>_job_events tables, owned by the module that owns
    the kind (for example tenant_provisioning_jobs, tenant_purge_jobs, authorizer_flush_jobs,
    snapshot_run_jobs, eligibility_population_jobs)
evidence:
  - >-
    macroservice-libraries at 54536a4: packages/jobs persistence/job-persistence-columns.ts,
    engine/job-engine.ts, engine/job-type-registry.ts, reconciler/job-reconciler.ts, api/job-wire.ts and
    api/job-scope.ts.
  - >-
    services-platform at ad3f6a6: modules/jobs (db, services, aws/api); docs/jobs.md;
    docs/hq/rhythm-hq-plan.md §D11, §D12, §E5.
  - >-
    codex examination 2026-10-23: checked the pinned source anchors, planning references and enforcement
    boundaries; unresolved limits are recorded in module findings.
---

# Background Job

## What It Models

A background job records work that continues after the initiating request. Orchestration executes it, the shared engine maintains its account, and the kind owner determines its business effect. Platform provides the common monitors, requester delivery and reconciliation of Platform jobs.

## Identity and Attributes

Kind and job identity together locate a run. The submission identity identifies the intention within its kind; uniqueness prevents a second record, although an insertion race inside a caller transaction requires caller retry. Submission creates the complete queued step list and the initial history. Started and settled times remain absent until their respective events. Step transitions derive progress, and declared progress reporting can also advance it.

## Relationships

Workspace lifecycle jobs create core application records and remove operational records during deletion. Licensing callers can request Security’s cache-refresh job. These are process relationships rather than mandatory foreign-key links between a licence decision and a job.

## Invariants

The structured invariants distinguish database shape checks from service behavior and documented input obligations. Reporting uses transactional step, event and summary writes. Final records reject changed outcomes, while late step reports are ignored and logged. A retry retains the old job and creates a linked run.

## How It Is Stored and Shared

Each kind owner keeps its root, step and event tables using the common persistence contract. Platform owns requester notice records and publishes its three monitoring views. The reader discovers compatible views across services and applies audience scope; it never writes another service’s jobs. Custom fields are absent.

## Open Design Questions

Cancellation has engine support but no Platform operation or screen. Caller-transaction submission conflicts, notice delivery and failure effects after corrected reconciliation retain the limits recorded in findings.
