---
id: STATE-PFM-SEC-002
title: Workspace business status
object: DOM-PFM-SEC-002
product_area: platform
module: security
revision: 1
status: draft
design_intent: confirmed
origin: services-platform:docs/tenants/tenant-lifecycle-plan.md#2.2 One record, two axes; docs/hq/rhythm-hq-plan.md#D10
implementation_evidence: observed
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
states:
- name: implementation
  meaning: Implementation is under way; this is the default business status for a new workspace.
  provenance: observed
  source: services-platform:modules/tenants/db/tenants.table.ts:tenants (tenants_deletion_pending_status_check)
- name: live
  meaning: The association is using the workspace for its live operations.
  provenance: observed
  source: services-platform:modules/tenants/tests/integration/services/persistence/tenants.integration.spec.js#lets
    a sandbox tenant go live, the data-import check being recorded as debt
- name: disabled
  meaning: Ordinary customer operations are blocked, while eligible HQ staff can inspect through HQ routes.
  provenance: observed
  source: services-platform:modules/tenants/aws/api/tenants.routes.ts:patchHqTenant (requireStatusAuthority)
transitions:
- from: implementation
  to: live
  trigger: Staff mark implementation work live.
  guard: The caller has workspace-update and status-management authority; loading is refused, but import completion
    is not checked.
  side_effects:
  - Invalidate local availability
  who: Rhythm staff
  provenance: test
  source: services-platform:modules/tenants/tests/integration/services/persistence/tenants.integration.spec.js#lets
    a sandbox tenant go live, the data-import check being recorded as debt
- from: live
  to: disabled
  trigger: Staff disable a live workspace.
  guard: A versioned staff edit passes status-management checks.
  side_effects:
  - Ordinary availability stops within the process cache bound
  who: Rhythm staff
  provenance: observed
  source: services-platform:modules/tenants/aws/api/tenants.routes.ts:patchHqTenant (requireStatusAuthority)
- from: implementation
  to: disabled
  trigger: Staff disable an implementation workspace.
  guard: Status-management checks pass and the workspace is not loading.
  side_effects:
  - Block ordinary availability
  who: Rhythm staff
  provenance: observed
  source: services-platform:modules/tenants/aws/api/tenants.routes.ts:patchHqTenant (requireStatusAuthority)
- from: disabled
  to: live
  trigger: Staff re-enable a disabled workspace as live.
  guard: Status-management checks pass and retirement is neither pending nor executing.
  side_effects:
  - Allow ordinary availability when lifecycle is active
  who: Rhythm staff
  provenance: observed
  source: services-platform:modules/tenants/db/tenants.table.ts:tenants (tenants_deletion_pending_status_check)
- from: disabled
  to: implementation
  trigger: Staff re-enable a disabled workspace for implementation.
  guard: Status-management checks pass and retirement is neither pending nor executing.
  side_effects:
  - Allow ordinary availability when lifecycle is active
  who: Rhythm staff
  provenance: observed
  source: services-platform:modules/tenants/db/tenants.table.ts:tenants (tenants_deletion_pending_status_check)
- from: live
  to: implementation
  trigger: Staff return a live workspace to implementation.
  guard: The caller has staff status-management authority.
  side_effects: []
  who: Rhythm staff
  provenance: observed
  source: services-platform:modules/tenants/db/tenants.table.ts:TENANT_STATUSES
invalid:
- from: disabled
  to: live
  why: Database checks reject a live status while deletion is pending or executing.
  provenance: observed
  source: services-platform:modules/tenants/db/tenants.table.ts:tenants (tenants_deletion_pending_status_check)
- from: implementation
  to: live
  why: Loading requires implementation status, so the edit is refused during an open load.
  provenance: observed
  source: services-platform:modules/tenants/tests/integration/services/persistence/tenants.integration.spec.js#lets
    a sandbox tenant go live, the data-import check being recorded as debt
- from: live
  to: disabled
  why: Console customer edits cannot supply the staff-only status change.
  provenance: observed
  source: services-platform:modules/tenants/aws/api/tenants.routes.ts:patchHqTenant (requireStatusAuthority)
concurrency: Status edits use the workspace record version. Database constraints on the same row protect compatibility
  between business status and lifecycle, so concurrent changes cannot commit an invalid pair.
invariants:
- INV-DOM-PFM-SEC-002-04
- INV-DOM-PFM-SEC-002-07
evidence:
- 'services-platform at ad3f6a65: modules/tenants/db/tenants.table.ts; aws/api/tenants.routes.ts, tenant-api-mapper.ts;
  services/access/tenant-availability.ts.'
examined_at: '2026-10-23'
examiner: codex
---

# Workspace business status

## The Lifecycle

```mermaid
stateDiagram-v2
    state "Implementation" as implementation
    state "Live" as live
    state "Disabled" as disabled
    implementation --> live
    live --> disabled
    implementation --> disabled
    disabled --> live
    disabled --> implementation
    live --> implementation
```

The diagram summarizes the observed transition rows; declared edges without an observed writer remain outside the operational graph.

## Transitions Explained

Staff edit business status separately from lifecycle readiness. The listed directions are ordinary record edits with permission and database checks, rather than a dedicated workflow graph.

Moving to live does not prove that an initial import completed. The planning expectation and the observed edit behavior remain distinct.

## What Cannot Happen

Database checks reject a live status while deletion is pending or executing.

Loading requires implementation status, so the edit is refused during an open load.

Console customer edits cannot supply the staff-only status change.

## Concurrency and Timing

Status edits use the workspace record version. Database constraints on the same row protect compatibility between business status and lifecycle, so concurrent changes cannot commit an invalid pair.
