---
id: STATE-PFM-QRY-001
title: Custom query table definition and its versions
object: DOM-PFM-QRY-001
product_area: platform
module: queries
revision: 1
status: draft
design_intent: confirmed
implementation_evidence: observed
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
states:
  - name: active
    meaning: >-
      Assigned workspaces can discover the active definition and execute its selected published
      version.
  - name: deprecated
    meaning: 'New dataset pickers omit the definition, while existing saved questions can still execute it.'
  - name: disabled
    meaning: >-
      Execution is refused with the recorded reason, and publication is unavailable until
      restoration.
  - name: draft version
    meaning: >-
      The editable version retains analysis; publication requires passing analysis of that same
      stored SQL.
  - name: published version
    meaning: >-
      The immutable released version is selected unless the workspace assignment pins another
      release.
  - name: superseded version
    meaning: A previous release remains historical and can still execute for assignments pinned to it.
transitions:
  - from: active
    to: deprecated
    trigger: Staff deprecate the definition using its read version.
    guard: The supplied version matches.
    side_effects:
      - >-
        a deprecation event and incremented definition version are committed; description stamps
        change
    who: Rhythm staff (hq.custom-query-tables.publish)
    provenance: observed
    source: 'services-platform:modules/queries/services/custom-tables/custom-table-library.ts:deprecate'
  - from: active
    to: disabled
    trigger: Staff disable the definition.
    guard: The supplied version matches.
    side_effects:
      - the disable event is recorded; dataset runs are refused
    who: Rhythm staff (hq.custom-query-tables.publish)
    provenance: observed
    source: 'services-platform:modules/queries/services/custom-tables/custom-table-library.ts:disable'
  - from: deprecated
    to: disabled
    trigger: Staff disable a deprecated definition.
    guard: The supplied version matches.
    side_effects:
      - the definition and its disable event are saved
    who: Rhythm staff (hq.custom-query-tables.publish)
    provenance: observed
    source: >-
      services-platform:modules/queries/services/persistence/custom-query-tables.ts:setCustomQueryTableStatus
  - from: deprecated
    to: active
    trigger: Staff restore a deprecated definition.
    guard: The supplied version matches.
    side_effects:
      - the restore event is saved; discovery resumes
    who: Rhythm staff (hq.custom-query-tables.publish)
    provenance: observed
    source: 'services-platform:modules/queries/services/custom-tables/custom-table-library.ts:restore'
  - from: disabled
    to: active
    trigger: Staff restore a disabled definition.
    guard: The supplied version matches.
    side_effects:
      - the restore event is saved; execution resumes
    who: Rhythm staff (hq.custom-query-tables.publish)
    provenance: observed
    source: 'services-platform:modules/queries/services/custom-tables/custom-table-library.ts:restore'
  - from: draft version
    to: published version
    trigger: Staff publish the analyzed draft.
    guard: >-
      The definition is enabled, validation workspace configured, analysis matches the SQL, record
      identity passes checks and breaking dependencies are acknowledged.
    side_effects:
      - >-
        the old release is superseded; the new release is selected; another draft and a publication
        event are created
    who: Rhythm staff (hq.custom-query-tables.publish)
    provenance: observed
    source: >-
      services-platform:modules/queries/services/persistence/custom-query-tables.ts:publishCustomTableDraft
  - from: published version
    to: superseded version
    trigger: Another draft is published.
    guard: The change occurs inside the publication transaction.
    side_effects:
      - existing pins can continue selecting the older version
    who: system (the publish)
    provenance: observed
    source: >-
      services-platform:db/migrations/0065_custom_query_tables.sql:custom_query_table_versions_immutable
  - from: active
    to: active
    trigger: Staff set the requested definition availability.
    guard: The supplied version matches; the previous availability is unrestricted.
    side_effects:
      - 'the requested status, incremented version and corresponding history event commit together'
    who: Rhythm staff (hq.custom-query-tables.publish)
    provenance: observed
    source: 'services-platform:modules/queries/services/custom-tables/custom-table-library.ts:restore'
  - from: deprecated
    to: deprecated
    trigger: Staff set the requested definition availability.
    guard: The supplied version matches; the previous availability is unrestricted.
    side_effects:
      - 'the requested status, incremented version and corresponding history event commit together'
    who: Rhythm staff (hq.custom-query-tables.publish)
    provenance: observed
    source: 'services-platform:modules/queries/services/custom-tables/custom-table-library.ts:deprecate'
  - from: disabled
    to: deprecated
    trigger: Staff set the requested definition availability.
    guard: The supplied version matches; the previous availability is unrestricted.
    side_effects:
      - 'the requested status, incremented version and corresponding history event commit together'
    who: Rhythm staff (hq.custom-query-tables.publish)
    provenance: observed
    source: 'services-platform:modules/queries/services/custom-tables/custom-table-library.ts:deprecate'
  - from: disabled
    to: disabled
    trigger: Staff set the requested definition availability.
    guard: The supplied version matches; the previous availability is unrestricted.
    side_effects:
      - 'the requested status, incremented version and corresponding history event commit together'
    who: Rhythm staff (hq.custom-query-tables.publish)
    provenance: observed
    source: 'services-platform:modules/queries/services/custom-tables/custom-table-library.ts:disable'
invalid:
  - from: disabled
    to: published version
    why: Publication requires restoration of a disabled definition.
  - from: published version
    to: draft version
    why: >-
      A database trigger prevents editing released content or deleting released versions; a new
      draft is separate.
  - from: superseded version
    to: published version
    why: >-
      Older releases remain superseded; an assignment pin selects one without restoring its
      publication status.
concurrency: >-
  Definition changes lock the row and compare the supplied version. Concurrent writers from one
  reading cannot both succeed. Lifecycle setters do not restrict the previous status, so repeated
  setters and changes from any of the three definition statuses are accepted and audited.
invariants:
  - INV-DOM-PFM-QRY-001-07
  - INV-DOM-PFM-QRY-001-08
  - INV-DOM-PFM-QRY-001-09
  - INV-DOM-PFM-QRY-001-11
evidence:
  - >-
    services-platform at ad3f6a6: modules/queries/services/custom-tables/custom-table-library.ts;
    services/persistence/custom-query-tables.ts; db/custom-query-tables.table.ts;
    db/custom-query-table-versions.table.ts;
    docs/queries/custom-query-tables/rhythm-custom-query-tables-architecture.md (phase 1 accepted
    2026-10-12)
---

# Custom query table definition and its versions

## The Lifecycle

```mermaid
stateDiagram-v2
  state "active" as s0
  state "deprecated" as s1
  state "disabled" as s2
  state "draft version" as s3
  state "published version" as s4
  state "superseded version" as s5
  s0 --> s1
  s0 --> s2
  s1 --> s2
  s1 --> s0
  s2 --> s0
  s3 --> s4
  s4 --> s5
  s0 --> s0
  s1 --> s1
  s2 --> s1
  s2 --> s2
```

Definition availability and version publication are separate dimensions. A definition can be active, deprecated or disabled while retaining its draft and released history.

## Transitions Explained

Publishing promotes the analyzed draft, supersedes the former release and creates another draft. Lifecycle setters record the requested status even when that status is unchanged.

## What Cannot Happen

Version immutability is database-enforced; publication also checks validation configuration and acknowledged breaking dependencies.

## Concurrency and Timing

Version checks serialize staff changes. Production lacks the configured validation workspace required for publication and nightly revalidation.
