---
id: ATS-PFM-TNL-016
scope: CAP-PFM-TNL-016
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-016-01
    title: HTTP catalog exposes no destruction shortcut
    level: api
    proves:
      - BR-CAP-PFM-TNL-016-01
    preconditions: The complete deletion route registry and a scheduled request are available.
    steps: Inspect operations and drive the schedule through eligibility.
    expected: No execute-now or force action appears; the schedule invokes destruction after its guards.
    negative: false
    data_needs: >-
      Create isolated workspace and caller fixtures matching the scenario; supply controlled failure or timing
      inputs only where required.
    bound_to: []
    provenance: proposed
    source: 'services-platform:modules/tenants/aws/api/tenant-deletion-requests.routes.ts'
    category: boundary
    action_evidence:
      provenance: proposed
      source: 'services-platform:modules/tenants/aws/api/tenant-deletion-requests.routes.ts'
    assertion_evidence:
      provenance: proposed
      source: 'services-platform:modules/tenants/aws/api/tenant-deletion-requests.routes.ts'
    binding_note: Bindings record source-level assertions; no execution result is established by this examination.
  - id: ATS-PFM-TNL-016-02
    title: Revalidation waits for changing obstacles
    level: api
    proves:
      - BR-CAP-PFM-TNL-016-02
    preconditions: Eligibility and workspace conditions vary one at a time.
    steps: 'Attempt destruction before and at the date and with held, unnotified, child-bearing or locked fixtures.'
    expected: The valid boundary begins destruction while the obstructed fixtures wait.
    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/deletion/begin-destruction.integration.spec.js#waits
        one millisecond before the date
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#begins
        at the date itself, which is the other side of that millisecond
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#waits
        while the request is held
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#waits
        when the tenant gained a child during the waiting period
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#waits
        when the tenant was locked during the waiting period
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#leaves
        the tenant awaiting deletion through every one of those waits
      - TST-PFM-TNL-061
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#waits
      one millisecond before the date
    category: validation
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#waits
        one millisecond before the date
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#waits
        one millisecond before the date
    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-016-03
    title: Lost requester authority produces a hold
    level: api
    proves:
      - BR-CAP-PFM-TNL-016-03
    preconditions: The requester no longer has deletion permission.
    steps: Attempt destruction at eligibility.
    expected: The request is held with its authority explanation and no purge begins.
    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/deletion/begin-destruction.integration.spec.js#waits
        when the person who asked no longer holds the permission to ask
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#holds
        the request in that case, so a person has to look at it rather than a job retrying forever
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#records
        why it held it
      - TST-PFM-TNL-061
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#waits
      when the person who asked no longer holds the permission to ask
    category: permission
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#waits
        when the person who asked no longer holds the permission to ask
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#waits
        when the person who asked no longer holds the permission to ask
    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-016-04
    title: Terminal schedules end without side effects
    level: api
    proves:
      - BR-CAP-PFM-TNL-016-04
    preconditions: 'Fixtures are cancelled, superseded, missing or have lost their workspace.'
    steps: Ask the schedule to begin destruction.
    expected: Each returns an explained end without mutating the request or workspace.
    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/deletion/begin-destruction.integration.spec.js#ends
        when the request was cancelled while the job slept
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#ends
        when another execution now owns the request, which is what a resume looks like
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#touches
        nothing when it ends: the tenant is still awaiting deletion
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#ends
        when the tenant is already gone
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/tenant-deletion-schedule.integration.spec.js#ends
        quietly, without destroying anything, when the request was cancelled while it slept
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/tenant-deletion-schedule.integration.spec.js#keeps
        waiting, and destroys nothing, while the request is held
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#ends
      when the request was cancelled while the job slept
    category: edge
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#ends
        when the request was cancelled while the job slept
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#ends
        when the request was cancelled while the job slept
    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-016-05
    title: Irreversible state and purge job commit together
    level: api
    proves:
      - BR-CAP-PFM-TNL-016-05
    preconditions: All destruction guards hold.
    steps: Begin destruction and inspect persisted records.
    expected: 'Executing state, time, deleting disabled lifecycle, notice and purge job agree.'
    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/deletion/begin-destruction.integration.spec.js#answers
        that destruction began
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#records
        when destruction began
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#moves
        the tenant to deleting
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#leaves
        the tenant disabled, as the cross-axis rule requires
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#names
        the purge job it submitted in the same transaction, so the point of no return and its destruction
        commit together
      - TST-PFM-TNL-061
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#answers
      that destruction began
    category: transition
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#answers
        that destruction began
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#answers
        that destruction began
    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-016-06
    title: Concurrent cancel has one winner
    level: api
    proves:
      - BR-CAP-PFM-TNL-016-06
    preconditions: Twenty eligible requests support separate connections.
    steps: Race cancellation and destruction on each.
    expected: One decision wins per round and request and workspace states match it.
    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/deletion/begin-destruction.integration.spec.js#lets
        exactly one of the two win, every round
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#leaves
        every request in a state that matches who won
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#leaves
        every tenant in a lifecycle state that matches who won
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#races
        both ways across the rounds, so the suite is not quietly proving one order every time
      - TST-PFM-TNL-061
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#lets
      exactly one of the two win, every round
    category: concurrency
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#lets
        exactly one of the two win, every round
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#lets
        exactly one of the two win, every round
    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-016-07
    title: Watcher recovery preserves the decision
    level: api
    proves:
      - BR-CAP-PFM-TNL-016-07
    preconditions: A request’s watcher has stopped.
    steps: Resume it and immediately attempt another resume.
    expected: >-
      The new watcher references its predecessor and unchanged date; the live replacement refuses another
      resume.
    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-deletion-recovery.e2e.spec.js#answers a new
        schedule job, and names the one it superseded
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-deletion-recovery.e2e.spec.js#leaves the request
        scheduled, and its eligibility exactly where it was: a resume cannot bring a deletion forward
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-deletion-recovery.e2e.spec.js#refuses a second
        resume as 409 while the new schedule job is alive
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-deletion-recovery.e2e.spec.js#may not resume a
        deletion schedule
      - TST-PFM-TNL-051
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/e2e/tenant-deletion-recovery.e2e.spec.js#answers a new schedule
      job, and names the one it superseded
    category: failure
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/e2e/tenant-deletion-recovery.e2e.spec.js#answers a new
        schedule job, and names the one it superseded
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/e2e/tenant-deletion-recovery.e2e.spec.js#answers a new
        schedule job, and names the one it superseded
    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-016-08
    title: Deletion journey respects the preservation boundary
    level: api
    proves:
      - AS-JNY-PFM-TNL-004-03
    preconditions: The deletion journey includes eligible race fixtures.
    steps: Cancel before and after the destruction transition.
    expected: The winning pre-destruction cancellation preserves data and the late cancellation refuses.
    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/deletion/begin-destruction.integration.spec.js#lets
        exactly one of the two win, every round
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#refuses
        a cancel that arrives after the point of no return
      - TST-PFM-TNL-061
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#lets
      exactly one of the two win, every round
    category: interaction
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#lets
        exactly one of the two win, every round
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#lets
        exactly one of the two win, every round
    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-016-09
    title: The winning destruction decision closes preservation routes
    category: interaction
    level: api
    proves:
      - BR-CAP-PFM-TNL-016-05
    interacts_with:
      - CAP-PFM-TNL-017
      - CAP-PFM-TNL-005
      - CAP-PFM-TNL-013
      - CAP-PFM-TNL-014
    preconditions: An eligible request and authorized cancellation attempt contend at the destruction boundary.
    steps: >-
      Run cancellation and irreversible handoff concurrently; inspect request, workspace and purge-job records
      and try a later cancellation.
    expected: >-
      One decision wins with matching records. A destruction winner submits purge and subsequent cancellation
      refuses; a cancellation winner submits no purge.
    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-016-begin-destruction-only-when-every-safeguard-still-holds.md;
      rhythm-v2-docs:specs/platform/tenant-lifecycle/planning/capabilities/CAP-PFM-TNL-017-remove-everything-a-workspace-owned-and-prove-it-is-gone.md;
      rhythm-v2-docs:specs/platform/tenant-lifecycle/planning/capabilities/CAP-PFM-TNL-005-keep-people-and-background-work-out-of-a-workspace-that-is.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-014-hold-release-or-call-off-a-deletion-before-destruction.md
    action_evidence:
      provenance: proposed
      source: >-
        rhythm-v2-docs:specs/platform/tenant-lifecycle/planning/capabilities/CAP-PFM-TNL-016-begin-destruction-only-when-every-safeguard-still-holds.md;
        rhythm-v2-docs:specs/platform/tenant-lifecycle/planning/capabilities/CAP-PFM-TNL-017-remove-everything-a-workspace-owned-and-prove-it-is-gone.md;
        rhythm-v2-docs:specs/platform/tenant-lifecycle/planning/capabilities/CAP-PFM-TNL-005-keep-people-and-background-work-out-of-a-workspace-that-is.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-014-hold-release-or-call-off-a-deletion-before-destruction.md
    assertion_evidence:
      provenance: proposed
      source: >-
        rhythm-v2-docs:specs/platform/tenant-lifecycle/planning/capabilities/CAP-PFM-TNL-016-begin-destruction-only-when-every-safeguard-still-holds.md;
        rhythm-v2-docs:specs/platform/tenant-lifecycle/planning/capabilities/CAP-PFM-TNL-017-remove-everything-a-workspace-owned-and-prove-it-is-gone.md;
        rhythm-v2-docs:specs/platform/tenant-lifecycle/planning/capabilities/CAP-PFM-TNL-005-keep-people-and-background-work-out-of-a-workspace-that-is.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-014-hold-release-or-call-off-a-deletion-before-destruction.md
evidence:
  - 'services-platform:modules/tenants/aws/api/tenant-deletion-requests.routes.ts'
  - >-
    services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#waits
    one millisecond before the date
  - >-
    services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#waits
    when the person who asked no longer holds the permission to ask
  - >-
    services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#ends
    when the request was cancelled while the job slept
  - >-
    services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#answers
    that destruction began
  - >-
    services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#lets
    exactly one of the two win, every round
  - >-
    services-platform:modules/tenants/tests/e2e/tenant-deletion-recovery.e2e.spec.js#answers a new schedule
    job, and names the one it superseded
  - >-
    rhythm-v2-docs:specs/platform/tenant-lifecycle/planning/capabilities/CAP-PFM-TNL-016-begin-destruction-only-when-every-safeguard-still-holds.md;
    rhythm-v2-docs:specs/platform/tenant-lifecycle/planning/capabilities/CAP-PFM-TNL-017-remove-everything-a-workspace-owned-and-prove-it-is-gone.md;
    rhythm-v2-docs:specs/platform/tenant-lifecycle/planning/capabilities/CAP-PFM-TNL-005-keep-people-and-background-work-out-of-a-workspace-that-is.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-014-hold-release-or-call-off-a-deletion-before-destruction.md
coverage:
  rule: 'gap: FND-PFM-TNL-081'
  transition: 'gap: FND-PFM-TNL-081'
  validation: covered
  permission: covered
  edge: covered
  failure: covered
  boundary: covered
  concurrency: covered
  invariant: 'gap: FND-PFM-TNL-081'
  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-081'
    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-081'
    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-081'
    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-081'
    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-081'
    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-081'
    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-081'
    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-081'
    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-081'
    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-081'
    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-081'
    provenance: observed
    source: 'services-platform:modules/tenants/services/persistence/tenants.ts:forceTenantDeletingAfterRestore'
  - state_model: STATE-PFM-TNL-004
    transition_n: 1
    coverage: 'gap: FND-PFM-TNL-081'
    provenance: observed
    source: 'services-platform:modules/tenants/services/deletion/deletion-holds.ts:holdTenantDeletion'
  - state_model: STATE-PFM-TNL-004
    transition_n: 2
    coverage: 'gap: FND-PFM-TNL-081'
    provenance: observed
    source: 'services-platform:modules/tenants/services/deletion/begin-destruction.ts:beginTenantDestruction'
  - state_model: STATE-PFM-TNL-004
    transition_n: 3
    coverage: 'gap: FND-PFM-TNL-081'
    provenance: observed
    source: 'services-platform:modules/tenants/services/deletion/deletion-holds.ts:releaseTenantDeletion'
  - state_model: STATE-PFM-TNL-004
    transition_n: 4
    coverage: 'gap: FND-PFM-TNL-081'
    provenance: observed
    source: 'services-platform:modules/tenants/services/deletion/deletion-holds.ts:cancelTenantDeletion'
  - state_model: STATE-PFM-TNL-004
    transition_n: 5
    coverage: 'gap: FND-PFM-TNL-081'
    provenance: observed
    source: 'services-platform:modules/tenants/services/deletion/deletion-holds.ts:cancelTenantDeletion'
  - state_model: STATE-PFM-TNL-004
    transition_n: 6
    coverage: 'gap: FND-PFM-TNL-081'
    provenance: observed
    source: 'services-platform:modules/tenants/services/deletion/begin-destruction.ts:beginTenantDestruction'
  - state_model: STATE-PFM-TNL-004
    transition_n: 7
    coverage: 'gap: FND-PFM-TNL-081'
    provenance: observed
    source: 'services-platform:modules/tenants/services/deletion/tenant-purge-operations.ts:tenantPurgeOperations'
  - state_model: STATE-PFM-TNL-004
    transition_n: 8
    coverage: 'gap: FND-PFM-TNL-081'
    provenance: observed
    source: 'services-platform:modules/tenants/services/deletion/tenant-purge-failure.ts:applyTenantPurgeFailure'
  - state_model: STATE-PFM-TNL-004
    transition_n: 9
    coverage: 'gap: FND-PFM-TNL-081'
    provenance: observed
    source: 'services-platform:modules/tenants/services/deletion/operator-recovery.ts:retryTenantPurge'
permission_obligations:
  - key: platform.tenants.deletion-request
    where_checked: service
    scenario_examples:
      - ATS-PFM-TNL-016-03
    coverage: 'gap: FND-PFM-TNL-081'
    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-016-begin-destruction-only-when-every-safeguard-still-holds.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.
---
# Revalidate the irreversible deletion decision: 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-016-01` | `ATS-PFM-TNL-016-01` |
| `BR-CAP-PFM-TNL-016-02` | `ATS-PFM-TNL-016-02` |
| `BR-CAP-PFM-TNL-016-03` | `ATS-PFM-TNL-016-03` |
| `BR-CAP-PFM-TNL-016-04` | `ATS-PFM-TNL-016-04` |
| `BR-CAP-PFM-TNL-016-05` | `ATS-PFM-TNL-016-05`, `ATS-PFM-TNL-016-09` |
| `BR-CAP-PFM-TNL-016-06` | `ATS-PFM-TNL-016-06` |
| `BR-CAP-PFM-TNL-016-07` | `ATS-PFM-TNL-016-07` |

## Interactions With Related Capabilities

The winning destruction decision closes preservation routes. 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-014` | `ATS-PFM-TNL-016-09` (proposed) |
| `CAP-PFM-TNL-017` | `ATS-PFM-TNL-016-09` (proposed) |
