---
id: ATS-PFM-TNL-003
scope: CAP-PFM-TNL-003
product_area: platform
module: tenant-lifecycle
revision: 1
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-003-01
    title: Snapshots distinguish authorized and absent reads
    level: api
    proves:
      - BR-CAP-PFM-TNL-003-01
    preconditions: Fixtures include a requested workspace and one without a provisioning job.
    steps: 'Read as staff and customer administrator, then inspect the no-job fixture.'
    expected: Staff obtain named steps; customer authority is refused and the no-job read returns not found.
    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/e2e/tenant-provisioning.e2e.spec.js#shows every step
        completed, and names each one for the person reading it
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-provisioning.e2e.spec.js#may not watch the
        provisioning of their own tenant
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-provisioning.e2e.spec.js#answers 404 for a tenant
        that was never provisioned by a request
      - TST-PFM-TNL-056
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/e2e/tenant-provisioning.e2e.spec.js#shows every step completed,
      and names each one for the person reading it
    category: permission
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/e2e/tenant-provisioning.e2e.spec.js#shows every step
        completed, and names each one for the person reading it
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/e2e/tenant-provisioning.e2e.spec.js#shows every step
        completed, and names each one for the person reading it
    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-003-02
    title: Failed construction retains partial resources
    level: api
    proves:
      - BR-CAP-PFM-TNL-003-02
    preconditions: A participant refuses its construction step.
    steps: Run the job and inspect its workspace and snapshot.
    expected: The workspace remains provisioning failed with the recorded refusal summary.
    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 saying
        its provisioning failed, which is what makes it retryable
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-provisioning.e2e.spec.js#says so in the snapshot
        too, with the failure summary the task refused with
      - TST-PFM-TNL-056
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/e2e/tenant-provisioning.e2e.spec.js#leaves the tenant saying its
      provisioning failed, which is what makes it retryable
    category: failure
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/e2e/tenant-provisioning.e2e.spec.js#leaves the tenant saying
        its provisioning failed, which is what makes it retryable
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/e2e/tenant-provisioning.e2e.spec.js#leaves the tenant saying
        its provisioning failed, which is what makes it retryable
    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-003-03
    title: Recovery is limited to failed builds
    level: api
    proves:
      - BR-CAP-PFM-TNL-003-03
    preconditions: One build failed and another succeeded.
    steps: Request retry for each workspace.
    expected: The failed build gets a new attempt and can open; the successful build rejects retry.
    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/e2e/tenant-provisioning.e2e.spec.js#answers 200 and a new job
        to the retry
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-provisioning.e2e.spec.js#leaves the tenant usable
        after the retry
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-provisioning.e2e.spec.js#refuses to provision a
        tenant again whose provisioning did not fail
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-provisioning.e2e.spec.js#may not provision their
        own tenant again
      - TST-PFM-TNL-056
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/e2e/tenant-provisioning.e2e.spec.js#answers 200 and a new job to
      the retry
    category: transition
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/e2e/tenant-provisioning.e2e.spec.js#answers 200 and a new job
        to the retry
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/e2e/tenant-provisioning.e2e.spec.js#answers 200 and a new job
        to the retry
    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-003-04
    title: Outcome handling avoids normal replay
    level: api
    proves:
      - BR-CAP-PFM-TNL-003-04
    preconditions: Success and failure fixtures include requester notices.
    steps: Repeat closing tasks and failure reconciliation.
    expected: The delivered fixture notice is retained without another send.
    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/provisioning-notices.integration.spec.js#sends
        the requester one message
      - >-
        services-platform:modules/tenants/tests/integration/services/provisioning/provisioning-notices.integration.spec.js#sends
        nothing a second time when the activate task runs again
      - >-
        services-platform:modules/tenants/tests/integration/services/provisioning/provisioning-notices.integration.spec.js#repeats
        the failure summary the job recorded, so the requester reads why
      - >-
        services-platform:modules/tenants/tests/integration/services/provisioning/provisioning-notices.integration.spec.js#sends
        nothing more when the reconciler applies the same consequence afterwards
      - TST-PFM-TNL-083
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/provisioning/provisioning-notices.integration.spec.js#sends
      the requester one message
    category: edge
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/provisioning/provisioning-notices.integration.spec.js#sends
        the requester one message
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/provisioning/provisioning-notices.integration.spec.js#sends
        the requester one message
    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-003-05
    title: Alerts accompany requester mail
    level: api
    proves:
      - BR-CAP-PFM-TNL-003-06
    preconditions: A successful build has an operations-channel fixture.
    steps: Inspect the alert and captured requester message.
    expected: Both channels identify the workspace and job outcome.
    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-alerts.e2e.spec.js#posts “Tenant
        ready” to the operations channel, with the message ts as the delivery’s provider reference
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-provisioning-alerts.e2e.spec.js#tells the requester
        by e-mail as well: the alert is beside the notice, not instead of it
      - TST-PFM-TNL-055
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/e2e/tenant-provisioning-alerts.e2e.spec.js#posts “Tenant ready”
      to the operations channel, with the message ts as the delivery’s provider reference
    category: rule
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/e2e/tenant-provisioning-alerts.e2e.spec.js#posts “Tenant
        ready” to the operations channel, with the message ts as the delivery’s provider reference
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/e2e/tenant-provisioning-alerts.e2e.spec.js#posts “Tenant
        ready” to the operations channel, with the message ts as the delivery’s provider reference
    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-003-06
    title: Stranded repair is repeatable
    level: api
    proves:
      - BR-CAP-PFM-TNL-003-07
    preconditions: One workspace has a settled unstarted job and another a running job.
    steps: Run repair twice.
    expected: >-
      Only the stranded workspace becomes failed; its notice is handled once and the running workspace remains
      intact.
    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/repair-stranded-provisioning.integration.spec.js#moves
        the stranded tenant to provisioning_failed, which makes it retryable and deletable again
      - >-
        services-platform:modules/tenants/tests/integration/services/provisioning/repair-stranded-provisioning.integration.spec.js#tells
        the staff member who asked for the tenant once, with the job’s own summary
      - >-
        services-platform:modules/tenants/tests/integration/services/provisioning/repair-stranded-provisioning.integration.spec.js#leaves
        a tenant whose provisioning is still running provisioning
      - >-
        services-platform:modules/tenants/tests/integration/services/provisioning/repair-stranded-provisioning.integration.spec.js#changes
        nothing about the repaired tenant on a second pass
      - >-
        services-platform:modules/tenants/tests/integration/lifecycle/reconciled-job-failure.integration.spec.js#moves
        the tenant to provisioning_failed, which is what makes it retryable and deletable again
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/provisioning/repair-stranded-provisioning.integration.spec.js#moves
      the stranded tenant to provisioning_failed, which makes it retryable and deletable again
    category: invariant
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/provisioning/repair-stranded-provisioning.integration.spec.js#moves
        the stranded tenant to provisioning_failed, which makes it retryable and deletable again
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/provisioning/repair-stranded-provisioning.integration.spec.js#moves
        the stranded tenant to provisioning_failed, which makes it retryable and deletable again
    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-003-07
    title: Ready mail links the requester to progress
    level: api
    proves:
      - AS-JNY-PFM-TNL-001-03
    preconditions: The successful provisioning journey captures requester mail.
    steps: Inspect the captured message and repeat outcome handling.
    expected: A single handled ready message includes the job link.
    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/provisioning-notices.integration.spec.js#sends
        the requester one message
      - >-
        services-platform:modules/tenants/tests/integration/services/provisioning/provisioning-notices.integration.spec.js#links
        to the job’s own page in Rhythm HQ, so the requester can read the steps
      - TST-PFM-TNL-083
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/provisioning/provisioning-notices.integration.spec.js#sends
      the requester one message
    category: rule
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/provisioning/provisioning-notices.integration.spec.js#sends
        the requester one message
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/provisioning/provisioning-notices.integration.spec.js#sends
        the requester one message
    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-003-08
    title: Failure explanation supports staff recovery
    level: api
    proves:
      - AS-JNY-PFM-TNL-002-01
    preconditions: The recovery journey has a refused build.
    steps: Inspect its retained workspace and job snapshot.
    expected: The failed workspace and explanation remain available without removal of completed construction.
    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 saying
        its provisioning failed, which is what makes it retryable
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-provisioning.e2e.spec.js#says so in the snapshot
        too, with the failure summary the task refused with
      - TST-PFM-TNL-056
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/e2e/tenant-provisioning.e2e.spec.js#leaves the tenant saying its
      provisioning failed, which is what makes it retryable
    category: rule
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/e2e/tenant-provisioning.e2e.spec.js#leaves the tenant saying
        its provisioning failed, which is what makes it retryable
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/e2e/tenant-provisioning.e2e.spec.js#leaves the tenant saying
        its provisioning failed, which is what makes it retryable
    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-003-09
    title: Recovery opens without duplicate construction
    level: api
    proves:
      - AS-JNY-PFM-TNL-002-02
    preconditions: The recovery journey retains completed steps from its failed attempt.
    steps: Run retry through activation.
    expected: The workspace opens and already completed participant work is not repeated.
    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/e2e/tenant-provisioning.e2e.spec.js#leaves the tenant usable
        after the retry
    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: interaction
    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: >-
      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-003-10
    title: An unwanted failed build enters deliberate deletion
    category: interaction
    level: api
    proves:
      - BR-CAP-PFM-TNL-003-08
    interacts_with:
      - CAP-PFM-TNL-013
      - CAP-PFM-TNL-001
    preconditions: A retained failed build contains completed participant work and is eligible for staff deletion.
    steps: 'Inspect its failed snapshot, request deletion and read the resulting request and workspace standing.'
    expected: >-
      The failed build remains available for review until deletion is requested; the request creates a
      separate decision and the shorter unopened-workspace wait.
    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-003-follow-a-provisioning-retry-it-and-hear-how-it-ended.md;
      rhythm-v2-docs:specs/platform/tenant-lifecycle/planning/capabilities/CAP-PFM-TNL-013-ask-for-a-workspace-to-be-deleted-after-a-waiting-period.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-003-follow-a-provisioning-retry-it-and-hear-how-it-ended.md;
        rhythm-v2-docs:specs/platform/tenant-lifecycle/planning/capabilities/CAP-PFM-TNL-013-ask-for-a-workspace-to-be-deleted-after-a-waiting-period.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-003-follow-a-provisioning-retry-it-and-hear-how-it-ended.md;
        rhythm-v2-docs:specs/platform/tenant-lifecycle/planning/capabilities/CAP-PFM-TNL-013-ask-for-a-workspace-to-be-deleted-after-a-waiting-period.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/e2e/tenant-provisioning.e2e.spec.js#shows every step completed,
    and names each one for the person reading it
  - >-
    services-platform:modules/tenants/tests/e2e/tenant-provisioning.e2e.spec.js#leaves the tenant saying its
    provisioning failed, which is what makes it retryable
  - >-
    services-platform:modules/tenants/tests/e2e/tenant-provisioning.e2e.spec.js#answers 200 and a new job to
    the retry
  - >-
    services-platform:modules/tenants/tests/integration/services/provisioning/provisioning-notices.integration.spec.js#sends
    the requester one message
  - >-
    services-platform:modules/tenants/tests/e2e/tenant-provisioning-alerts.e2e.spec.js#posts “Tenant ready” to
    the operations channel, with the message ts as the delivery’s provider reference
  - >-
    services-platform:modules/tenants/tests/integration/services/provisioning/repair-stranded-provisioning.integration.spec.js#moves
    the stranded tenant to provisioning_failed, which makes it retryable and deletable again
  - >-
    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
  - >-
    rhythm-v2-docs:specs/platform/tenant-lifecycle/planning/capabilities/CAP-PFM-TNL-003-follow-a-provisioning-retry-it-and-hear-how-it-ended.md;
    rhythm-v2-docs:specs/platform/tenant-lifecycle/planning/capabilities/CAP-PFM-TNL-013-ask-for-a-workspace-to-be-deleted-after-a-waiting-period.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: covered
  transition: 'gap: FND-PFM-TNL-068'
  validation: 'gap: FND-PFM-TNL-068'
  permission: covered
  edge: covered
  failure: covered
  boundary: 'gap: FND-PFM-TNL-068'
  concurrency: 'gap: FND-PFM-TNL-068'
  invariant: covered
  interaction: covered
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-068'
    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-068'
    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-068'
    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-068'
    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-068'
    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-068'
    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-068'
    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-068'
    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-068'
    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-068'
    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-068'
    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-068'
    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-068'
    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-068'
    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-068'
    provenance: observed
    source: >-
      services-platform:modules/tenants/services/provisioning/provision-tenant-workflow.ts:tenantProvisioningWorkflow
permission_obligations:
  - key: hq.tenants.read
    where_checked: api
    scenario_examples:
      - ATS-PFM-TNL-003-01
    coverage: 'gap: FND-PFM-TNL-068'
    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-003-follow-a-provisioning-retry-it-and-hear-how-it-ended.md
  - key: hq.tenants.provision
    where_checked: api
    scenario_examples:
      - ATS-PFM-TNL-003-01
    coverage: 'gap: FND-PFM-TNL-068'
    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-003-follow-a-provisioning-retry-it-and-hear-how-it-ended.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.
---
# Understand and recover a workspace build: 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-003-01` | `ATS-PFM-TNL-003-01` |
| `BR-CAP-PFM-TNL-003-02` | `ATS-PFM-TNL-003-02` |
| `BR-CAP-PFM-TNL-003-03` | `ATS-PFM-TNL-003-03` |
| `BR-CAP-PFM-TNL-003-04` | `ATS-PFM-TNL-003-04` |
| `BR-CAP-PFM-TNL-003-06` | `ATS-PFM-TNL-003-05` |
| `BR-CAP-PFM-TNL-003-07` | `ATS-PFM-TNL-003-06` |

## Interactions With Related Capabilities

An unwanted failed build enters deliberate deletion. 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-003-10` (proposed) |
| `CAP-PFM-TNL-013` | `ATS-PFM-TNL-003-10` (proposed) |
