---
id: ATS-PFM-TNL-002
scope: CAP-PFM-TNL-002
product_area: platform
module: tenant-lifecycle
revision: 3
status: proposed
approved_by: null
approved_at: null
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
  services-commerce: c8b66a98e2490617aec38ba5c8165dd9bd0a8f9b
  services-committees: 36129c24daeaadcdb339218c38cdeaff9861359d
  services-membership: 5994c270e8a37a30f848e99ba5b5ee6b87c08893
  services-submissions: 64236c19be89579ef5897aad7de3925ed3ce03bf
  services-websites: 5fc6823c69d5e6f208c21dba8c0eb3132f8bdc4c
  services-marketing: d071a159fe9782bb71ff246d5c67d5bbfe07fbfa
  rhythm-v2-docs: d318a948692343e2f0a7ecc2e11c50db179a8c95
scenarios:
  - id: ATS-PFM-TNL-002-01
    title: Dependencies determine construction order
    level: unit
    proves:
      - BR-CAP-PFM-TNL-002-01
    preconditions: Participant declarations include their prerequisites.
    steps: Derive the plan and step catalog.
    expected: The workspace comes first and participants appear once before readiness and activation.
    negative: false
    data_needs: >-
      Use the run-owned records and caller contexts created by the cited tests; use their provider and clock
      seams only where declared.
    bound_to:
      - >-
        services-platform:modules/tenants/tests/unit/services/provisioning/provision-tenant-workflow.spec.js#runs
        the tenant row before anything that depends on it
      - >-
        services-platform:modules/tenants/tests/unit/services/provisioning/provision-tenant-workflow.spec.js#names
        every planned participant exactly once
      - >-
        services-platform:modules/tenants/tests/unit/services/provisioning/provision-tenant-workflow.spec.js#has
        one step per planned participant, then the readiness check and the activation
      - >-
        services-platform:modules/tenants/tests/integration/services/provisioning/provision-tenant.integration.spec.js#provisions
        all seven of CRM’s participants, the tasks, activities and duplicates participants after the entities
        they depend on
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/unit/services/provisioning/provision-tenant-workflow.spec.js#runs
      the tenant row before anything that depends on it
    category: rule
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/unit/services/provisioning/provision-tenant-workflow.spec.js#runs
        the tenant row before anything that depends on it
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/unit/services/provisioning/provision-tenant-workflow.spec.js#runs
        the tenant row before anything that depends on it
    binding_note: >-
      The original test-title references contribute separate assertions from several files. No suite receives
      an implements link for the complete combined scenario; a full executable mapping remains
      FND-PFM-TNL-084.
    binding_gap: FND-PFM-TNL-084
  - id: ATS-PFM-TNL-002-02
    title: Live declaration drift stops execution
    level: api
    proves:
      - BR-CAP-PFM-TNL-002-02
    preconditions: Live descriptions differ from the static participant order.
    steps: Start the lifecycle plan.
    expected: The refusal reports planned and current participants before their work runs.
    negative: true
    data_needs: >-
      Use the run-owned records and caller contexts created by the cited tests; use their provider and clock
      seams only where declared.
    bound_to:
      - >-
        services-platform:modules/tenants/tests/unit/services/provisioning/provision-tenant-workflow.spec.js#refuses
        a run whose participants are not the ones it was planned for, naming both plans
      - >-
        services-platform:modules/tenants/tests/unit/services/lifecycle/remote-participants.spec.js#plans the
        live manifests, so normalised, in exactly the order the static copies plan (what the publish step
        compares)
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/tenant-purge.integration.spec.js#refuses
        the purge as planned for other participants rather than skipping one
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/unit/services/provisioning/provision-tenant-workflow.spec.js#refuses
      a run whose participants are not the ones it was planned for, naming both plans
    category: validation
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/unit/services/provisioning/provision-tenant-workflow.spec.js#refuses
        a run whose participants are not the ones it was planned for, naming both plans
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/unit/services/provisioning/provision-tenant-workflow.spec.js#refuses
        a run whose participants are not the ones it was planned for, naming both plans
    binding_note: >-
      The original test-title references contribute separate assertions from several files. No suite receives
      an implements link for the complete combined scenario; a full executable mapping remains
      FND-PFM-TNL-084.
    binding_gap: FND-PFM-TNL-084
  - id: ATS-PFM-TNL-002-03
    title: Enablement controls remote construction
    level: api
    proves:
      - BR-CAP-PFM-TNL-002-03
    preconditions: Fixtures include enabled remote participants and a disabled application.
    steps: Provision under each registry configuration.
    expected: Enabled participants are invoked and the disabled application receives no description or work call.
    negative: false
    data_needs: >-
      Use the run-owned records and caller contexts created by the cited tests; use their provider and clock
      seams only where declared.
    bound_to:
      - >-
        services-platform:modules/tenants/tests/integration/services/provisioning/provision-tenant.integration.spec.js#asks
        the other macroservice to provision each of its participants, for the tenant being provisioned
      - >-
        services-platform:modules/tenants/tests/integration/services/provisioning/provision-tenant.integration.spec.js#neither
        describes nor asks Accounting while a registry that switches Accounting’s participants off is in force
      - TST-PFM-TNL-082
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/provisioning/provision-tenant.integration.spec.js#asks
      the other macroservice to provision each of its participants, for the tenant being provisioned
    category: interaction
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/provisioning/provision-tenant.integration.spec.js#asks
        the other macroservice to provision each of its participants, for the tenant being provisioned
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/provisioning/provision-tenant.integration.spec.js#asks
        the other macroservice to provision each of its participants, for the tenant being provisioned
    binding_note: >-
      All cited checks for this scenario occur in the registered file. The link establishes inspected
      executable source rather than a passing run.
  - id: ATS-PFM-TNL-002-04
    title: Readiness retains a missing-resource failure
    level: api
    proves:
      - BR-CAP-PFM-TNL-002-04
    preconditions: A participant cannot account for a required resource.
    steps: Run construction through readiness.
    expected: The missing resource is reported and the workspace stays closed.
    negative: true
    data_needs: >-
      Use the run-owned records and caller contexts created by the cited tests; use their provider and clock
      seams only where declared.
    bound_to:
      - >-
        services-platform:modules/tenants/tests/integration/services/provisioning/provision-tenant.integration.spec.js#asks
        every participant to confirm what it made before the tenant is opened
      - >-
        services-platform:modules/tenants/tests/integration/services/provisioning/provision-tenant.integration.spec.js#leaves
        the tenant where an operator can see it, and does not open it
      - TST-PFM-TNL-082
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/provisioning/provision-tenant.integration.spec.js#asks
      every participant to confirm what it made before the tenant is opened
    category: failure
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/provisioning/provision-tenant.integration.spec.js#asks
        every participant to confirm what it made before the tenant is opened
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/provisioning/provision-tenant.integration.spec.js#asks
        every participant to confirm what it made before the tenant is opened
    binding_note: >-
      All cited checks for this scenario occur in the registered file. The link establishes inspected
      executable source rather than a passing run.
  - id: ATS-PFM-TNL-002-05
    title: Activation retains its first opening
    level: api
    proves:
      - BR-CAP-PFM-TNL-002-05
    preconditions: All construction participants report readiness.
    steps: Activate the workspace and repeat activation.
    expected: Active lifecycle uses the requested mode and the recorded activation time remains stable.
    negative: false
    data_needs: >-
      Use the run-owned records and caller contexts created by the cited tests; use their provider and clock
      seams only where declared.
    bound_to:
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-provisioning.e2e.spec.js#leaves the tenant usable
        once the job has run
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-provisioning.e2e.spec.js#records when the tenant
        became usable
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-provisioning.e2e.spec.js#shows one step per
        participant, then the readiness check and the activation
      - TST-PFM-TNL-056
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/e2e/tenant-provisioning.e2e.spec.js#leaves the tenant usable
      once the job has run
    category: transition
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/e2e/tenant-provisioning.e2e.spec.js#leaves the tenant usable
        once the job has run
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/e2e/tenant-provisioning.e2e.spec.js#leaves the tenant usable
        once the job has run
    binding_note: >-
      All cited checks for this scenario occur in the registered file. The link establishes inspected
      executable source rather than a passing run.
  - id: ATS-PFM-TNL-002-06
    title: Retry omits completed construction
    level: api
    proves:
      - BR-CAP-PFM-TNL-002-06
    preconditions: An earlier attempt stopped after partial completion.
    steps: Run a replacement attempt.
    expected: Outstanding resources are supplied without repeating completed participant work.
    negative: false
    data_needs: >-
      Use the run-owned records and caller contexts created by the cited tests; use their provider and clock
      seams only where declared.
    bound_to:
      - >-
        services-platform:modules/tenants/tests/integration/services/provisioning/provision-tenant.integration.spec.js#does
        the missing work and not the finished work when it is provisioned again
      - >-
        services-platform:modules/tenants/tests/integration/services/provisioning/provision-tenant.integration.spec.js#does
        not repeat work the other macroservice completed before it lost the answer
      - TST-PFM-TNL-082
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/provisioning/provision-tenant.integration.spec.js#does
      the missing work and not the finished work when it is provisioned again
    category: invariant
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/provisioning/provision-tenant.integration.spec.js#does
        the missing work and not the finished work when it is provisioned again
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/provisioning/provision-tenant.integration.spec.js#does
        the missing work and not the finished work when it is provisioned again
    binding_note: >-
      All cited checks for this scenario occur in the registered file. The link establishes inspected
      executable source rather than a passing run.
  - id: ATS-PFM-TNL-002-07
    title: Construction progress satisfies its journey assertion
    level: api
    proves:
      - AS-JNY-PFM-TNL-001-02
    preconditions: The provisioning journey’s fixture has a successful build.
    steps: Inspect the resulting build snapshot.
    expected: 'Participant, readiness and activation steps are present and completed.'
    negative: false
    data_needs: >-
      Use the run-owned records and caller contexts created by the cited tests; use their provider and clock
      seams only where declared.
    bound_to:
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-provisioning.e2e.spec.js#shows one step per
        participant, then the readiness check and the activation
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-provisioning.e2e.spec.js#says the provisioning
        succeeded
      - TST-PFM-TNL-056
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/e2e/tenant-provisioning.e2e.spec.js#shows one step per
      participant, then the readiness check and the activation
    category: rule
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/e2e/tenant-provisioning.e2e.spec.js#shows one step per
        participant, then the readiness check and the activation
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/e2e/tenant-provisioning.e2e.spec.js#shows one step per
        participant, then the readiness check and the activation
    binding_note: >-
      All cited checks for this scenario occur in the registered file. The link establishes inspected
      executable source rather than a passing run.
  - id: ATS-PFM-TNL-002-08
    title: Activation and repeated activation preserve lifecycle authority
    category: interaction
    level: api
    proves:
      - BR-CAP-PFM-TNL-002-05
    interacts_with:
      - CAP-PFM-TNL-006
      - CAP-PFM-TNL-001
    preconditions: The participant plan is ready and the workspace has no first opening time.
    steps: >-
      Complete construction, read lifecycle facts, repeat activation and attempt an ordinary client lifecycle
      edit.
    expected: Opening records one activation time; repetition and the client edit cannot replace it.
    negative: true
    data_needs: >-
      Create a separate run-owned workspace for each decision branch and an unaffected comparison workspace.
      Use a controlled clock, paused task or injected fault at the boundary named in the scenario.
    bound_to: []
    provenance: proposed
    source: >-
      rhythm-v2-docs:specs/platform/tenant-lifecycle/planning/capabilities/CAP-PFM-TNL-002-open-a-new-workspace-only-when-every-application-reports-it.md;
      rhythm-v2-docs:specs/platform/tenant-lifecycle/planning/capabilities/CAP-PFM-TNL-006-keep-every-workspace-s-lifecycle-state-truthful.md;
      rhythm-v2-docs:specs/platform/tenant-lifecycle/planning/capabilities/CAP-PFM-TNL-001-ask-for-a-new-workspace-and-have-every-application-build-it.md
    action_evidence:
      provenance: proposed
      source: >-
        rhythm-v2-docs:specs/platform/tenant-lifecycle/planning/capabilities/CAP-PFM-TNL-002-open-a-new-workspace-only-when-every-application-reports-it.md;
        rhythm-v2-docs:specs/platform/tenant-lifecycle/planning/capabilities/CAP-PFM-TNL-006-keep-every-workspace-s-lifecycle-state-truthful.md;
        rhythm-v2-docs:specs/platform/tenant-lifecycle/planning/capabilities/CAP-PFM-TNL-001-ask-for-a-new-workspace-and-have-every-application-build-it.md
    assertion_evidence:
      provenance: proposed
      source: >-
        rhythm-v2-docs:specs/platform/tenant-lifecycle/planning/capabilities/CAP-PFM-TNL-002-open-a-new-workspace-only-when-every-application-reports-it.md;
        rhythm-v2-docs:specs/platform/tenant-lifecycle/planning/capabilities/CAP-PFM-TNL-006-keep-every-workspace-s-lifecycle-state-truthful.md;
        rhythm-v2-docs:specs/platform/tenant-lifecycle/planning/capabilities/CAP-PFM-TNL-001-ask-for-a-new-workspace-and-have-every-application-build-it.md
evidence:
  - >-
    services-platform:modules/tenants/tests/unit/services/provisioning/provision-tenant-workflow.spec.js#runs
    the tenant row before anything that depends on it
  - >-
    services-platform:modules/tenants/tests/unit/services/provisioning/provision-tenant-workflow.spec.js#refuses
    a run whose participants are not the ones it was planned for, naming both plans
  - >-
    services-platform:modules/tenants/tests/integration/services/provisioning/provision-tenant.integration.spec.js#asks
    the other macroservice to provision each of its participants, for the tenant being provisioned
  - >-
    services-platform:modules/tenants/tests/integration/services/provisioning/provision-tenant.integration.spec.js#asks
    every participant to confirm what it made before the tenant is opened
  - >-
    services-platform:modules/tenants/tests/e2e/tenant-provisioning.e2e.spec.js#leaves the tenant usable once
    the job has run
  - >-
    services-platform:modules/tenants/tests/integration/services/provisioning/provision-tenant.integration.spec.js#does
    the missing work and not the finished work when it is provisioned again
  - >-
    services-platform:modules/tenants/tests/e2e/tenant-provisioning.e2e.spec.js#shows one step per
    participant, then the readiness check and the activation
  - >-
    rhythm-v2-docs:specs/platform/tenant-lifecycle/planning/capabilities/CAP-PFM-TNL-002-open-a-new-workspace-only-when-every-application-reports-it.md;
    rhythm-v2-docs:specs/platform/tenant-lifecycle/planning/capabilities/CAP-PFM-TNL-006-keep-every-workspace-s-lifecycle-state-truthful.md;
    rhythm-v2-docs:specs/platform/tenant-lifecycle/planning/capabilities/CAP-PFM-TNL-001-ask-for-a-new-workspace-and-have-every-application-build-it.md
coverage:
  rule: 'gap: FND-PFM-TNL-067'
  transition: 'gap: FND-PFM-TNL-067'
  validation: covered
  permission: 'gap: FND-PFM-TNL-067'
  edge: 'gap: FND-PFM-TNL-067'
  failure: covered
  boundary: 'gap: FND-PFM-TNL-067'
  concurrency: 'gap: FND-PFM-TNL-067'
  invariant: covered
  interaction: 'gap: FND-PFM-TNL-067'
coverage_notes:
  transition: >-
    The listed scenarios sample lifecycle changes. Complete transition, guard and side-effect proof is still
    owed for the state models named in the coverage finding.
  interaction: >-
    The added interaction is proposed. Related capabilities not included in that scenario remain named in the
    coverage finding.
transition_obligations:
  - state_model: STATE-PFM-TNL-001
    transition_n: 1
    coverage: 'gap: FND-PFM-TNL-067'
    provenance: observed
    source: 'services-platform:modules/tenants/services/persistence/tenants.ts:activateProvisionedTenant'
  - state_model: STATE-PFM-TNL-001
    transition_n: 2
    coverage: 'gap: FND-PFM-TNL-067'
    provenance: observed
    source: >-
      services-platform:modules/tenants/services/provisioning/provision-tenant-failure.ts:applyTenantProvisioningFailure
  - state_model: STATE-PFM-TNL-001
    transition_n: 3
    coverage: 'gap: FND-PFM-TNL-067'
    provenance: observed
    source: >-
      services-platform:modules/tenants/services/provisioning/submit-tenant-provisioning.ts:retryTenantProvisioning
  - state_model: STATE-PFM-TNL-001
    transition_n: 4
    coverage: 'gap: FND-PFM-TNL-067'
    provenance: observed
    source: 'services-platform:modules/tenants/services/deletion/request-deletion.ts:requestTenantDeletion'
  - state_model: STATE-PFM-TNL-001
    transition_n: 5
    coverage: 'gap: FND-PFM-TNL-067'
    provenance: observed
    source: 'services-platform:modules/tenants/services/persistence/tenants.ts:enterTenantLoading'
  - state_model: STATE-PFM-TNL-001
    transition_n: 6
    coverage: 'gap: FND-PFM-TNL-067'
    provenance: observed
    source: 'services-platform:modules/tenants/services/deletion/request-deletion.ts:requestTenantDeletion'
  - state_model: STATE-PFM-TNL-001
    transition_n: 7
    coverage: 'gap: FND-PFM-TNL-067'
    provenance: observed
    source: 'services-platform:modules/tenants/services/persistence/tenants.ts:activateLoadedTenant'
  - state_model: STATE-PFM-TNL-001
    transition_n: 8
    coverage: 'gap: FND-PFM-TNL-067'
    provenance: observed
    source: 'services-platform:modules/tenants/services/lifecycle/lifecycle-transitions.ts:SUCCESSORS'
  - state_model: STATE-PFM-TNL-001
    transition_n: 9
    coverage: 'gap: FND-PFM-TNL-067'
    provenance: observed
    source: 'services-platform:modules/tenants/services/deletion/deletion-holds.ts:cancelTenantDeletion'
  - state_model: STATE-PFM-TNL-001
    transition_n: 10
    coverage: 'gap: FND-PFM-TNL-067'
    provenance: observed
    source: 'services-platform:modules/tenants/services/deletion/begin-destruction.ts:beginTenantDestruction'
  - state_model: STATE-PFM-TNL-001
    transition_n: 11
    coverage: 'gap: FND-PFM-TNL-067'
    provenance: observed
    source: 'services-platform:modules/tenants/services/persistence/tenants.ts:forceTenantDeletingAfterRestore'
  - state_model: STATE-PFM-TNL-002
    transition_n: 1
    coverage: 'gap: FND-PFM-TNL-067'
    provenance: observed
    source: >-
      services-platform:modules/tenants/services/provisioning/provision-tenant-operations.ts:tenantProvisioningOperations
  - state_model: STATE-PFM-TNL-002
    transition_n: 2
    coverage: 'gap: FND-PFM-TNL-067'
    provenance: documented
    source: 'services-platform:docs/jobs.md#§2 step 8'
  - state_model: STATE-PFM-TNL-002
    transition_n: 3
    coverage: 'gap: FND-PFM-TNL-067'
    provenance: observed
    source: >-
      services-platform:modules/tenants/services/provisioning/provision-tenant-operations.ts:tenantProvisioningOperations
  - state_model: STATE-PFM-TNL-002
    transition_n: 4
    coverage: 'gap: FND-PFM-TNL-067'
    provenance: observed
    source: >-
      services-platform:modules/tenants/services/provisioning/provision-tenant-workflow.ts:tenantProvisioningWorkflow
permission_obligations:
  - key: hq.tenants.provision
    where_checked: service
    scenario_examples: []
    coverage: 'gap: FND-PFM-TNL-067'
    note: 'Examples do not establish the complete key-by-key grant, revoked-grant and staff-context matrix.'
    provenance: documented
    source: >-
      rhythm-v2-docs:specs/platform/tenant-lifecycle/planning/capabilities/CAP-PFM-TNL-002-open-a-new-workspace-only-when-every-application-reports-it.md
evidence_note: >-
  The test-specific convention lists an Evidence body section, but the corpus checker rejects it. Sources and
  verification limits remain in frontmatter so this artifact conforms without changing the checker.
---
# Open a workspace after its applications are ready: Capability Test Specification

## Coverage

The category map separates defined scenarios from missing proof. A covered category has a scenario; a binding records inspected test assertions and carries no execution result. State-model completeness and untested interactions remain explicit gaps.

| Rule | Proved by |
|---|---|
| `BR-CAP-PFM-TNL-002-01` | `ATS-PFM-TNL-002-01` |
| `BR-CAP-PFM-TNL-002-02` | `ATS-PFM-TNL-002-02` |
| `BR-CAP-PFM-TNL-002-03` | `ATS-PFM-TNL-002-03` |
| `BR-CAP-PFM-TNL-002-04` | `ATS-PFM-TNL-002-04` |
| `BR-CAP-PFM-TNL-002-05` | `ATS-PFM-TNL-002-05`, `ATS-PFM-TNL-002-08` |
| `BR-CAP-PFM-TNL-002-06` | `ATS-PFM-TNL-002-06` |
| `BR-CAP-PFM-TNL-002-08` | No scenario: `FND-PFM-TNL-067` |

## Interactions With Related Capabilities

Activation and repeated activation preserve lifecycle authority. The combined scenario sets up the stated boundary, changes the upstream condition and observes its effect on the dependent outcome. Its steps and assertions are proposed; component tests do not establish this combined execution.

| Related capability | Combined coverage |
|---|---|
| `CAP-PFM-TNL-001` | `ATS-PFM-TNL-002-08` (proposed) |
| `CAP-PFM-TNL-003` | Gap: `FND-PFM-TNL-067` |
| `CAP-PFM-TNL-006` | `ATS-PFM-TNL-002-08` (proposed) |
