---
id: WF-PFM-QRY-018
title: 'Plan, admit, run and publish monthly snapshots'
trigger: >-
  The planner checks completed workspace-local months every fifteen minutes; staff can alternatively
  request a reasoned manual run or backfill.
product_area: platform
module: queries
revision: 1
status: draft
design_intent: confirmed
implementation_evidence: observed
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
inference: []
implements:
  - CAP-PFM-QRY-019
moves:
  - STATE-PFM-QRY-014
crosses:
  - SVC-PFM-QRY-snapshots
idempotency: >-
  Planning inserts only version one under uniqueness. Owner locking coordinates admission, and
  repeated failure consequences leave already-settled attempts unchanged.
concurrency: >-
  Unique indexes protect each period’s active and current version. The default admission cap is four
  with one backfill; worker and dispatcher limits follow configuration.
hops:
  - 'n': 1
    actor_or_service: Snapshot planner
    action: >-
      Plan the first period version for registered Platform types, retaining skipped reasons for
      loading or policy-disabled workspaces, then nudge dispatch.
    anchor: 'services-platform:modules/snapshots/aws/lambda/PLANNER.handler.ts'
    seam: schedule
    on_failure: The next pass can insert missed eligible period rows.
    left_inconsistent: A missing planned period remains visible through the overdue inspection gap.
    observer: the HQ period status and overdue reads
    provenance: observed
    source: 'services-platform:modules/snapshots/aws/logic/snapshots-functions.lambda.ts'
  - 'n': 2
    actor_or_service: HQ snapshot routes (alternative entry)
    action: >-
      Accept reasoned staff requests as new versions or backfill candidates, respecting active work
      and protected captured or finalized history.
    anchor: 'services-platform:modules/snapshots/aws/api/snapshots.routes.ts:requestSnapshotRunInHq'
    seam: sync
    on_failure: Refuse unsupported or overlapping requests with their reason.
    left_inconsistent: No accepted generation is implied by a staff refusal.
    observer: the staff member
    provenance: observed
    source: 'services-platform:modules/snapshots/aws/api/snapshots.routes.ts'
  - 'n': 3
    actor_or_service: Snapshot dispatcher
    action: >-
      Claim eligible or retry-due runs, create their attempt jobs and reoffer queued rows with no
      job after five minutes.
    anchor: >-
      services-platform:node_modules/@rhythmsoftware/macroservice-snapshots/dist/snapshot-dispatcher.js
    seam: schedule
    on_failure: Later dispatch and job reconciliation handle failed starts.
    left_inconsistent: A queued run can wait for attachment or execution of its job.
    observer: dispatcher alarms
    provenance: observed
    source: >-
      services-platform:node_modules/@rhythmsoftware/macroservice-snapshots/dist/snapshot-states.js
      (UNSTARTED_RUN_REOFFER_MINUTES)
  - 'n': 4
    actor_or_service: Snapshot run job
    action: >-
      Start or resume the attempt, retain the chosen generation mode, commit chunks with their
      cursor when needed, then finalize, validate and publish transactionally.
    anchor: 'services-platform:modules/snapshots/services/runs/snapshot-run-workflow.ts'
    seam: state_machine
    on_failure: >-
      Final validation failure settles the attempt; other faults use job retries before attempt
      backoff, with the fourth retryable failure final.
    left_inconsistent: Committed chunks can remain unpublished while the previous current version stays current.
    observer: run ledger; failure alarm; overdue alarm after 24 hours
    provenance: observed
    source: >-
      services-platform:node_modules/@rhythmsoftware/macroservice-snapshots/dist/snapshot-run-workflow.js:advanceSnapshotRun
  - 'n': 5
    actor_or_service: Report period picker (intended)
    action: 'Expose workspace periods with status, chosen version, basis, publication time and skip reason.'
    anchor: 'services-platform:modules/snapshots/aws/api/snapshots.routes.ts:listSnapshotPeriods'
    seam: sync
    on_failure: The period read returns its ordinary access or service refusal.
    left_inconsistent: The console has not integrated this answer into a report month selector.
    observer: the console (not yet consuming it)
    provenance: observed
    source: 'services-platform:modules/snapshots/services/persistence/snapshot-runs.ts'
branches:
  - Other snapshot owners use the shared ledger with their own roles and generation behavior.
  - The Platform self-test type is enabled in development and disabled in production configuration.
waits:
  - Published periods are due within twenty-four hours of month end; overdue status is alarmed.
evidence:
  - >-
    services-platform at ad3f6a6: modules/snapshots/**; @rhythmsoftware/macroservice-snapshots;
    docs/snapshots/README.md; docs/proposals/snapshot-architecture.md (D1–D8 approved 2026-10-15)
controls: [TC-AVL-001, TC-AVL-004, TC-AVL-005, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-AZ-005, TC-DAT-001, TC-DAT-003, TC-DAT-004, 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-002, 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-TEN-004, TC-VEN-001, TC-VEN-002, TC-VEN-003]
---

# Plan, admit, run and publish monthly snapshots

## What It Does

The planner checks completed workspace-local months every fifteen minutes; staff can alternatively request a reasoned manual run or backfill. Other snapshot owners use the shared ledger with their own roles and generation behavior.

## The Flow

```mermaid
sequenceDiagram
  participant C as Request or schedule
  participant H0 as Snapshot planner
  participant H1 as HQ snapshot routes alternative entry
  participant H2 as Snapshot dispatcher
  participant H3 as Snapshot run job
  participant H4 as Report period picker intended
  opt Scheduled planning
    C-)H0: Plan the first period version for registered Platform types, retaining skipped reasons for loading o
  end
  opt Manual or backfill entry
    C->>H1: Accept reasoned staff requests as new versions or backfill candidates, respecting active work and pr
  end
  H1-)H2: Claim eligible or retry-due runs, create their attempt jobs and reoffer queued rows with no job afte
  H2-)H3: Start or resume the attempt, retain the chosen generation mode, commit chunks with their cursor when
  H3->>H4: Expose workspace periods with status, chosen version, basis, publication time and skip reason
```

Plan the first period version for registered Platform types, retaining skipped reasons for loading or policy-disabled workspaces, then nudge dispatch. Accept reasoned staff requests as new versions or backfill candidates, respecting active work and protected captured or finalized history. Claim eligible or retry-due runs, create their attempt jobs and reoffer queued rows with no job after five minutes. Start or resume the attempt, retain the chosen generation mode, commit chunks with their cursor when needed, then finalize, validate and publish transactionally. Expose workspace periods with status, chosen version, basis, publication time and skip reason.

## When Something Fails

The next pass can insert missed eligible period rows. A missing planned period remains visible through the overdue inspection gap. Refuse unsupported or overlapping requests with their reason. No accepted generation is implied by a staff refusal. Later dispatch and job reconciliation handle failed starts. A queued run can wait for attachment or execution of its job. Final validation failure settles the attempt; other faults use job retries before attempt backoff, with the fourth retryable failure final. Committed chunks can remain unpublished while the previous current version stays current. The period read returns its ordinary access or service refusal. The console has not integrated this answer into a report month selector.

## Idempotency and Concurrency

Planning inserts only version one under uniqueness. Owner locking coordinates admission, and repeated failure consequences leave already-settled attempts unchanged. Unique indexes protect each period’s active and current version. The default admission cap is four with one backfill; worker and dispatcher limits follow configuration.
