---
id: ATS-PFM-SEC-004
scope: CAP-PFM-SEC-004
product_area: platform
module: security
revision: 3
status: proposed
approved_by: null
approved_at: null
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
scenarios:
  - id: ATS-PFM-SEC-004-01
    title: Separate staff permissions for retirement actions
    level: api
    proves:
      - BR-CAP-PFM-SEC-004-01
    preconditions: Prepare a deletion request and a customer-administrator identity.
    steps: 'Attempt requesting, holding, releasing, cancelling, reading, listing and recovering deletion.'
    expected: The administrator is refused and the existing request is unchanged.
    negative: true
    data_needs: Use the records described in the setup.
    bound_to:
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-deletion-requests.e2e.spec.js#may not ask
        for a tenant to be deleted
      - TST-PFM-SEC-225
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-deletion-requests.e2e.spec.js#may not
        hold a deletion request
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-deletion-requests.e2e.spec.js#may not
        cancel a deletion request
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-deletion-requests.e2e.spec.js#may not
        list deletion requests
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-deletion-recovery.e2e.spec.js#may not
        resume a deletion schedule
      - TST-PFM-SEC-224
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-deletion-requests.e2e.spec.js#leaves the
        request exactly as it was after all of those refusals
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/e2e/tenant-deletion-requests.e2e.spec.js#may not ask
      for a tenant to be deleted
    category: permission
    test_references:
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-deletion-requests.e2e.spec.js#may not ask
        for a tenant to be deleted
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-deletion-requests.e2e.spec.js#may not
        hold a deletion request
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-deletion-requests.e2e.spec.js#may not
        cancel a deletion request
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-deletion-requests.e2e.spec.js#may not
        list deletion requests
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-deletion-recovery.e2e.spec.js#may not
        resume a deletion schedule
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-deletion-requests.e2e.spec.js#leaves the
        request exactly as it was after all of those refusals
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/e2e/tenant-deletion-requests.e2e.spec.js#may not ask
        for a tenant to be deleted
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/e2e/tenant-deletion-requests.e2e.spec.js#may not ask
        for a tenant to be deleted
    binding_scope: >-
      The binding applies to the cited executable observations and their dependency boundary. Extra
      setup, operations or combinations in this scenario still require evidence before the whole
      scenario is qualified.
  - id: ATS-PFM-SEC-004-02
    title: Request safety and confirmation inputs
    level: api
    proves:
      - BR-CAP-PFM-SEC-004-02
    preconditions: 'Prepare live, implementation, locked, parent and protected workspaces.'
    steps: >-
      Request each, then try identifier confirmation instead of name, an inadequate reason and a
      missing version.
    expected: All invalid attempts fail; the protected workspace gains no request.
    negative: true
    data_needs: Use the records described in the setup.
    bound_to:
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        a tenant that is still live, because people must lose access first
      - TST-PFM-SEC-237
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        a tenant that is still being implemented, for the same reason
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        a tenant that is locked
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        a tenant that is somebody else parent
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        a well-known tenant the whole development environment is built on
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        a confirmation that repeats the tenant id, which is no longer what the person types
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        a reason too short to tell anybody anything
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-deletion-requests.e2e.spec.js#refuses a
        body with no version as 400
      - TST-PFM-SEC-225
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
      a tenant that is still live, because people must lose access first
    category: validation
    test_references:
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        a tenant that is still live, because people must lose access first
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        a tenant that is still being implemented, for the same reason
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        a tenant that is locked
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        a tenant that is somebody else parent
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        a well-known tenant the whole development environment is built on
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        a confirmation that repeats the tenant id, which is no longer what the person types
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        a reason too short to tell anybody anything
      - >-
        services-platform:modules/tenants/tests/e2e/tenant-deletion-requests.e2e.spec.js#refuses a
        body with no version as 400
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        a tenant that is still live, because people must lose access first
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        a tenant that is still live, because people must lose access first
    binding_scope: >-
      The binding applies to the cited executable observations and their dependency boundary. Extra
      setup, operations or combinations in this scenario still require evidence before the whole
      scenario is qualified.
  - id: ATS-PFM-SEC-004-03
    title: Duplicate requests and a new request after cancellation
    level: api
    proves:
      - BR-CAP-PFM-SEC-004-03
      - INV-DOM-PFM-SEC-002-08
    preconditions: Prepare a scheduled request.
    steps: 'Request again, cancel the original and submit a new request.'
    expected: >-
      The duplicate returns 409 naming the open request; after cancellation a fresh request has a
      new eligibility date.
    negative: true
    data_needs: Use the records described in the setup.
    bound_to:
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        a second request, naming the one that is open
      - TST-PFM-SEC-237
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#allows
        a new request, with a new waiting period, once the first is cancelled
      - >-
        services-platform:modules/tenants/tests/integration/services/persistence/tenant-deletion-requests.integration.spec.js#refuses
        a second open request for the same tenant, by the index and not only by the service
      - TST-PFM-SEC-245
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
      a second request, naming the one that is open
    category: concurrency
    test_references:
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        a second request, naming the one that is open
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#allows
        a new request, with a new waiting period, once the first is cancelled
      - >-
        services-platform:modules/tenants/tests/integration/services/persistence/tenant-deletion-requests.integration.spec.js#refuses
        a second open request for the same tenant, by the index and not only by the service
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        a second request, naming the one that is open
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        a second request, naming the one that is open
    binding_scope: >-
      The binding applies to the cited executable observations and their dependency boundary. Extra
      setup, operations or combinations in this scenario still require evidence before the whole
      scenario is qualified.
  - id: ATS-PFM-SEC-004-04
    title: Calendar waits and the production minimum
    level: unit
    proves:
      - BR-CAP-PFM-SEC-004-04
    preconditions: 'Prepare previously used, never-activated and disposable workspaces.'
    steps: Request their removal and attempt an eleven-day production configuration.
    expected: >-
      Normal requests wait thirty days, never-activated requests one day and disposable short waits
      apply only outside production; the short production configuration fails.
    negative: false
    data_needs: Use the records described in the setup.
    bound_to:
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#makes
        a tenant that has been in use wait the full period
      - TST-PFM-SEC-237
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#makes
        a tenant that was never provisioned wait one day
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        the disposable path in Production, where no tenant is disposable
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#honours
        the Production floor, refusing a configured period below fourteen days
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#makes
      a tenant that has been in use wait the full period
    category: boundary
    test_references:
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#makes
        a tenant that has been in use wait the full period
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#makes
        a tenant that was never provisioned wait one day
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        the disposable path in Production, where no tenant is disposable
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#honours
        the Production floor, refusing a configured period below fourteen days
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#makes
        a tenant that has been in use wait the full period
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#makes
        a tenant that has been in use wait the full period
    binding_scope: >-
      The binding applies to the cited executable observations and their dependency boundary. Extra
      setup, operations or combinations in this scenario still require evidence before the whole
      scenario is qualified.
  - id: ATS-PFM-SEC-004-05
    title: Destruction waits for failed notice delivery
    level: api
    proves:
      - BR-CAP-PFM-SEC-004-05
    preconditions: Arrange a scheduled request whose one-day reminder cannot be delivered.
    steps: Advance the schedule beyond eligibility.
    expected: Destruction remains blocked while the required notice is undelivered.
    negative: true
    data_needs: Use the records described in the setup.
    bound_to:
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/tenant-deletion-schedule.integration.spec.js#holds
        the deletion indefinitely when a notice could not be delivered, rather than destroying the
        tenant unannounced
      - TST-PFM-SEC-238
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#waits
        while a notice destruction waits for has not been sent
      - TST-PFM-SEC-235
      - >-
        services-platform:modules/tenants/tests/integration/services/persistence/tenant-deletion-requests.integration.spec.js#still
        lists a failed notice, so a send that never worked never lets a tenant be deleted
      - TST-PFM-SEC-245
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/deletion/tenant-deletion-schedule.integration.spec.js#holds
      the deletion indefinitely when a notice could not be delivered, rather than destroying the
      tenant unannounced
    category: failure
    test_references:
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/tenant-deletion-schedule.integration.spec.js#holds
        the deletion indefinitely when a notice could not be delivered, rather than destroying the
        tenant unannounced
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#waits
        while a notice destruction waits for has not been sent
      - >-
        services-platform:modules/tenants/tests/integration/services/persistence/tenant-deletion-requests.integration.spec.js#still
        lists a failed notice, so a send that never worked never lets a tenant be deleted
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/deletion/tenant-deletion-schedule.integration.spec.js#holds
        the deletion indefinitely when a notice could not be delivered, rather than destroying the
        tenant unannounced
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/deletion/tenant-deletion-schedule.integration.spec.js#holds
        the deletion indefinitely when a notice could not be delivered, rather than destroying the
        tenant unannounced
    binding_scope: >-
      The binding applies to the cited executable observations and their dependency boundary. Extra
      setup, operations or combinations in this scenario still require evidence before the whole
      scenario is qualified.
  - id: ATS-PFM-SEC-004-06
    title: Reasoned holds and late-release reminders
    level: api
    proves:
      - BR-CAP-PFM-SEC-004-06
      - INV-DOM-PFM-SEC-002-09
    preconditions: Prepare a request eligible tomorrow.
    steps: 'Try a hold without an adequate reason, then hold with a reason and release.'
    expected: >-
      The invalid hold fails; the valid hold preserves the date; release grants three more days and
      creates a new reminder.
    negative: false
    data_needs: Use the records described in the setup.
    bound_to:
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/deletion-holds.integration.spec.js#refuses
        a hold with no reason worth reading
      - TST-PFM-SEC-236
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/deletion-holds.integration.spec.js#leaves
        the date alone: a hold stops the clock rather than moving it
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/deletion-holds.integration.spec.js#pushes
        the date out three days when the original is nearly here
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/deletion-holds.integration.spec.js#owes
        a fresh one-day reminder against the date that now applies
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/deletion/deletion-holds.integration.spec.js#refuses
      a hold with no reason worth reading
    category: transition
    test_references:
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/deletion-holds.integration.spec.js#refuses
        a hold with no reason worth reading
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/deletion-holds.integration.spec.js#leaves
        the date alone: a hold stops the clock rather than moving it
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/deletion-holds.integration.spec.js#pushes
        the date out three days when the original is nearly here
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/deletion-holds.integration.spec.js#owes
        a fresh one-day reminder against the date that now applies
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/deletion/deletion-holds.integration.spec.js#refuses
        a hold with no reason worth reading
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/deletion/deletion-holds.integration.spec.js#refuses
        a hold with no reason worth reading
    binding_scope: >-
      The binding applies to the cited executable observations and their dependency boundary. Extra
      setup, operations or combinations in this scenario still require evidence before the whole
      scenario is qualified.
  - id: ATS-PFM-SEC-004-07
    title: Cancellation before and after destruction
    level: api
    proves:
      - BR-CAP-PFM-SEC-004-07
    preconditions: Prepare held and executing requests.
    steps: Cancel both.
    expected: >-
      The held request is cancelled with active lifecycle and disabled status; the executing request
      is refused without change.
    negative: true
    data_needs: Use the records described in the setup.
    bound_to:
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/deletion-holds.integration.spec.js#returns
        the tenant to active
      - TST-PFM-SEC-236
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/deletion-holds.integration.spec.js#leaves
        the tenant disabled: calling off a deletion restores nobody access
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/deletion-holds.integration.spec.js#refuses
        to cancel a request whose destruction has begun
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/deletion-holds.integration.spec.js#leaves
        that executing request exactly as it was
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/deletion/deletion-holds.integration.spec.js#returns
      the tenant to active
    category: transition
    test_references:
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/deletion-holds.integration.spec.js#returns
        the tenant to active
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/deletion-holds.integration.spec.js#leaves
        the tenant disabled: calling off a deletion restores nobody access
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/deletion-holds.integration.spec.js#refuses
        to cancel a request whose destruction has begun
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/deletion-holds.integration.spec.js#leaves
        that executing request exactly as it was
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/deletion/deletion-holds.integration.spec.js#returns
        the tenant to active
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/deletion/deletion-holds.integration.spec.js#returns
        the tenant to active
    binding_scope: >-
      The binding applies to the cited executable observations and their dependency boundary. Extra
      setup, operations or combinations in this scenario still require evidence before the whole
      scenario is qualified.
  - id: ATS-PFM-SEC-004-08
    title: Current safeguards at destruction start
    level: api
    proves:
      - BR-CAP-PFM-SEC-004-08
    preconditions: Prepare a request at eligibility.
    steps: >-
      Attempt start just before eligibility, during a hold, after adding a sandbox or lock, and
      after removing requester authority.
    expected: 'Each attempt waits; lost authority creates a hold, and the workspace stays pending deletion.'
    negative: true
    data_needs: Use the records described in the setup.
    bound_to:
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#waits
        one millisecond before the date
      - TST-PFM-SEC-235
      - >-
        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#holds
        the request in that case, so a person has to look at it rather than a job retrying forever
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#waits
      one millisecond before the date
    category: invariant
    test_references:
      - >-
        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
        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#holds
        the request in that case, so a person has to look at it rather than a job retrying forever
    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_scope: >-
      The binding applies to the cited executable observations and their dependency boundary. Extra
      setup, operations or combinations in this scenario still require evidence before the whole
      scenario is qualified.
  - id: ATS-PFM-SEC-004-09
    title: The cancellation/destruction race
    level: api
    proves:
      - BR-CAP-PFM-SEC-004-09
    preconditions: Prepare requests at their eligibility time.
    steps: Race cancellation against destruction on two database connections over twenty rounds.
    expected: 'Each round has one winning outcome, and cancellation after destruction is refused.'
    negative: true
    data_needs: Use the records described in the setup.
    bound_to:
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#refuses
        the cancel as already executing in every round destruction won
      - TST-PFM-SEC-235
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#refuses
        a cancel that arrives after the point of no return
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#refuses
      the cancel as already executing in every round destruction won
    category: concurrency
    test_references:
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#refuses
        the cancel as already executing in every round destruction won
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#refuses
        a cancel that arrives after the point of no return
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#refuses
        the cancel as already executing in every round destruction won
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js#refuses
        the cancel as already executing in every round destruction won
    binding_scope: >-
      The binding applies to the cited executable observations and their dependency boundary. Extra
      setup, operations or combinations in this scenario still require evidence before the whole
      scenario is qualified.
  - id: ATS-PFM-SEC-004-10
    title: Recovery preserves eligibility and requires purge failure
    level: api
    proves:
      - BR-CAP-PFM-SEC-004-10
    preconditions: Prepare a scheduled request and a completed purge.
    steps: Resume the schedule twice and attempt purge retry.
    expected: >-
      Eligibility stays fixed; a second running schedule and a retry without purge failure each
      return 409 without changing the request.
    negative: true
    data_needs: Use the records described in the setup.
    bound_to:
      - >-
        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
      - TST-PFM-SEC-224
      - >-
        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#refuses as
        409 a retry of a purge that did not fail
    provenance: test
    source: >-
      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
    category: failure
    test_references:
      - >-
        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#refuses as
        409 a retry of a purge that did not fail
    action_evidence:
      provenance: test
      source: >-
        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
    assertion_evidence:
      provenance: test
      source: >-
        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
    binding_scope: >-
      The binding applies to the cited executable observations and their dependency boundary. Extra
      setup, operations or combinations in this scenario still require evidence before the whole
      scenario is qualified.
  - id: ATS-PFM-SEC-004-11
    title: Retained identity and identifier retirement
    level: api
    proves:
      - BR-CAP-PFM-SEC-004-11
      - INV-DOM-PFM-SEC-002-01
    preconditions: Prepare a deletion that can complete.
    steps: >-
      Read the request’s copied identity and try provisioning under the removed workspace
      identifier.
    expected: >-
      The request retains the workspace name and customer; provisioning with the retired identifier
      fails.
    negative: false
    data_needs: Complete a workspace removal in the test database before reading the retained request.
    bound_to:
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#copies
        the tenant name and customer, so the record still reads after the tenant is gone
      - TST-PFM-SEC-237
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/tenant-purge-recovery.integration.spec.js#refuses
        to create a tenant again under the id of one that was deleted
      - TST-PFM-SEC-240
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#copies
      the tenant name and customer, so the record still reads after the tenant is gone
    category: invariant
    test_references:
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#copies
        the tenant name and customer, so the record still reads after the tenant is gone
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/tenant-purge-recovery.integration.spec.js#refuses
        to create a tenant again under the id of one that was deleted
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#copies
        the tenant name and customer, so the record still reads after the tenant is gone
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#copies
        the tenant name and customer, so the record still reads after the tenant is gone
    binding_scope: >-
      The binding applies to the cited executable observations and their dependency boundary. Extra
      setup, operations or combinations in this scenario still require evidence before the whole
      scenario is qualified.
  - id: ATS-PFM-SEC-004-12
    title: 'Workspace lifecycle: provisioning_failed to deletion_pending'
    category: transition
    level: api
    proves:
      - BR-CAP-PFM-SEC-004-02
    state_model: STATE-PFM-SEC-001
    transition:
      from: provisioning_failed
      to: deletion_pending
      index: 3
    preconditions: >-
      Prepare a run-owned workspace lifecycle in provisioning_failed state with the authority and
      inputs required by the cited transition.
    steps:
      - do: Request retirement of the disabled failed setup with its name and reason.
        expect: >-
          After the stated action, observe the workspace lifecycle in deletion_pending state. This
          case does not require an additional history event unless the transition explicitly defines
          one.
        provenance: proposed
        source:
          - >-
            services-platform:modules/tenants/services/deletion/request-deletion.ts:REQUESTABLE_TENANT_LIFECYCLE_STATES
          - >-
            services-platform at ad3f6a65:
            modules/tenants/services/lifecycle/lifecycle-transitions.ts;
            services/persistence/tenants.ts; services/provisioning/*; services/deletion/*;
            services/access/tenant-availability.ts; db/tenants.table.ts;
            docs/tenants/tenant-lifecycle-plan.md §2.2, §4, §5.
    expected: >-
      After the stated action, observe the workspace lifecycle in deletion_pending state. This case
      does not require an additional history event unless the transition explicitly defines one.
    negative: false
    data_needs: >-
      A disposable customer, workspace and named actor; a controllable clock where the transition
      depends on time.
    bound_to: []
    provenance: proposed
    source:
      - >-
        services-platform:modules/tenants/services/deletion/request-deletion.ts:REQUESTABLE_TENANT_LIFECYCLE_STATES
      - >-
        services-platform at ad3f6a65: modules/tenants/services/lifecycle/lifecycle-transitions.ts;
        services/persistence/tenants.ts; services/provisioning/*; services/deletion/*;
        services/access/tenant-availability.ts; db/tenants.table.ts;
        docs/tenants/tenant-lifecycle-plan.md §2.2, §4, §5.
    guard_cases: Retirement preconditions pass and business status is disabled.
    side_effects_to_verify:
      - 'Commit request, notices and schedule job together'
      - Use the never-activated waiting policy
    transition_assertion:
      state: deletion_pending
      provenance: proposed
      source:
        - >-
          services-platform:modules/tenants/services/deletion/request-deletion.ts:REQUESTABLE_TENANT_LIFECYCLE_STATES
        - >-
          services-platform at ad3f6a65:
          modules/tenants/services/lifecycle/lifecycle-transitions.ts;
          services/persistence/tenants.ts; services/provisioning/*; services/deletion/*;
          services/access/tenant-availability.ts; db/tenants.table.ts;
          docs/tenants/tenant-lifecycle-plan.md §2.2, §4, §5.
    action_evidence:
      provenance: proposed
      source:
        - >-
          services-platform:modules/tenants/services/deletion/request-deletion.ts:REQUESTABLE_TENANT_LIFECYCLE_STATES
        - >-
          services-platform at ad3f6a65:
          modules/tenants/services/lifecycle/lifecycle-transitions.ts;
          services/persistence/tenants.ts; services/provisioning/*; services/deletion/*;
          services/access/tenant-availability.ts; db/tenants.table.ts;
          docs/tenants/tenant-lifecycle-plan.md §2.2, §4, §5.
    assertion_evidence:
      provenance: proposed
      source:
        - >-
          services-platform:modules/tenants/services/deletion/request-deletion.ts:REQUESTABLE_TENANT_LIFECYCLE_STATES
        - >-
          services-platform at ad3f6a65:
          modules/tenants/services/lifecycle/lifecycle-transitions.ts;
          services/persistence/tenants.ts; services/provisioning/*; services/deletion/*;
          services/access/tenant-availability.ts; db/tenants.table.ts;
          docs/tenants/tenant-lifecycle-plan.md §2.2, §4, §5.
    binding_scope: >-
      No executable assertion is bound. The scenario specifies proposed proof and does not establish
      implemented or passing behavior.
  - id: ATS-PFM-SEC-004-13
    title: 'Workspace lifecycle: active to deletion_pending'
    category: transition
    level: api
    proves:
      - BR-CAP-PFM-SEC-004-02
    state_model: STATE-PFM-SEC-001
    transition:
      from: active
      to: deletion_pending
      index: 7
    preconditions: >-
      Prepare a run-owned workspace lifecycle in active state with the authority and inputs required
      by the cited transition.
    steps:
      - do: Request retirement of the disabled active workspace with its current version.
        expect: >-
          After the stated action, observe the workspace lifecycle in deletion_pending state. This
          case does not require an additional history event unless the transition explicitly defines
          one.
        provenance: proposed
        source:
          - >-
            services-platform:modules/tenants/services/deletion/request-deletion.ts:requestTenantDeletion
          - >-
            services-platform at ad3f6a65:
            modules/tenants/services/lifecycle/lifecycle-transitions.ts;
            services/persistence/tenants.ts; services/provisioning/*; services/deletion/*;
            services/access/tenant-availability.ts; db/tenants.table.ts;
            docs/tenants/tenant-lifecycle-plan.md §2.2, §4, §5.
    expected: >-
      After the stated action, observe the workspace lifecycle in deletion_pending state. This case
      does not require an additional history event unless the transition explicitly defines one.
    negative: false
    data_needs: >-
      A disposable customer, workspace and named actor; a controllable clock where the transition
      depends on time.
    bound_to: []
    provenance: proposed
    source:
      - >-
        services-platform:modules/tenants/services/deletion/request-deletion.ts:requestTenantDeletion
      - >-
        services-platform at ad3f6a65: modules/tenants/services/lifecycle/lifecycle-transitions.ts;
        services/persistence/tenants.ts; services/provisioning/*; services/deletion/*;
        services/access/tenant-availability.ts; db/tenants.table.ts;
        docs/tenants/tenant-lifecycle-plan.md §2.2, §4, §5.
    guard_cases: >-
      Disabled status, no locks or sandboxes, allowed environment, typed confirmation, reason and no
      open request are required.
    side_effects_to_verify:
      - 'Commit request, notices and schedule job together'
      - Calculate eligibility from the request-time policy
      - Invalidate local availability
    transition_assertion:
      state: deletion_pending
      provenance: proposed
      source:
        - >-
          services-platform:modules/tenants/services/deletion/request-deletion.ts:requestTenantDeletion
        - >-
          services-platform at ad3f6a65:
          modules/tenants/services/lifecycle/lifecycle-transitions.ts;
          services/persistence/tenants.ts; services/provisioning/*; services/deletion/*;
          services/access/tenant-availability.ts; db/tenants.table.ts;
          docs/tenants/tenant-lifecycle-plan.md §2.2, §4, §5.
    action_evidence:
      provenance: proposed
      source:
        - >-
          services-platform:modules/tenants/services/deletion/request-deletion.ts:requestTenantDeletion
        - >-
          services-platform at ad3f6a65:
          modules/tenants/services/lifecycle/lifecycle-transitions.ts;
          services/persistence/tenants.ts; services/provisioning/*; services/deletion/*;
          services/access/tenant-availability.ts; db/tenants.table.ts;
          docs/tenants/tenant-lifecycle-plan.md §2.2, §4, §5.
    assertion_evidence:
      provenance: proposed
      source:
        - >-
          services-platform:modules/tenants/services/deletion/request-deletion.ts:requestTenantDeletion
        - >-
          services-platform at ad3f6a65:
          modules/tenants/services/lifecycle/lifecycle-transitions.ts;
          services/persistence/tenants.ts; services/provisioning/*; services/deletion/*;
          services/access/tenant-availability.ts; db/tenants.table.ts;
          docs/tenants/tenant-lifecycle-plan.md §2.2, §4, §5.
    binding_scope: >-
      No executable assertion is bound. The scenario specifies proposed proof and does not establish
      implemented or passing behavior.
  - id: ATS-PFM-SEC-004-14
    title: 'Workspace lifecycle: deletion_pending to active'
    category: transition
    level: api
    proves:
      - BR-CAP-PFM-SEC-004-07
    state_model: STATE-PFM-SEC-001
    transition:
      from: deletion_pending
      to: active
      index: 8
    preconditions: >-
      Prepare a run-owned workspace lifecycle in deletion_pending state with the authority and
      inputs required by the cited transition.
    steps:
      - do: Cancel before the destructive task takes the request lock.
        expect: >-
          After the stated action, observe the workspace lifecycle in active state. This case does
          not require an additional history event unless the transition explicitly defines one.
        provenance: proposed
        source:
          - 'services-platform:modules/tenants/services/deletion/deletion-holds.ts'
          - >-
            services-platform at ad3f6a65:
            modules/tenants/services/lifecycle/lifecycle-transitions.ts;
            services/persistence/tenants.ts; services/provisioning/*; services/deletion/*;
            services/access/tenant-availability.ts; db/tenants.table.ts;
            docs/tenants/tenant-lifecycle-plan.md §2.2, §4, §5.
    expected: >-
      After the stated action, observe the workspace lifecycle in active state. This case does not
      require an additional history event unless the transition explicitly defines one.
    negative: false
    data_needs: >-
      A disposable customer, workspace and named actor; a controllable clock where the transition
      depends on time.
    bound_to: []
    provenance: proposed
    source:
      - 'services-platform:modules/tenants/services/deletion/deletion-holds.ts'
      - >-
        services-platform at ad3f6a65: modules/tenants/services/lifecycle/lifecycle-transitions.ts;
        services/persistence/tenants.ts; services/provisioning/*; services/deletion/*;
        services/access/tenant-availability.ts; db/tenants.table.ts;
        docs/tenants/tenant-lifecycle-plan.md §2.2, §4, §5.
    guard_cases: The scheduled or held request wins the shared locks before the point of no return.
    side_effects_to_verify:
      - Keep business status disabled
      - Record the cancellation notice
    transition_assertion:
      state: active
      provenance: proposed
      source:
        - 'services-platform:modules/tenants/services/deletion/deletion-holds.ts'
        - >-
          services-platform at ad3f6a65:
          modules/tenants/services/lifecycle/lifecycle-transitions.ts;
          services/persistence/tenants.ts; services/provisioning/*; services/deletion/*;
          services/access/tenant-availability.ts; db/tenants.table.ts;
          docs/tenants/tenant-lifecycle-plan.md §2.2, §4, §5.
    action_evidence:
      provenance: proposed
      source:
        - 'services-platform:modules/tenants/services/deletion/deletion-holds.ts'
        - >-
          services-platform at ad3f6a65:
          modules/tenants/services/lifecycle/lifecycle-transitions.ts;
          services/persistence/tenants.ts; services/provisioning/*; services/deletion/*;
          services/access/tenant-availability.ts; db/tenants.table.ts;
          docs/tenants/tenant-lifecycle-plan.md §2.2, §4, §5.
    assertion_evidence:
      provenance: proposed
      source:
        - 'services-platform:modules/tenants/services/deletion/deletion-holds.ts'
        - >-
          services-platform at ad3f6a65:
          modules/tenants/services/lifecycle/lifecycle-transitions.ts;
          services/persistence/tenants.ts; services/provisioning/*; services/deletion/*;
          services/access/tenant-availability.ts; db/tenants.table.ts;
          docs/tenants/tenant-lifecycle-plan.md §2.2, §4, §5.
    binding_scope: >-
      No executable assertion is bound. The scenario specifies proposed proof and does not establish
      implemented or passing behavior.
  - id: ATS-PFM-SEC-004-15
    title: 'Workspace lifecycle: deletion_pending to deleting'
    category: transition
    level: api
    proves:
      - BR-CAP-PFM-SEC-004-08
    state_model: STATE-PFM-SEC-001
    transition:
      from: deletion_pending
      to: deleting
      index: 9
    preconditions: >-
      Prepare a run-owned workspace lifecycle in deletion_pending state with the authority and
      inputs required by the cited transition.
    steps:
      - do: 'Deliver the gating notices, advance beyond eligibility and execute the destructive task.'
        expect: >-
          After the stated action, observe the workspace lifecycle in deleting state. This case does
          not require an additional history event unless the transition explicitly defines one.
        provenance: proposed
        source:
          - 'services-platform:modules/tenants/services/deletion/begin-destruction.ts'
          - >-
            services-platform at ad3f6a65:
            modules/tenants/services/lifecycle/lifecycle-transitions.ts;
            services/persistence/tenants.ts; services/provisioning/*; services/deletion/*;
            services/access/tenant-availability.ts; db/tenants.table.ts;
            docs/tenants/tenant-lifecycle-plan.md §2.2, §4, §5.
    expected: >-
      After the stated action, observe the workspace lifecycle in deleting state. This case does not
      require an additional history event unless the transition explicitly defines one.
    negative: false
    data_needs: >-
      A disposable customer, workspace and named actor; a controllable clock where the transition
      depends on time.
    bound_to: []
    provenance: proposed
    source:
      - 'services-platform:modules/tenants/services/deletion/begin-destruction.ts'
      - >-
        services-platform at ad3f6a65: modules/tenants/services/lifecycle/lifecycle-transitions.ts;
        services/persistence/tenants.ts; services/provisioning/*; services/deletion/*;
        services/access/tenant-availability.ts; db/tenants.table.ts;
        docs/tenants/tenant-lifecycle-plan.md §2.2, §4, §5.
    guard_cases: >-
      Eligibility and gating notices pass; no hold, locks or sandboxes remain; requester authority
      is re-evaluated.
    side_effects_to_verify:
      - Mark the request executing
      - Create its purge job atomically
    transition_assertion:
      state: deleting
      provenance: proposed
      source:
        - 'services-platform:modules/tenants/services/deletion/begin-destruction.ts'
        - >-
          services-platform at ad3f6a65:
          modules/tenants/services/lifecycle/lifecycle-transitions.ts;
          services/persistence/tenants.ts; services/provisioning/*; services/deletion/*;
          services/access/tenant-availability.ts; db/tenants.table.ts;
          docs/tenants/tenant-lifecycle-plan.md §2.2, §4, §5.
    action_evidence:
      provenance: proposed
      source:
        - 'services-platform:modules/tenants/services/deletion/begin-destruction.ts'
        - >-
          services-platform at ad3f6a65:
          modules/tenants/services/lifecycle/lifecycle-transitions.ts;
          services/persistence/tenants.ts; services/provisioning/*; services/deletion/*;
          services/access/tenant-availability.ts; db/tenants.table.ts;
          docs/tenants/tenant-lifecycle-plan.md §2.2, §4, §5.
    assertion_evidence:
      provenance: proposed
      source:
        - 'services-platform:modules/tenants/services/deletion/begin-destruction.ts'
        - >-
          services-platform at ad3f6a65:
          modules/tenants/services/lifecycle/lifecycle-transitions.ts;
          services/persistence/tenants.ts; services/provisioning/*; services/deletion/*;
          services/access/tenant-availability.ts; db/tenants.table.ts;
          docs/tenants/tenant-lifecycle-plan.md §2.2, §4, §5.
    binding_scope: >-
      No executable assertion is bound. The scenario specifies proposed proof and does not establish
      implemented or passing behavior.
  - id: ATS-PFM-SEC-004-16
    title: 'Workspace lifecycle: active to deleting'
    category: transition
    level: api
    proves:
      - BR-CAP-PFM-SEC-004-10
    state_model: STATE-PFM-SEC-001
    transition:
      from: active
      to: deleting
      index: 10
    preconditions: >-
      Prepare a run-owned workspace lifecycle in active state with the authority and inputs required
      by the cited transition.
    steps:
      - do: >-
          Apply the operator restore-recovery action first in dry-run mode and then to the run-owned
          restored workspace.
        expect: >-
          After the stated action, observe the workspace lifecycle in deleting state. This case does
          not require an additional history event unless the transition explicitly defines one.
        provenance: proposed
        source:
          - >-
            services-platform:modules/tenants/services/persistence/tenants.ts:forceTenantDeletingAfterRestore
          - >-
            services-platform at ad3f6a65:
            modules/tenants/services/lifecycle/lifecycle-transitions.ts;
            services/persistence/tenants.ts; services/provisioning/*; services/deletion/*;
            services/access/tenant-availability.ts; db/tenants.table.ts;
            docs/tenants/tenant-lifecycle-plan.md §2.2, §4, §5.
    expected: >-
      After the stated action, observe the workspace lifecycle in deleting state. This case does not
      require an additional history event unless the transition explicitly defines one.
    negative: false
    data_needs: >-
      A disposable customer, workspace and named actor; a controllable clock where the transition
      depends on time.
    bound_to: []
    provenance: proposed
    source:
      - >-
        services-platform:modules/tenants/services/persistence/tenants.ts:forceTenantDeletingAfterRestore
      - >-
        services-platform at ad3f6a65: modules/tenants/services/lifecycle/lifecycle-transitions.ts;
        services/persistence/tenants.ts; services/provisioning/*; services/deletion/*;
        services/access/tenant-availability.ts; db/tenants.table.ts;
        docs/tenants/tenant-lifecycle-plan.md §2.2, §4, §5.
    guard_cases: The external deletion ledger supplies authority; the script defaults to dry run.
    side_effects_to_verify:
      - Set disabled business status with deleting lifecycle
      - Use the explicit restore exception to the transition graph
    transition_assertion:
      state: deleting
      provenance: proposed
      source:
        - >-
          services-platform:modules/tenants/services/persistence/tenants.ts:forceTenantDeletingAfterRestore
        - >-
          services-platform at ad3f6a65:
          modules/tenants/services/lifecycle/lifecycle-transitions.ts;
          services/persistence/tenants.ts; services/provisioning/*; services/deletion/*;
          services/access/tenant-availability.ts; db/tenants.table.ts;
          docs/tenants/tenant-lifecycle-plan.md §2.2, §4, §5.
    action_evidence:
      provenance: proposed
      source:
        - >-
          services-platform:modules/tenants/services/persistence/tenants.ts:forceTenantDeletingAfterRestore
        - >-
          services-platform at ad3f6a65:
          modules/tenants/services/lifecycle/lifecycle-transitions.ts;
          services/persistence/tenants.ts; services/provisioning/*; services/deletion/*;
          services/access/tenant-availability.ts; db/tenants.table.ts;
          docs/tenants/tenant-lifecycle-plan.md §2.2, §4, §5.
    assertion_evidence:
      provenance: proposed
      source:
        - >-
          services-platform:modules/tenants/services/persistence/tenants.ts:forceTenantDeletingAfterRestore
        - >-
          services-platform at ad3f6a65:
          modules/tenants/services/lifecycle/lifecycle-transitions.ts;
          services/persistence/tenants.ts; services/provisioning/*; services/deletion/*;
          services/access/tenant-availability.ts; db/tenants.table.ts;
          docs/tenants/tenant-lifecycle-plan.md §2.2, §4, §5.
    binding_scope: >-
      No executable assertion is bound. The scenario specifies proposed proof and does not establish
      implemented or passing behavior.
  - id: ATS-PFM-SEC-004-17
    title: 'Workspace retirement request: scheduled to held'
    category: transition
    level: api
    proves:
      - BR-CAP-PFM-SEC-004-06
    state_model: STATE-PFM-SEC-003
    transition:
      from: scheduled
      to: held
      index: 0
    preconditions: >-
      Prepare a run-owned workspace retirement request in scheduled state with the authority and
      inputs required by the cited transition.
    steps:
      - do: >-
          Place a reasoned hold; also inspect the automatic hold after the requester loses
          authority.
        expect: >-
          After the stated action, observe the workspace retirement request in held state. This case
          does not require an additional history event unless the transition explicitly defines one.
        provenance: proposed
        source:
          - >-
            services-platform:modules/tenants/services/deletion/deletion-holds.ts;
            begin-destruction.ts
          - >-
            services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
            tenant-deletion-notices.table.ts; services/deletion/*;
            docs/tenants/tenant-lifecycle-plan.md §5.
    expected: >-
      After the stated action, observe the workspace retirement request in held state. This case
      does not require an additional history event unless the transition explicitly defines one.
    negative: false
    data_needs: >-
      A disposable customer, workspace and named actor; a controllable clock where the transition
      depends on time.
    bound_to: []
    provenance: proposed
    source:
      - 'services-platform:modules/tenants/services/deletion/deletion-holds.ts; begin-destruction.ts'
      - >-
        services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
        tenant-deletion-notices.table.ts; services/deletion/*; docs/tenants/tenant-lifecycle-plan.md
        §5.
    guard_cases: >-
      A human hold requires deletion-hold authority; the system can hold its scheduled request when
      authority is lost.
    side_effects_to_verify:
      - Queue a hold notice
    transition_assertion:
      state: held
      provenance: proposed
      source:
        - >-
          services-platform:modules/tenants/services/deletion/deletion-holds.ts;
          begin-destruction.ts
        - >-
          services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
          tenant-deletion-notices.table.ts; services/deletion/*;
          docs/tenants/tenant-lifecycle-plan.md §5.
    action_evidence:
      provenance: proposed
      source:
        - >-
          services-platform:modules/tenants/services/deletion/deletion-holds.ts;
          begin-destruction.ts
        - >-
          services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
          tenant-deletion-notices.table.ts; services/deletion/*;
          docs/tenants/tenant-lifecycle-plan.md §5.
    assertion_evidence:
      provenance: proposed
      source:
        - >-
          services-platform:modules/tenants/services/deletion/deletion-holds.ts;
          begin-destruction.ts
        - >-
          services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
          tenant-deletion-notices.table.ts; services/deletion/*;
          docs/tenants/tenant-lifecycle-plan.md §5.
    binding_scope: >-
      No executable assertion is bound. The scenario specifies proposed proof and does not establish
      implemented or passing behavior.
  - id: ATS-PFM-SEC-004-18
    title: 'Workspace retirement request: held to scheduled'
    category: transition
    level: api
    proves:
      - BR-CAP-PFM-SEC-004-06
    state_model: STATE-PFM-SEC-003
    transition:
      from: held
      to: scheduled
      index: 1
    preconditions: >-
      Prepare a run-owned workspace retirement request in held state with the authority and inputs
      required by the cited transition.
    steps:
      - do: Release the hold close to eligibility and inspect the revised deadline and reminder.
        expect: >-
          After the stated action, observe the workspace retirement request in scheduled state. This
          case does not require an additional history event unless the transition explicitly defines
          one.
        provenance: proposed
        source:
          - 'services-platform:modules/tenants/services/deletion/deletion-holds.ts'
          - >-
            services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
            tenant-deletion-notices.table.ts; services/deletion/*;
            docs/tenants/tenant-lifecycle-plan.md §5.
    expected: >-
      After the stated action, observe the workspace retirement request in scheduled state. This
      case does not require an additional history event unless the transition explicitly defines
      one.
    negative: false
    data_needs: >-
      A disposable customer, workspace and named actor; a controllable clock where the transition
      depends on time.
    bound_to: []
    provenance: proposed
    source:
      - 'services-platform:modules/tenants/services/deletion/deletion-holds.ts'
      - >-
        services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
        tenant-deletion-notices.table.ts; services/deletion/*; docs/tenants/tenant-lifecycle-plan.md
        §5.
    guard_cases: The request is held and the caller has deletion-hold authority.
    side_effects_to_verify:
      - Extend eligibility to the later of its prior date and three days from release
      - Schedule a fresh one-day reminder
    transition_assertion:
      state: scheduled
      provenance: proposed
      source:
        - 'services-platform:modules/tenants/services/deletion/deletion-holds.ts'
        - >-
          services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
          tenant-deletion-notices.table.ts; services/deletion/*;
          docs/tenants/tenant-lifecycle-plan.md §5.
    action_evidence:
      provenance: proposed
      source:
        - 'services-platform:modules/tenants/services/deletion/deletion-holds.ts'
        - >-
          services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
          tenant-deletion-notices.table.ts; services/deletion/*;
          docs/tenants/tenant-lifecycle-plan.md §5.
    assertion_evidence:
      provenance: proposed
      source:
        - 'services-platform:modules/tenants/services/deletion/deletion-holds.ts'
        - >-
          services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
          tenant-deletion-notices.table.ts; services/deletion/*;
          docs/tenants/tenant-lifecycle-plan.md §5.
    binding_scope: >-
      No executable assertion is bound. The scenario specifies proposed proof and does not establish
      implemented or passing behavior.
  - id: ATS-PFM-SEC-004-19
    title: 'Workspace retirement request: scheduled to cancelled'
    category: transition
    level: api
    proves:
      - BR-CAP-PFM-SEC-004-07
    state_model: STATE-PFM-SEC-003
    transition:
      from: scheduled
      to: cancelled
      index: 2
    preconditions: >-
      Prepare a run-owned workspace retirement request in scheduled state with the authority and
      inputs required by the cited transition.
    steps:
      - do: Cancel the scheduled request before destructive execution.
        expect: >-
          After the stated action, observe the workspace retirement request in cancelled state. This
          case does not require an additional history event unless the transition explicitly defines
          one.
        provenance: proposed
        source:
          - 'services-platform:modules/tenants/services/deletion/deletion-holds.ts'
          - >-
            services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
            tenant-deletion-notices.table.ts; services/deletion/*;
            docs/tenants/tenant-lifecycle-plan.md §5.
    expected: >-
      After the stated action, observe the workspace retirement request in cancelled state. This
      case does not require an additional history event unless the transition explicitly defines
      one.
    negative: false
    data_needs: >-
      A disposable customer, workspace and named actor; a controllable clock where the transition
      depends on time.
    bound_to: []
    provenance: proposed
    source:
      - 'services-platform:modules/tenants/services/deletion/deletion-holds.ts'
      - >-
        services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
        tenant-deletion-notices.table.ts; services/deletion/*; docs/tenants/tenant-lifecycle-plan.md
        §5.
    guard_cases: Cancellation must win the request/workspace locks before execution.
    side_effects_to_verify:
      - Return lifecycle to active without enabling business status
      - Queue cancellation notice; the watcher settles on its next inspection
    transition_assertion:
      state: cancelled
      provenance: proposed
      source:
        - 'services-platform:modules/tenants/services/deletion/deletion-holds.ts'
        - >-
          services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
          tenant-deletion-notices.table.ts; services/deletion/*;
          docs/tenants/tenant-lifecycle-plan.md §5.
    action_evidence:
      provenance: proposed
      source:
        - 'services-platform:modules/tenants/services/deletion/deletion-holds.ts'
        - >-
          services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
          tenant-deletion-notices.table.ts; services/deletion/*;
          docs/tenants/tenant-lifecycle-plan.md §5.
    assertion_evidence:
      provenance: proposed
      source:
        - 'services-platform:modules/tenants/services/deletion/deletion-holds.ts'
        - >-
          services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
          tenant-deletion-notices.table.ts; services/deletion/*;
          docs/tenants/tenant-lifecycle-plan.md §5.
    binding_scope: >-
      No executable assertion is bound. The scenario specifies proposed proof and does not establish
      implemented or passing behavior.
  - id: ATS-PFM-SEC-004-20
    title: 'Workspace retirement request: held to cancelled'
    category: transition
    level: api
    proves:
      - BR-CAP-PFM-SEC-004-07
    state_model: STATE-PFM-SEC-003
    transition:
      from: held
      to: cancelled
      index: 3
    preconditions: >-
      Prepare a run-owned workspace retirement request in held state with the authority and inputs
      required by the cited transition.
    steps:
      - do: Cancel the held request before destructive execution.
        expect: >-
          After the stated action, observe the workspace retirement request in cancelled state. This
          case does not require an additional history event unless the transition explicitly defines
          one.
        provenance: proposed
        source:
          - 'services-platform:modules/tenants/services/deletion/deletion-holds.ts'
          - >-
            services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
            tenant-deletion-notices.table.ts; services/deletion/*;
            docs/tenants/tenant-lifecycle-plan.md §5.
    expected: >-
      After the stated action, observe the workspace retirement request in cancelled state. This
      case does not require an additional history event unless the transition explicitly defines
      one.
    negative: false
    data_needs: >-
      A disposable customer, workspace and named actor; a controllable clock where the transition
      depends on time.
    bound_to: []
    provenance: proposed
    source:
      - 'services-platform:modules/tenants/services/deletion/deletion-holds.ts'
      - >-
        services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
        tenant-deletion-notices.table.ts; services/deletion/*; docs/tenants/tenant-lifecycle-plan.md
        §5.
    guard_cases: The request has not entered execution.
    side_effects_to_verify:
      - Return lifecycle to active while retaining disabled status
    transition_assertion:
      state: cancelled
      provenance: proposed
      source:
        - 'services-platform:modules/tenants/services/deletion/deletion-holds.ts'
        - >-
          services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
          tenant-deletion-notices.table.ts; services/deletion/*;
          docs/tenants/tenant-lifecycle-plan.md §5.
    action_evidence:
      provenance: proposed
      source:
        - 'services-platform:modules/tenants/services/deletion/deletion-holds.ts'
        - >-
          services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
          tenant-deletion-notices.table.ts; services/deletion/*;
          docs/tenants/tenant-lifecycle-plan.md §5.
    assertion_evidence:
      provenance: proposed
      source:
        - 'services-platform:modules/tenants/services/deletion/deletion-holds.ts'
        - >-
          services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
          tenant-deletion-notices.table.ts; services/deletion/*;
          docs/tenants/tenant-lifecycle-plan.md §5.
    binding_scope: >-
      No executable assertion is bound. The scenario specifies proposed proof and does not establish
      implemented or passing behavior.
  - id: ATS-PFM-SEC-004-21
    title: 'Workspace retirement request: scheduled to executing'
    category: transition
    level: api
    proves:
      - BR-CAP-PFM-SEC-004-08
    state_model: STATE-PFM-SEC-003
    transition:
      from: scheduled
      to: executing
      index: 4
    preconditions: >-
      Prepare a run-owned workspace retirement request in scheduled state with the authority and
      inputs required by the cited transition.
    steps:
      - do: Deliver required notices and let the eligible watcher start destruction.
        expect: >-
          After the stated action, observe the workspace retirement request in executing state. This
          case does not require an additional history event unless the transition explicitly defines
          one.
        provenance: proposed
        source:
          - 'services-platform:modules/tenants/services/deletion/begin-destruction.ts'
          - >-
            services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
            tenant-deletion-notices.table.ts; services/deletion/*;
            docs/tenants/tenant-lifecycle-plan.md §5.
    expected: >-
      After the stated action, observe the workspace retirement request in executing state. This
      case does not require an additional history event unless the transition explicitly defines
      one.
    negative: false
    data_needs: >-
      A disposable customer, workspace and named actor; a controllable clock where the transition
      depends on time.
    bound_to: []
    provenance: proposed
    source:
      - 'services-platform:modules/tenants/services/deletion/begin-destruction.ts'
      - >-
        services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
        tenant-deletion-notices.table.ts; services/deletion/*; docs/tenants/tenant-lifecycle-plan.md
        §5.
    guard_cases: >-
      The named schedule job rechecks eligibility, notices, hold, workspace protections and
      requester authority.
    side_effects_to_verify:
      - Set workspace lifecycle to deleting
      - Create the purge job in the same transaction
    transition_assertion:
      state: executing
      provenance: proposed
      source:
        - 'services-platform:modules/tenants/services/deletion/begin-destruction.ts'
        - >-
          services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
          tenant-deletion-notices.table.ts; services/deletion/*;
          docs/tenants/tenant-lifecycle-plan.md §5.
    action_evidence:
      provenance: proposed
      source:
        - 'services-platform:modules/tenants/services/deletion/begin-destruction.ts'
        - >-
          services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
          tenant-deletion-notices.table.ts; services/deletion/*;
          docs/tenants/tenant-lifecycle-plan.md §5.
    assertion_evidence:
      provenance: proposed
      source:
        - 'services-platform:modules/tenants/services/deletion/begin-destruction.ts'
        - >-
          services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
          tenant-deletion-notices.table.ts; services/deletion/*;
          docs/tenants/tenant-lifecycle-plan.md §5.
    binding_scope: >-
      No executable assertion is bound. The scenario specifies proposed proof and does not establish
      implemented or passing behavior.
  - id: ATS-PFM-SEC-004-22
    title: 'Workspace retirement request: executing to failed'
    category: transition
    level: api
    proves:
      - BR-CAP-PFM-SEC-004-10
    state_model: STATE-PFM-SEC-003
    transition:
      from: executing
      to: failed
      index: 5
    preconditions: >-
      Prepare a run-owned workspace retirement request in executing state with the authority and
      inputs required by the cited transition.
    steps:
      - do: Fail the named purge job after a completed removal step and run the failure handler.
        expect: >-
          After the stated action, observe the workspace retirement request in failed state. This
          case does not require an additional history event unless the transition explicitly defines
          one.
        provenance: proposed
        source:
          - 'services-platform:modules/tenants/services/deletion/tenant-purge-failure.ts'
          - >-
            services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
            tenant-deletion-notices.table.ts; services/deletion/*;
            docs/tenants/tenant-lifecycle-plan.md §5.
    expected: >-
      After the stated action, observe the workspace retirement request in failed state. This case
      does not require an additional history event unless the transition explicitly defines one.
    negative: false
    data_needs: >-
      A disposable customer, workspace and named actor; a controllable clock where the transition
      depends on time.
    bound_to: []
    provenance: proposed
    source:
      - 'services-platform:modules/tenants/services/deletion/tenant-purge-failure.ts'
      - >-
        services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
        tenant-deletion-notices.table.ts; services/deletion/*; docs/tenants/tenant-lifecycle-plan.md
        §5.
    guard_cases: The executing request still names the failing job.
    side_effects_to_verify:
      - Queue an operator-safe failure notice
      - Keep lifecycle deleting
    transition_assertion:
      state: failed
      provenance: proposed
      source:
        - 'services-platform:modules/tenants/services/deletion/tenant-purge-failure.ts'
        - >-
          services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
          tenant-deletion-notices.table.ts; services/deletion/*;
          docs/tenants/tenant-lifecycle-plan.md §5.
    action_evidence:
      provenance: proposed
      source:
        - 'services-platform:modules/tenants/services/deletion/tenant-purge-failure.ts'
        - >-
          services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
          tenant-deletion-notices.table.ts; services/deletion/*;
          docs/tenants/tenant-lifecycle-plan.md §5.
    assertion_evidence:
      provenance: proposed
      source:
        - 'services-platform:modules/tenants/services/deletion/tenant-purge-failure.ts'
        - >-
          services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
          tenant-deletion-notices.table.ts; services/deletion/*;
          docs/tenants/tenant-lifecycle-plan.md §5.
    binding_scope: >-
      No executable assertion is bound. The scenario specifies proposed proof and does not establish
      implemented or passing behavior.
  - id: ATS-PFM-SEC-004-23
    title: 'Workspace retirement request: failed to executing'
    category: transition
    level: api
    proves:
      - BR-CAP-PFM-SEC-004-10
    state_model: STATE-PFM-SEC-003
    transition:
      from: failed
      to: executing
      index: 6
    preconditions: >-
      Prepare a run-owned workspace retirement request in failed state with the authority and inputs
      required by the cited transition.
    steps:
      - do: Retry the failed named purge as authorized staff.
        expect: >-
          After the stated action, observe the workspace retirement request in executing state. This
          case does not require an additional history event unless the transition explicitly defines
          one.
        provenance: proposed
        source:
          - >-
            services-platform:modules/tenants/services/deletion/operator-recovery.ts:retryTenantPurge
          - >-
            services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
            tenant-deletion-notices.table.ts; services/deletion/*;
            docs/tenants/tenant-lifecycle-plan.md §5.
    expected: >-
      After the stated action, observe the workspace retirement request in executing state. This
      case does not require an additional history event unless the transition explicitly defines
      one.
    negative: false
    data_needs: >-
      A disposable customer, workspace and named actor; a controllable clock where the transition
      depends on time.
    bound_to: []
    provenance: proposed
    source:
      - 'services-platform:modules/tenants/services/deletion/operator-recovery.ts:retryTenantPurge'
      - >-
        services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
        tenant-deletion-notices.table.ts; services/deletion/*; docs/tenants/tenant-lifecycle-plan.md
        §5.
    guard_cases: The request is failed and the caller has deletion-request authority.
    side_effects_to_verify:
      - Create and name the retry job with completed steps copied
      - The recovery path does not add a security-history event
    transition_assertion:
      state: executing
      provenance: proposed
      source:
        - 'services-platform:modules/tenants/services/deletion/operator-recovery.ts:retryTenantPurge'
        - >-
          services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
          tenant-deletion-notices.table.ts; services/deletion/*;
          docs/tenants/tenant-lifecycle-plan.md §5.
    action_evidence:
      provenance: proposed
      source:
        - 'services-platform:modules/tenants/services/deletion/operator-recovery.ts:retryTenantPurge'
        - >-
          services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
          tenant-deletion-notices.table.ts; services/deletion/*;
          docs/tenants/tenant-lifecycle-plan.md §5.
    assertion_evidence:
      provenance: proposed
      source:
        - 'services-platform:modules/tenants/services/deletion/operator-recovery.ts:retryTenantPurge'
        - >-
          services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
          tenant-deletion-notices.table.ts; services/deletion/*;
          docs/tenants/tenant-lifecycle-plan.md §5.
    binding_scope: >-
      No executable assertion is bound. The scenario specifies proposed proof and does not establish
      implemented or passing behavior.
  - id: ATS-PFM-SEC-004-24
    title: 'Workspace retirement request: executing to completed'
    category: transition
    level: api
    proves:
      - BR-CAP-PFM-SEC-004-11
    state_model: STATE-PFM-SEC-003
    transition:
      from: executing
      to: completed
      index: 7
    preconditions: >-
      Prepare a run-owned workspace retirement request in executing state with the authority and
      inputs required by the cited transition.
    steps:
      - do: >-
          Complete every participant inventory and execute finalization; inspect retained counts and
          the external ledger attempt.
        expect: >-
          After the stated action, observe the workspace retirement request in completed state. This
          case does not require an additional history event unless the transition explicitly defines
          one.
        provenance: proposed
        source:
          - 'services-platform:modules/tenants/services/deletion/tenant-purge-workflow.ts (finalize)'
          - >-
            services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
            tenant-deletion-notices.table.ts; services/deletion/*;
            docs/tenants/tenant-lifecycle-plan.md §5.
    expected: >-
      After the stated action, observe the workspace retirement request in completed state. This
      case does not require an additional history event unless the transition explicitly defines
      one.
    negative: false
    data_needs: >-
      A disposable customer, workspace and named actor; a controllable clock where the transition
      depends on time.
    bound_to: []
    provenance: proposed
    source:
      - 'services-platform:modules/tenants/services/deletion/tenant-purge-workflow.ts (finalize)'
      - >-
        services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
        tenant-deletion-notices.table.ts; services/deletion/*; docs/tenants/tenant-lifecycle-plan.md
        §5.
    guard_cases: The deleting workspace and request still authorize this job.
    side_effects_to_verify:
      - 'Remove workspace, resource and seed records'
      - 'Retain counts, then attempt the external ledger write'
      - Permanently retire the identifier
    transition_assertion:
      state: completed
      provenance: proposed
      source:
        - 'services-platform:modules/tenants/services/deletion/tenant-purge-workflow.ts (finalize)'
        - >-
          services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
          tenant-deletion-notices.table.ts; services/deletion/*;
          docs/tenants/tenant-lifecycle-plan.md §5.
    action_evidence:
      provenance: proposed
      source:
        - 'services-platform:modules/tenants/services/deletion/tenant-purge-workflow.ts (finalize)'
        - >-
          services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
          tenant-deletion-notices.table.ts; services/deletion/*;
          docs/tenants/tenant-lifecycle-plan.md §5.
    assertion_evidence:
      provenance: proposed
      source:
        - 'services-platform:modules/tenants/services/deletion/tenant-purge-workflow.ts (finalize)'
        - >-
          services-platform at ad3f6a65: modules/tenants/db/tenant-deletion-requests.table.ts,
          tenant-deletion-notices.table.ts; services/deletion/*;
          docs/tenants/tenant-lifecycle-plan.md §5.
    binding_scope: >-
      No executable assertion is bound. The scenario specifies proposed proof and does not establish
      implemented or passing behavior.
  - id: ATS-PFM-SEC-004-25
    title: Manage a workspace retirement request with maintain workspace information and operating status
    category: interaction
    level: api
    proves:
      - BR-CAP-PFM-SEC-002-03
      - BR-CAP-PFM-SEC-004-07
    exercises:
      - CAP-PFM-SEC-004
      - CAP-PFM-SEC-002
    preconditions: A disabled active workspace is eligible for retirement.
    steps: 'Request retirement, try enabling the workspace, cancel before destruction, and read both axes.'
    expected: >-
      The enabling attempt fails; cancellation restores active lifecycle while business status
      remains disabled.
    negative: true
    data_needs: >-
      An isolated customer with two workspaces, ordinary and staff identities, and records owned by
      this run.
    bound_to: []
    provenance: proposed
    source:
      - >-
        services-platform:modules/tenants/tests/integration/services/persistence/tenants.integration.spec.js#ignores
        a lifecycle state a write input carries, rather than letting a client set the system axis
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/deletion-holds.integration.spec.js#leaves
        the tenant disabled: calling off a deletion restores nobody access
    action_evidence:
      provenance: proposed
      source:
        - >-
          services-platform:modules/tenants/tests/integration/services/persistence/tenants.integration.spec.js#ignores
          a lifecycle state a write input carries, rather than letting a client set the system axis
        - >-
          services-platform:modules/tenants/tests/integration/services/deletion/deletion-holds.integration.spec.js#leaves
          the tenant disabled: calling off a deletion restores nobody access
    assertion_evidence:
      provenance: proposed
      source:
        - >-
          services-platform:modules/tenants/tests/integration/services/persistence/tenants.integration.spec.js#ignores
          a lifecycle state a write input carries, rather than letting a client set the system axis
        - >-
          services-platform:modules/tenants/tests/integration/services/deletion/deletion-holds.integration.spec.js#leaves
          the tenant disabled: calling off a deletion restores nobody access
    binding_scope: >-
      No executable assertion is bound. The scenario specifies proposed proof and does not establish
      implemented or passing behavior.
  - id: ATS-PFM-SEC-004-26
    title: Manage a workspace retirement request with prepare a workspace for customer use
    category: interaction
    level: api
    proves:
      - BR-CAP-PFM-SEC-003-05
      - BR-CAP-PFM-SEC-004-02
    exercises:
      - CAP-PFM-SEC-004
      - CAP-PFM-SEC-003
    preconditions: A failed setup has a disabled workspace and completed participant work.
    steps: >-
      Request retirement instead of retrying setup, then attempt a setup retry against the pending
      retirement.
    expected: Retirement owns the lifecycle and setup cannot reactivate the workspace.
    negative: true
    data_needs: >-
      An isolated customer with two workspaces, ordinary and staff identities, and records owned by
      this run.
    bound_to: []
    provenance: proposed
    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
      - >-
        services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
        a tenant that is still live, because people must lose access first
    action_evidence:
      provenance: proposed
      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
        - >-
          services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
          a tenant that is still live, because people must lose access first
    assertion_evidence:
      provenance: proposed
      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
        - >-
          services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
          a tenant that is still live, because people must lose access first
    binding_scope: >-
      No executable assertion is bound. The scenario specifies proposed proof and does not establish
      implemented or passing behavior.
evidence:
  - >-
    Pinned services-platform references for the structured rows:
    modules/tenants/tests/e2e/tenant-deletion-recovery.e2e.spec.js;
    modules/tenants/tests/e2e/tenant-deletion-requests.e2e.spec.js;
    modules/tenants/tests/integration/services/deletion/begin-destruction.integration.spec.js;
    modules/tenants/tests/integration/services/deletion/deletion-holds.integration.spec.js;
    modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js;
    modules/tenants/tests/integration/services/deletion/tenant-deletion-schedule.integration.spec.js;
    modules/tenants/tests/integration/services/deletion/tenant-purge-recovery.integration.spec.js;
    modules/tenants/tests/integration/services/persistence/tenant-deletion-requests.integration.spec.js.
  - >-
    Testing back-fill reviews the pinned suite assertions, related capabilities, domain invariants,
    state transitions and workflow failure boundaries. New unbound rows remain proposed.
coverage:
  rule: 'gap: FND-PFM-SEC-061'
  transition: 'gap: FND-PFM-SEC-061'
  validation: covered
  permission: covered
  edge: 'gap: FND-PFM-SEC-061'
  failure: covered
  boundary: covered
  concurrency: covered
  invariant: covered
  interaction: covered
coverage_notes:
  rule: No scenario isolates this category. The referenced finding retains the missing design proof.
  edge: No scenario isolates this category. The referenced finding retains the missing design proof.
  transition: >-
    Some declared transitions have no observed writer. Those edges remain findings rather than
    executable guarantees.
invariant_proofs:
  - scenario: ATS-PFM-SEC-004-03
    proves:
      - INV-DOM-PFM-SEC-002-08
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#refuses
      a second request, naming the one that is open
    proof_scope: >-
      Only the cited assertions support this invariant mapping; a source reference does not
      establish a passing execution.
  - scenario: ATS-PFM-SEC-004-06
    proves:
      - INV-DOM-PFM-SEC-002-09
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/deletion/deletion-holds.integration.spec.js#refuses
      a hold with no reason worth reading
    proof_scope: >-
      Only the cited assertions support this invariant mapping; a source reference does not
      establish a passing execution.
  - scenario: ATS-PFM-SEC-004-11
    proves:
      - INV-DOM-PFM-SEC-002-01
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/deletion/request-deletion.integration.spec.js#copies
      the tenant name and customer, so the record still reads after the tenant is gone
    proof_scope: >-
      Only the cited assertions support this invariant mapping; a source reference does not
      establish a passing execution.
permission_proof_review:
  - key: platform.tenants.deletion-request
    scenario_candidates:
      - ATS-PFM-SEC-004-01
    qualification: >-
      These are candidate scenarios for the authority boundary, not an exhaustive allowed/refused
      matrix for this key. The finding retains combinations not established by the executable
      assertions.
    gap: FND-PFM-SEC-061
    provenance: inferred
    source: >-
      specs/platform/security/planning/capabilities/CAP-PFM-SEC-004-retire-a-workspace-through-a-deliberate-reversible-deletion.md
  - key: platform.tenants.deletion-hold
    scenario_candidates:
      - ATS-PFM-SEC-004-01
    qualification: >-
      These are candidate scenarios for the authority boundary, not an exhaustive allowed/refused
      matrix for this key. The finding retains combinations not established by the executable
      assertions.
    gap: FND-PFM-SEC-061
    provenance: inferred
    source: >-
      specs/platform/security/planning/capabilities/CAP-PFM-SEC-004-retire-a-workspace-through-a-deliberate-reversible-deletion.md
  - key: platform.tenants.deletion-cancel
    scenario_candidates:
      - ATS-PFM-SEC-004-01
    qualification: >-
      These are candidate scenarios for the authority boundary, not an exhaustive allowed/refused
      matrix for this key. The finding retains combinations not established by the executable
      assertions.
    gap: FND-PFM-SEC-061
    provenance: inferred
    source: >-
      specs/platform/security/planning/capabilities/CAP-PFM-SEC-004-retire-a-workspace-through-a-deliberate-reversible-deletion.md
  - key: platform.tenants.deletion-read
    scenario_candidates:
      - ATS-PFM-SEC-004-01
    qualification: >-
      These are candidate scenarios for the authority boundary, not an exhaustive allowed/refused
      matrix for this key. The finding retains combinations not established by the executable
      assertions.
    gap: FND-PFM-SEC-061
    provenance: inferred
    source: >-
      specs/platform/security/planning/capabilities/CAP-PFM-SEC-004-retire-a-workspace-through-a-deliberate-reversible-deletion.md
examiner: codex
examined_at: '2026-10-23'
final_text: OpenAI
---
# Manage a workspace retirement request: Capability Test Specification

## Coverage

| Required rule | Scenario or finding |
|---|---|
| `BR-CAP-PFM-SEC-004-01` | `ATS-PFM-SEC-004-01` |
| `BR-CAP-PFM-SEC-004-02` | `ATS-PFM-SEC-004-02`, `ATS-PFM-SEC-004-12`, `ATS-PFM-SEC-004-13`, `ATS-PFM-SEC-004-26` |
| `BR-CAP-PFM-SEC-004-03` | `ATS-PFM-SEC-004-03` |
| `BR-CAP-PFM-SEC-004-04` | `ATS-PFM-SEC-004-04` |
| `BR-CAP-PFM-SEC-004-05` | `ATS-PFM-SEC-004-05` |
| `BR-CAP-PFM-SEC-004-06` | `ATS-PFM-SEC-004-06`, `ATS-PFM-SEC-004-17`, `ATS-PFM-SEC-004-18` |
| `BR-CAP-PFM-SEC-004-07` | `ATS-PFM-SEC-004-07`, `ATS-PFM-SEC-004-14`, `ATS-PFM-SEC-004-19`, `ATS-PFM-SEC-004-20`, `ATS-PFM-SEC-004-25` |
| `BR-CAP-PFM-SEC-004-08` | `ATS-PFM-SEC-004-08`, `ATS-PFM-SEC-004-15`, `ATS-PFM-SEC-004-21` |
| `BR-CAP-PFM-SEC-004-09` | `ATS-PFM-SEC-004-09` |
| `BR-CAP-PFM-SEC-004-10` | `ATS-PFM-SEC-004-10`, `ATS-PFM-SEC-004-16`, `ATS-PFM-SEC-004-22`, `ATS-PFM-SEC-004-23` |
| `BR-CAP-PFM-SEC-004-11` | `ATS-PFM-SEC-004-11`, `ATS-PFM-SEC-004-24` |
| `BR-CAP-PFM-SEC-004-13` | no scenario: `FND-PFM-SEC-61` |

The category map records specified proof. A covered category can contain proposed scenarios; it does not mean the checks have run. The bindings identify individual executable contributions, while findings retain missing rules, permissions, transitions and assertions.

## Interactions With Related Capabilities

The interaction scenarios connect this capability to the related actions and workflow handoffs named in their proof references. Each case observes the outcome after the connected action changes records or available authority. A collection of separately bound checks does not establish an ordered feature journey.

Source revisions and assertion references are recorded in frontmatter. Steps and expected observations carry separate evidence annotations. Proposed checks remain distinct from executable test statements, and static review supplies no run result.
