---
id: CAP-PFM-OPS-015
title: Prepare and operate workspace applications
feature: FEAT-PFM-OPS-04
product_area: platform
module: operations
revision: 1
status: draft
product_intent: confirmed
implementation_evidence: observed
supersedes: []
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
intent_sources:
  - >-
    services-platform:docs/proposals/application-access-and-entitlements.md#6.2 (operational states; built and
    accepted 2026-10-15)
  - >-
    services-platform:docs/proposals/application-access-and-entitlements.md#10.2 Later (D5: automatic
    initialization on licence; default taken)
purpose: 'Establish application readiness and support deliberate suspension, recovery and resumption.'
outcomes:
  - Preparation and staff changes leave an explainable operational record.
  - Suspension and resumption preserve prepared information.
concepts:
  - CON-PFM-OPS-004
actors:
  - ACT-PFM-004
  - ACT-PFM-006
surfaces:
  - console
  - api
  - job
preconditions:
  - The staff caller holds HQ licensing-management authority for an operational action.
postconditions:
  - The workspace retains a single operational record for each prepared application.
permissions:
  - key: hq.licensing.manage
    where_checked: api
    scope: global
rules:
  - id: BR-CAP-PFM-OPS-015-01
    proved_by: [ATS-PFM-OPS-015-01, ATS-PFM-OPS-015-09, ATS-PFM-OPS-015-11, ATS-PFM-OPS-015-14, TST-PFM-OPS-087]
    statement: >-
      Application preparation records provisioning before running workspace participants and then records
      enabled or a participant-specific failure, without undoing the triggering commercial decision; enabled
      applications need no repeat preparation.
    kind: lifecycle
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/licensing/tests/integration/services/enablement/provision-tenant-application.integration.spec.js#says
      which participant could not run, in the reason an operator reads
    origin: none
  - id: BR-CAP-PFM-OPS-015-02
    proved_by: [ATS-PFM-OPS-013-09, ATS-PFM-OPS-014-10, ATS-PFM-OPS-015-02, ATS-PFM-OPS-015-10, ATS-PFM-OPS-015-14, TST-PFM-OPS-087]
    statement: >-
      Retry requires failed preparation, suspend requires enabled state and resume requires suspension, with
      absent operational records and invalid starting states refused.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/licensing/tests/integration/services/enablement/provision-tenant-application.integration.spec.js#refuses
      every move for an application the tenant has never been provisioned for
    origin: none
  - id: BR-CAP-PFM-OPS-015-03
    proved_by: [ATS-PFM-OPS-015-03, ATS-PFM-OPS-015-14, TST-PFM-OPS-081, TST-PFM-OPS-087]
    statement: >-
      Suspended and failed-preparation states require reasons, while enabled and provisioning states clear
      reasons; an unexplained suspension is refused.
    kind: validation
    enforced_at:
      - api
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/licensing/tests/e2e/licensing.e2e.spec.js#refuses a suspension with no reason,
      with 400
    origin: none
  - id: BR-CAP-PFM-OPS-015-04
    proved_by: [ATS-PFM-OPS-015-04]
    statement: Suspending and resuming retain application data and the original first-enabled timestamp.
    kind: invariant
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/licensing/tests/integration/services/persistence/tenant-applications.integration.spec.js#keeps
      the instant it was first enabled through a suspension and a resumption
    origin: none
  - id: BR-CAP-PFM-OPS-015-05
    proved_by: [ATS-PFM-OPS-015-05]
    statement: >-
      Staff state-change services request a flush after committing and routes then attempt audit insertion, so
      failures in later work do not undo state changes; rejected transitions request no flush.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: observed
    source: >-
      services-platform:modules/licensing/aws/api/licensing.routes.ts:suspendTenantApplication;
      services-platform:modules/licensing/services/enablement/provision-tenant-application.ts:suspendTenantApplication
    origin: none
  - id: BR-CAP-PFM-OPS-015-06
    proved_by: [ATS-PFM-OPS-015-06, TST-PFM-OPS-104]
    statement: >-
      Provisioning activation and deployment backfill add missing always-available operational rows without
      changing existing rows, including suspensions.
    kind: lifecycle
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/licensing/tests/integration/services/persistence/tenant-applications.integration.spec.js#leaves
      a suspended row suspended, so a redeploy never undoes an operational decision
    origin: 'services-platform:docs/licensing.md#6. Where the rows come from'
  - id: BR-CAP-PFM-OPS-015-07
    proved_by: [ATS-PFM-OPS-015-07, TST-PFM-OPS-081]
    statement: Staff application-state actions require licensing-management authority and refuse read-only staff.
    kind: permission
    enforced_at:
      - api
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/licensing/tests/e2e/licensing.e2e.spec.js#refuses a staff member who may only
      read, with 403
    origin: none
  - id: BR-CAP-PFM-OPS-015-08
    proved_by: [ATS-PFM-OPS-015-13, TST-PFM-OPS-104]
    statement: >-
      Concurrent state writers resolve an insertion collision on one shared row, without thereby serializing
      participant execution or protecting the entire transition.
    kind: invariant
    enforced_at:
      - service
      - database
    must_prove: false
    provenance: observed
    source: >-
      services-platform:modules/licensing/services/persistence/tenant-applications.ts:setTenantApplicationState
    origin: none
  - id: BR-CAP-PFM-OPS-015-09
    proved_by: [ATS-PFM-OPS-001-17, ATS-PFM-OPS-015-08, ATS-PFM-OPS-015-12, ATS-PFM-OPS-015-15]
    statement: >-
      Workspace purge includes its licence overrides and application states in the licensing participant’s
      declared resources.
    kind: lifecycle
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: observed
    source: 'services-platform:modules/licensing/services/maintenance/tenant-participant.ts:licensingParticipant'
    origin: none
  - id: BR-CAP-PFM-OPS-015-10
    proved_by: []
    statement: >-
      Operational services check their starting state before the writer obtains its row lock, allowing a
      concurrent action to overwrite a newer state decision.
    kind: invariant
    enforced_at:
      - service
    must_prove: true
    provenance: observed
    source: >-
      services-platform:modules/licensing/services/enablement/provision-tenant-application.ts:suspendTenantApplication;
      services-platform:modules/licensing/services/persistence/tenant-applications.ts:setTenantApplicationState
    origin: none
scenarios:
  - id: SC-CAP-PFM-OPS-015-01
    given: An application participant is unable to finish workspace preparation.
    when: Preparation runs and is attempted again after the participant is repaired.
    then: The failed attempt retains an explanation and a successful subsequent attempt records enabled.
    provenance: inferred
    source: >-
      services-platform:modules/licensing/tests/integration/services/enablement/provision-tenant-application.integration.spec.js#succeeds
      when it is retried after the participants would run, which is the enabled path of the same call
    note: >-
      This illustrative example combines behavior established by the cited test and the capability’s
      implementation evidence; it is not an independently bound end-to-end proof.
  - id: SC-CAP-PFM-OPS-015-02
    given: A licensed application is operationally enabled.
    when: Staff suspend it with a reason and later resume it.
    then: >-
      Operational standing changes without deleting data, with audit attempts and cache invalidation following
      the staff actions.
    provenance: inferred
    source: 'services-platform:modules/licensing/tests/e2e/licensing.e2e.spec.js#resumes a suspended application'
    note: >-
      This illustrative example combines behavior established by the cited test and the capability’s
      implementation evidence; it is not an independently bound end-to-end proof.
edge_cases: []
constraints:
  - Application preparation runs synchronously and relies on lifecycle participants’ idempotent seed handling.
depends_on: []
related:
  - CAP-PFM-OPS-011
  - CAP-PFM-OPS-014
  - CAP-PFM-SEC-003
  - CAP-PFM-SEC-004
journeys:
  - JNY-PFM-OPS-004
open_questions: []
evidence:
  - >-
    services-platform at ad3f6a6: modules/licensing/services/enablement/provision-tenant-application.ts,
    grant-licence-override.ts:recordTenantApplicationEvent, services/persistence/tenant-applications.ts,
    services/maintenance/tenant-participant.ts, catalog/application-participants.ts,
    db/tenant-applications.table.ts, aws/api/licensing.routes.ts; provision-tenant-application,
    tenant-applications and table integration suites; licensing e2e ("moving an application between
    operational states"); docs/licensing.md §3, §6.
  - 'services-platform at ad3f6a6, tables named by this capability: tenant-applications.table.ts.'
  - >-
    Operations this capability covers: suspendTenantApplication, resumeTenantApplication,
    retryTenantApplicationProvisioning.
  - >-
    Examination: proposed acceptance matrices retain candidate test references; incomplete proof is recorded
    by FND-PFM-OPS-028.
controls: [TC-AVL-001, TC-AVL-004, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-AZ-005, TC-AZ-006, TC-CHG-001, TC-CHG-002, TC-CHG-003, TC-CHG-004, TC-CHG-005, TC-CHG-006, TC-DAT-001, TC-DAT-003, TC-DAT-004, TC-IAM-001, TC-IAM-003, TC-IAM-006, TC-LOG-001, TC-LOG-002, TC-LOG-003, TC-LOG-004, TC-LOG-005, TC-MON-001, 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-VEN-001, TC-VEN-002, TC-VEN-003]
exercised_by: [FAS-PFM-OPS-04-01, FAS-PFM-OPS-04-02, FAS-PFM-OPS-04-03, FAS-PFM-OPS-04-04, FAS-PFM-OPS-04-05]
suites: [TST-PFM-OPS-081, TST-PFM-OPS-087, TST-PFM-OPS-104]
---

# Prepare and operate workspace applications

## Purpose

Establish application readiness and support deliberate suspension, recovery and resumption.

## How It Works

An application is prepared by recording provisioning and invoking its declared workspace participants. Successful preparation records enabled; participant failure records a bounded explanation and leaves the commercial decision intact. Staff recover a failed preparation through retry. Suspension and resumption change operational standing without discarding application data. Services validate the starting state before asking the persistence writer to lock and change the row. That split permits races between concurrent state changes. Completed staff actions request a flush and then attempt security-history insertion, so later failures do not undo the committed state. Activation and release backfill supply missing always-available states without overriding an existing suspension.

## Relationships

Licence decisions feed availability alongside operational state; security applies the resulting access decision and the console explains it.
