---
id: ATS-CRM-ACT-012
scope: CAP-CRM-ACT-012
product_area: crm
module: activities-tasks
revision: 3
status: proposed
approved_by: null
approved_at: null
source_sha:
  services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
  rhythm-v2-docs: 18a49edf30ee6bda18b159b65a2b91e093ea713d
scenarios:
- id: ATS-CRM-ACT-012-01
  title: Attribute assignment once for an unchanged holder
  level: api
  proves:
  - BR-CAP-CRM-ACT-012-01
  preconditions: An open task can be assigned.
  steps: Assign a colleague, repeat that holder and clear assignment.
  expected: The first assignment stamps persist until clearing removes them.
  negative: false
  data_needs: Each run creates and isolates the records it needs.
  bound_to:
  - services-crm:modules/tasks/tests/e2e/tasks.e2e.spec.js#stamps who holds the task, who gave it to them
    and when
  - services-crm:modules/tasks/tests/e2e/tasks.e2e.spec.js#takes it back when the assignment names nobody,
    clearing the stamps with it
  - services-crm:modules/tasks/tests/integration/services/persistence/tasks.integration.spec.js#keeps
    the first stamp when the task is handed to the person who already holds it
  - services-crm:modules/tasks/tests/integration/db/tasks.table.integration.spec.js#refuses an assignee
    with no stamp, so “who gave me this?” always has an answer
  - TST-CRM-ACT-015
  - TST-CRM-ACT-025
  - TST-CRM-ACT-017
  provenance: test
  source: services-crm:modules/tasks/tests/e2e/tasks.e2e.spec.js#stamps who holds the task, who gave it
    to them and when
  category: invariant
  binding_scope: Each registered suite contributes the assertions named by the retained file bindings;
    a compound scenario can require several suites. Conformance remains unverified.
- id: ATS-CRM-ACT-012-02
  title: Preserve and reset queue arrival at the appropriate times
  level: api
  proves:
  - BR-CAP-CRM-ACT-012-02
  - BR-CAP-CRM-ACT-012-03
  preconditions: Two queues are available.
  steps: Queue a task, edit it, move queues and remove its queue.
  expected: Edit preserves arrival, movement resets it and removal clears it.
  negative: false
  data_needs: Each run creates and isolates the records it needs.
  bound_to:
  - services-crm:modules/tasks/tests/integration/services/persistence/tasks.integration.spec.js#moves
    a task to another queue and re-stamps when it entered, so it joins the back of that one
  - services-crm:modules/tasks/tests/integration/services/persistence/tasks.integration.spec.js#clears
    the queue the replacement did not state, and the moment it entered it with it
  - services-crm:modules/tasks/tests/integration/db/tasks.table.integration.spec.js#refuses a queue with
    no moment, so no task sits in a queue in no order
  - services-crm:modules/tasks/tests/integration/db/tasks.table.integration.spec.js#refuses a moment with
    no queue
  - react-console:acceptance/crm/playwright/journeys/cross-application/CRM-ACC-0709.spec.ts#CRM-ACC-0709
  - TST-CRM-ACT-025
  - TST-CRM-ACT-017
  - TST-CRM-ACT-053
  provenance: test
  source: services-crm:modules/tasks/tests/integration/services/persistence/tasks.integration.spec.js#moves
    a task to another queue and re-stamps when it entered, so it joins the back of that one
  category: transition
  binding_scope: Each registered suite contributes the assertions named by the retained file bindings;
    a compound scenario can require several suites. Conformance remains unverified.
- id: ATS-CRM-ACT-012-03
  title: Reject assignment changes on closed work
  level: api
  proves:
  - BR-CAP-CRM-ACT-012-04
  preconditions: The task is completed.
  steps: Assign it to a different colleague.
  expected: The service requests reopening before reassignment.
  negative: true
  data_needs: Each run creates and isolates the records it needs.
  bound_to:
  - services-crm:modules/tasks/tests/integration/services/persistence/tasks.integration.spec.js#refuses
    an assignment of a closed task, asking for the reopen first
  - TST-CRM-ACT-025
  provenance: test
  source: services-crm:modules/tasks/tests/integration/services/persistence/tasks.integration.spec.js#refuses
    an assignment of a closed task, asking for the reopen first
  category: failure
  binding_scope: Each registered suite contributes the assertions named by the retained file bindings;
    a compound scenario can require several suites. Conformance remains unverified.
- id: ATS-CRM-ACT-012-04
  title: Reject invalid or service holders
  level: api
  proves:
  - BR-CAP-CRM-ACT-012-06
  preconditions: An open task accepts user assignment.
  steps: Supply malformed user and service-principal references.
  expected: Both are rejected against the holder field.
  negative: true
  data_needs: Each run creates and isolates the records it needs.
  bound_to:
  - services-crm:modules/tasks/tests/e2e/tasks.e2e.spec.js#answers 400 for an assignee that is not a Rhythm
    user id
  - services-crm:modules/tasks/tests/integration/services/persistence/tasks.integration.spec.js#refuses
    an assignee that is not a Rhythm user id
  - 'services-crm:modules/tasks/tests/integration/db/tasks.table.integration.spec.js#refuses a service
    principal as the assignee: a service never holds a task'
  - TST-CRM-ACT-015
  - TST-CRM-ACT-025
  - TST-CRM-ACT-017
  provenance: test
  source: services-crm:modules/tasks/tests/e2e/tasks.e2e.spec.js#answers 400 for an assignee that is not
    a Rhythm user id
  category: validation
  binding_scope: Each registered suite contributes the assertions named by the retained file bindings;
    a compound scenario can require several suites. Conformance remains unverified.
- id: ATS-CRM-ACT-012-05
  title: Require Platform eligibility before assigning work
  level: api
  proves:
  - BR-CAP-CRM-ACT-012-07
  preconditions: A foreign-customer user and removed colleague are available.
  steps: Attempt assignment to each.
  expected: The proposed contract refuses ineligible holders; current code accepts valid-looking references.
  negative: true
  data_needs: Each run creates and isolates the records it needs.
  bound_to: []
  provenance: proposed
  source: react-console:acceptance/crm/playwright/journeys/cross-application/CRM-ACC-0711.spec.ts#CRM-ACC-0711
  category: validation
- id: ATS-CRM-ACT-012-06
  title: Reserve queued work for one concurrent claimant
  level: api
  proves:
  - BR-CAP-CRM-ACT-012-08
  preconditions: An open queued task has no holder.
  steps: Race three users and also race duplicate requests by one user.
  expected: One assignment and version increment occur; unsuccessful requests identify the holder.
  negative: true
  data_needs: Each run creates and isolates the records it needs.
  bound_to:
  - services-crm:modules/tasks/tests/integration/services/persistence/tasks.concurrency.integration.spec.js#lets
    exactly one of them have it
  - services-crm:modules/tasks/tests/integration/services/persistence/tasks.concurrency.integration.spec.js#tells
    each of them who did get it
  - services-crm:modules/tasks/tests/integration/services/persistence/tasks.concurrency.integration.spec.js#bumps
    the version exactly once, because exactly one write happened
  - services-crm:modules/tasks/tests/integration/services/persistence/tasks.concurrency.integration.spec.js#still
    lets only one of the two statements through
  - react-console:acceptance/crm/playwright/journeys/cross-application/CRM-ACC-0710.spec.ts#CRM-ACC-0710
  - TST-CRM-ACT-024
  - TST-CRM-ACT-054
  provenance: test
  source: services-crm:modules/tasks/tests/integration/services/persistence/tasks.concurrency.integration.spec.js#lets
    exactly one of them have it
  category: concurrency
  binding_scope: Each registered suite contributes the assertions named by the retained file bindings;
    a compound scenario can require several suites. Conformance remains unverified.
- id: ATS-CRM-ACT-012-07
  title: Reject claims of ineligible task states
  level: api
  proves:
  - BR-CAP-CRM-ACT-012-09
  preconditions: Tasks are closed, fully locked or unqueued without a role offer.
  steps: Claim each task.
  expected: Each refusal explains why that work cannot be taken.
  negative: true
  data_needs: Each run creates and isolates the records it needs.
  bound_to:
  - services-crm:modules/tasks/tests/integration/services/persistence/tasks.integration.spec.js#refuses
    a task that is in no queue, saying it is assigned instead
  - services-crm:modules/tasks/tests/integration/services/persistence/tasks.integration.spec.js#refuses
    a closed task, which is nobody’s to take
  - services-crm:modules/tasks/tests/integration/services/persistence/tasks.integration.spec.js#refuses
    a task locked against updates
  - services-crm:modules/tasks/tests/e2e/tasks.e2e.spec.js#answers 409 on claiming a task that is in no
    queue, which is assigned rather than claimed
  - TST-CRM-ACT-025
  - TST-CRM-ACT-015
  provenance: test
  source: services-crm:modules/tasks/tests/integration/services/persistence/tasks.integration.spec.js#refuses
    a task that is in no queue, saying it is assigned instead
  category: validation
  binding_scope: Each registered suite contributes the assertions named by the retained file bindings;
    a compound scenario can require several suites. Conformance remains unverified.
- id: ATS-CRM-ACT-012-08
  title: Release without changing queue position
  level: api
  proves:
  - BR-CAP-CRM-ACT-012-10
  preconditions: A queued task has been claimed.
  steps: Release it, repeat release and let another user claim.
  expected: Its position persists, duplicate release fails and the other user can take it.
  negative: true
  data_needs: Each run creates and isolates the records it needs.
  bound_to:
  - 'services-crm:modules/tasks/tests/integration/services/persistence/tasks.integration.spec.js#leaves
    the task in its queue, in the place it had: a release is not a re-queue'
  - services-crm:modules/tasks/tests/integration/services/persistence/tasks.integration.spec.js#refuses
    a task nobody holds
  - services-crm:modules/tasks/tests/integration/services/persistence/tasks.integration.spec.js#lets somebody
    else claim it afterwards
  - services-crm:modules/tasks/tests/integration/services/persistence/tasks.concurrency.integration.spec.js#lets
    exactly one release happen
  - services-crm:modules/tasks/tests/e2e/tasks.e2e.spec.js#keeps the task in its queue after the release,
    at the place it was queued
  - TST-CRM-ACT-025
  - TST-CRM-ACT-024
  - TST-CRM-ACT-015
  provenance: test
  source: 'services-crm:modules/tasks/tests/integration/services/persistence/tasks.integration.spec.js#leaves
    the task in its queue, in the place it had: a release is not a re-queue'
  category: transition
  binding_scope: Each registered suite contributes the assertions named by the retained file bindings;
    a compound scenario can require several suites. Conformance remains unverified.
- id: ATS-CRM-ACT-012-09
  title: Keep inactive queues available to existing claim behavior
  level: browser
  proves:
  - BR-CAP-CRM-ACT-012-12
  preconditions: A queue has been deactivated.
  steps: Claim its waiting work and create new work naming it.
  expected: Both remain supported by current code; retirement refusal needs a product decision.
  negative: false
  data_needs: Each run creates and isolates the records it needs.
  bound_to:
  - react-console:acceptance/crm/playwright/journeys/cross-application/CRM-ACC-0710.spec.ts#CRM-ACC-0710
  - TST-CRM-ACT-054
  provenance: test
  source: react-console:acceptance/crm/playwright/journeys/cross-application/CRM-ACC-0710.spec.ts#CRM-ACC-0710
  category: edge
  binding_scope: Each registered suite contributes the assertions named by the retained file bindings;
    a compound scenario can require several suites. Conformance remains unverified.
- id: ATS-CRM-ACT-012-10
  title: Shared claims change the overdue audience while preserving role routing
  category: interaction
  level: api
  proves:
  - BR-CAP-CRM-ACT-012-10
  - BR-CAP-CRM-ACT-013-04
  - BR-CAP-CRM-ACT-015-02
  preconditions: Publishing is enabled; overdue work carries a queue and a candidate role.
  steps: Claim as an updater who does not hold the role, inspect audience, release and inspect routing
    and attention again.
  expected: The queue permits the claim, the item addresses the holder, and release retains queue arrival
    and role while restoring the shared audience.
  negative: false
  data_needs: Run-owned records in an isolated workspace; fixed clock for calendar checks.
  bound_to: []
  provenance: proposed
  source: 'services-crm:modules/tasks/tests/integration/services/persistence/tasks.integration.spec.js#leaves
    the task in its queue, in the place it had: a release is not a re-queue; services-crm:modules/tasks/tests/integration/services/persistence/tasks.role-claim.integration.spec.js#keeps
    the candidate role, so the task is offered again; services-crm:modules/tasks/tests/integration/services/persistence/task-attention-items.integration.spec.js#addresses
    a queued task nobody holds to the task queue responsibility at its queue'
  exercises:
  - CAP-CRM-ACT-012
  - CAP-CRM-ACT-013
  - CAP-CRM-ACT-015
  related:
  - CAP-CRM-ACT-013
  - CAP-CRM-ACT-015
- id: ATS-CRM-ACT-012-11
  title: Persist task routing from Unrouted to Held
  category: transition
  level: api
  proves:
  - INV-DOM-CRM-ACT-003-03
  - INV-DOM-CRM-ACT-003-04
  - INV-DOM-CRM-ACT-003-05
  - INV-DOM-CRM-ACT-003-06
  preconditions: Run-owned task routing has Unrouted standing. The task is unfinished, updates are unlocked
    and the user reference has the accepted syntax.
  steps: Assign a user directly, including through ordinary editing. Read the resulting record and affected
    projections after commit.
  expected: The resulting task routing has Held standing. Set holder and assignment attribution; enabled
    attention updates its audience.
  negative: false
  data_needs: Run-owned records in an isolated workspace; fixed clock for calendar checks.
  bound_to: []
  provenance: proposed
  source: services-crm:modules/tasks/tests/e2e/tasks.e2e.spec.js#stamps who holds the task, who gave it
    to them and when
  state_model: STATE-CRM-ACT-003
  transition:
    from: unrouted
    to: held
    trigger: Assign a user directly, including through ordinary editing.
- id: ATS-CRM-ACT-012-12
  title: Persist task routing from Held to Unrouted
  category: transition
  level: api
  proves:
  - INV-DOM-CRM-ACT-003-03
  - INV-DOM-CRM-ACT-003-04
  - INV-DOM-CRM-ACT-003-05
  - INV-DOM-CRM-ACT-003-06
  preconditions: Run-owned task routing has Held standing. The task is unfinished and updates are unlocked.
  steps: Clear the directly assigned user. Read the resulting record and affected projections after commit.
  expected: The resulting task routing has Unrouted standing. Remove assignment attribution; enabled attention
    falls back to workspace administrators.
  negative: false
  data_needs: Run-owned records in an isolated workspace; fixed clock for calendar checks.
  bound_to: []
  provenance: proposed
  source: services-crm:modules/tasks/services/persistence/tasks.ts:assignmentValues
  state_model: STATE-CRM-ACT-003
  transition:
    from: held
    to: unrouted
    trigger: Clear the directly assigned user.
- id: ATS-CRM-ACT-012-13
  title: Persist task routing from Unrouted to Queued waiting
  category: transition
  level: api
  proves:
  - INV-DOM-CRM-ACT-003-03
  - INV-DOM-CRM-ACT-003-04
  - INV-DOM-CRM-ACT-003-05
  - INV-DOM-CRM-ACT-003-06
  preconditions: Run-owned task routing has Unrouted standing. The queue exists locally; updates require
    unfinished and unlocked work. Inactive queues are accepted.
  steps: Place unheld work in a queue, including on creation. Read the resulting record and affected projections
    after commit.
  expected: The resulting task routing has Queued waiting standing. Record arrival at the queue and use
    queue responsibility for enabled attention.
  negative: false
  data_needs: Run-owned records in an isolated workspace; fixed clock for calendar checks.
  bound_to: []
  provenance: proposed
  source: services-crm:modules/tasks/tests/integration/services/persistence/tasks.integration.spec.js#moves
    a task to another queue and re-stamps when it entered, so it joins the back of that one
  state_model: STATE-CRM-ACT-003
  transition:
    from: unrouted
    to: queued_waiting
    trigger: Place unheld work in a queue, including on creation.
- id: ATS-CRM-ACT-012-14
  title: Persist task routing from Queued waiting to Queued claimed
  category: transition
  level: api
  proves:
  - INV-DOM-CRM-ACT-003-03
  - INV-DOM-CRM-ACT-003-04
  - INV-DOM-CRM-ACT-003-05
  - INV-DOM-CRM-ACT-003-06
  preconditions: Run-owned task routing has Queued waiting standing. The conditional write requires an
    unfinished, unlocked, queued and unheld task, and a user caller.
  steps: Claim available queued work. Read the resulting record and affected projections after commit.
  expected: The resulting task routing has Queued claimed standing. Set the caller as holder and assigner
    while retaining queue arrival.
  negative: false
  data_needs: Run-owned records in an isolated workspace; fixed clock for calendar checks.
  bound_to: []
  provenance: proposed
  source: services-crm:modules/tasks/tests/integration/services/persistence/tasks.concurrency.integration.spec.js#lets
    exactly one of them have it
  state_model: STATE-CRM-ACT-003
  transition:
    from: queued_waiting
    to: queued_claimed
    trigger: Claim available queued work.
- id: ATS-CRM-ACT-012-15
  title: Persist task routing from Queued claimed to Queued waiting
  category: transition
  level: api
  proves:
  - INV-DOM-CRM-ACT-003-03
  - INV-DOM-CRM-ACT-003-04
  - INV-DOM-CRM-ACT-003-05
  - INV-DOM-CRM-ACT-003-06
  preconditions: Run-owned task routing has Queued claimed standing. The task is unfinished, update-unlocked,
    held and queued.
  steps: Release held queued work. Read the resulting record and affected projections after commit.
  expected: The resulting task routing has Queued waiting standing. Clear holder and assignment stamps
    without changing queue arrival.
  negative: false
  data_needs: Run-owned records in an isolated workspace; fixed clock for calendar checks.
  bound_to: []
  provenance: proposed
  source: 'services-crm:modules/tasks/tests/integration/services/persistence/tasks.integration.spec.js#leaves
    the task in its queue, in the place it had: a release is not a re-queue'
  state_model: STATE-CRM-ACT-003
  transition:
    from: queued_claimed
    to: queued_waiting
    trigger: Release held queued work.
- id: ATS-CRM-ACT-012-16
  title: Persist task routing from Queued waiting to Queued claimed
  category: transition
  level: api
  proves:
  - INV-DOM-CRM-ACT-003-03
  - INV-DOM-CRM-ACT-003-04
  - INV-DOM-CRM-ACT-003-05
  - INV-DOM-CRM-ACT-003-06
  preconditions: Run-owned task routing has Queued waiting standing. The task is unfinished and updates
    are unlocked.
  steps: Assign a user while retaining the queue. Read the resulting record and affected projections after
    commit.
  expected: The resulting task routing has Queued claimed standing. Record assignment attribution without
    changing its retained queue position.
  negative: false
  data_needs: Run-owned records in an isolated workspace; fixed clock for calendar checks.
  bound_to: []
  provenance: proposed
  source: services-crm:modules/tasks/services/persistence/tasks.ts:assignTask
  state_model: STATE-CRM-ACT-003
  transition:
    from: queued_waiting
    to: queued_claimed
    trigger: Assign a user while retaining the queue.
- id: ATS-CRM-ACT-012-17
  title: Persist task routing from Held to Queued claimed
  category: transition
  level: api
  proves:
  - INV-DOM-CRM-ACT-003-03
  - INV-DOM-CRM-ACT-003-04
  - INV-DOM-CRM-ACT-003-05
  - INV-DOM-CRM-ACT-003-06
  preconditions: Run-owned task routing has Held standing. The task is unfinished, unlocked and references
    a local queue.
  steps: Add a queue while retaining the holder. Read the resulting record and affected projections after
    commit.
  expected: The resulting task routing has Queued claimed standing. Stamp arrival in the newly selected
    queue.
  negative: false
  data_needs: Run-owned records in an isolated workspace; fixed clock for calendar checks.
  bound_to: []
  provenance: proposed
  source: services-crm:modules/tasks/services/persistence/tasks.ts:queueValues
  state_model: STATE-CRM-ACT-003
  transition:
    from: held
    to: queued_claimed
    trigger: Add a queue while retaining the holder.
evidence:
- 'services-crm at a8d1364f1dd44b723bb5f9acba12f983e9ec8d69: scenario sources, executable assertions and
  local dependency boundaries are inspected.'
- 'react-console at baf6dae382d6f41dce976c7f848667ccc37e076f: scoped component tests and browser journey
  assertions are inspected.'
coverage:
  rule: 'gap: FND-CRM-ACT-058'
  transition: covered
  validation: covered
  permission: 'gap: FND-CRM-ACT-058'
  edge: covered
  failure: covered
  boundary: 'gap: FND-CRM-ACT-058'
  concurrency: covered
  invariant: covered
  interaction: covered
coverage_obligations:
  finding: FND-CRM-ACT-058
  unproved_rules:
  - BR-CAP-CRM-ACT-012-05
  permission_matrix:
    keys:
    - crm.tasks.update
    remaining: Complete allow/refuse combinations, including each console guard and each API operation.
  execution_note: Covered means a scenario is specified; it does not mean that scenario has executed or
    every variant has an executable binding.
related_coverage:
- capability: CAP-CRM-ACT-013
  scenarios:
  - ATS-CRM-ACT-012-10
  finding: FND-CRM-ACT-058
- capability: CAP-CRM-ACT-015
  scenarios:
  - ATS-CRM-ACT-012-10
  finding: FND-CRM-ACT-058
permission_coverage:
- key: crm.tasks.update
  finding: FND-CRM-ACT-058
  note: The finding covers unproved operation and surface combinations; a permission-category scenario
    is not a complete permission matrix.
---

# Assign shared work and claim it from a queue: Capability Test Specification

## Coverage

Category coverage counts specified proof. Unbound cases remain proposed; registered assertions do not establish a passing run.

| Rule | Proof Scenario Or Finding |
|---|---|
| `BR-CAP-CRM-ACT-012-01` | `ATS-CRM-ACT-012-01` |
| `BR-CAP-CRM-ACT-012-02` | `ATS-CRM-ACT-012-02` |
| `BR-CAP-CRM-ACT-012-03` | `ATS-CRM-ACT-012-02` |
| `BR-CAP-CRM-ACT-012-04` | `ATS-CRM-ACT-012-03` |
| `BR-CAP-CRM-ACT-012-05` | `FND-CRM-ACT-058` |
| `BR-CAP-CRM-ACT-012-06` | `ATS-CRM-ACT-012-04` |
| `BR-CAP-CRM-ACT-012-07` | `ATS-CRM-ACT-012-05` |
| `BR-CAP-CRM-ACT-012-08` | `ATS-CRM-ACT-012-06` |
| `BR-CAP-CRM-ACT-012-09` | `ATS-CRM-ACT-012-07` |
| `BR-CAP-CRM-ACT-012-10` | `ATS-CRM-ACT-012-08`, `ATS-CRM-ACT-012-10` |
| `BR-CAP-CRM-ACT-012-12` | `ATS-CRM-ACT-012-09` |

## Interactions With Related Capabilities

Publishing is enabled; overdue work carries a queue and a candidate role. Claim as an updater who does not hold the role, inspect audience, release and inspect routing and attention again.

The interaction scenario names the capabilities and rules it exercises. The coverage finding retains incomplete permission combinations and failure variants.
