---
id: ATS-CRM-ACT-013
scope: CAP-CRM-ACT-013
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-013-01
  title: Create a role offer without a simultaneous holder
  level: api
  proves:
  - BR-CAP-CRM-ACT-013-01
  preconditions: A role has eligible users.
  steps: Create offers by custom reference and built-in key, then include both a holder and role.
  expected: Valid offers remain unassigned and the combined assignment fails.
  negative: true
  data_needs: Each run creates and isolates the records it needs.
  bound_to:
  - services-crm:modules/tasks/tests/integration/services/persistence/tasks.role-claim.integration.spec.js#stores
    the role as the candidate role and leaves the task held by nobody
  - services-crm:modules/tasks/tests/integration/services/persistence/tasks.role-claim.integration.spec.js#stores
    a built-in role by its key
  - services-crm:modules/tasks/tests/integration/services/persistence/tasks.role-claim.integration.spec.js#refuses
    a create naming both an assignee and a role, naming the field, and writes nothing
  - services-crm:modules/tasks/tests/integration/db/tasks.table.integration.spec.js#refuses a task created
    both assigned to a person and offered to a role
  - TST-CRM-ACT-027
  - TST-CRM-ACT-017
  provenance: test
  source: services-crm:modules/tasks/tests/integration/services/persistence/tasks.role-claim.integration.spec.js#stores
    the role as the candidate role and leaves the task held by nobody
  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-013-02
  title: Check role membership on unqueued claims
  level: api
  proves:
  - BR-CAP-CRM-ACT-013-02
  preconditions: An offered task and a non-holder are available.
  steps: Attempt a non-holder claim and a built-in-role holder claim.
  expected: The non-holder is forbidden while the eligible holder succeeds.
  negative: true
  data_needs: Each run creates and isolates the records it needs.
  bound_to:
  - services-crm:modules/tasks/tests/integration/services/persistence/tasks.role-claim.integration.spec.js#is
    refused 403 with the code task_claim_not_role_holder, and the task stays offered
  - 'services-crm:modules/tasks/tests/integration/services/persistence/tasks.role-claim.integration.spec.js#claims
    it: the key is resolved to the role, which the holder holds at the customer’s scope'
  - services-crm:modules/tasks/tests/e2e/tasks.e2e.spec.js#refuses a user who does not hold the role 403,
    code task_claim_not_role_holder
  - TST-CRM-ACT-027
  - TST-CRM-ACT-015
  provenance: test
  source: services-crm:modules/tasks/tests/integration/services/persistence/tasks.role-claim.integration.spec.js#is
    refused 403 with the code task_claim_not_role_holder, and the task stays offered
  category: permission
  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-013-03
  title: Select one role holder in a claim race
  level: api
  proves:
  - BR-CAP-CRM-ACT-013-03
  preconditions: Three users hold the candidate role.
  steps: Claim concurrently.
  expected: One user receives assignment and the others receive winner-specific conflicts.
  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#refuses
    the other two 409 with the code task_claimed_by_other
  - services-crm:modules/tasks/tests/e2e/tasks.e2e.spec.js#refuses the second holder 409, code task_claimed_by_other
  - TST-CRM-ACT-024
  - TST-CRM-ACT-015
  provenance: test
  source: services-crm:modules/tasks/tests/integration/services/persistence/tasks.concurrency.integration.spec.js#refuses
    the other two 409 with the code task_claimed_by_other
  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-013-04
  title: Reoffer released work and clear reassigned offers
  level: api
  proves:
  - BR-CAP-CRM-ACT-013-04
  - BR-CAP-CRM-ACT-013-05
  preconditions: A claimed task retains its candidate role.
  steps: Release it and assign a different holder.
  expected: Release preserves the offer and different-holder assignment 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.role-claim.integration.spec.js#keeps
    the candidate role, so the task is offered again
  - services-crm:modules/tasks/tests/integration/services/persistence/tasks.role-claim.integration.spec.js#clears
    the role when the task is given to somebody other than its holder
  - services-crm:modules/tasks/tests/integration/services/persistence/tasks.role-claim.integration.spec.js#keeps
    the role when the claimed task is handed back
  - 'services-crm:modules/tasks/tests/e2e/tasks.e2e.spec.js#offers the task again on a release: nobody
    holds it, the role kept'
  - TST-CRM-ACT-027
  - TST-CRM-ACT-015
  provenance: test
  source: services-crm:modules/tasks/tests/integration/services/persistence/tasks.role-claim.integration.spec.js#keeps
    the candidate role, so the task is offered again
  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-013-05
  title: Page work offered to the current role holdings
  level: api
  proves:
  - BR-CAP-CRM-ACT-013-07
  preconditions: Some role offers are unassigned and one has been claimed.
  steps: Read and paginate offered work, then request an excessive page.
  expected: Eligible unclaimed tasks appear oldest first and pages above 200 fail.
  negative: false
  data_needs: Each run creates and isolates the records it needs.
  bound_to:
  - services-crm:modules/tasks/tests/integration/services/persistence/tasks.queries.integration.spec.js#answers
    the three tasks offered to the user’s roles, oldest first, then by id
  - services-crm:modules/tasks/tests/integration/services/persistence/tasks.queries.integration.spec.js#answers
    a page at most as long as the limit, with where it ended
  - services-crm:modules/tasks/tests/integration/services/persistence/tasks.queries.integration.spec.js#answers
    an empty page for a user who holds no role
  - services-crm:modules/tasks/tests/e2e/tasks.e2e.spec.js#refuses a page longer than 200, 400
  - TST-CRM-ACT-026
  - TST-CRM-ACT-015
  provenance: test
  source: services-crm:modules/tasks/tests/integration/services/persistence/tasks.queries.integration.spec.js#answers
    the three tasks offered to the user’s roles, oldest first, then by id
  category: boundary
  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-013-06
  title: Inspect the role-offer console discovery boundary
  level: browser
  proves:
  - BR-CAP-CRM-ACT-013-09
  preconditions: An unqueued open task is offered to a role the current user holds.
  steps: Read offered work through its API and inspect the available Tasks views.
  expected: The eligible offer appears through the separate API; no offered-to-me view exists on the Tasks
    screen.
  negative: false
  data_needs: Each run creates and isolates the records it needs.
  bound_to: []
  provenance: proposed
  source: services-crm:modules/tasks/services/persistence/tasks.ts:listOfferedTasks; react-console:components/console/tasks/definition.tsx
  category: interaction
  note: The earlier proposed view expectation is corrected to the cited rule; any future view needs a
    separately approved capability change.
- id: ATS-CRM-ACT-013-07
  title: Workflow offers can be claimed and reoffered without duplicate creation
  category: interaction
  level: api
  proves:
  - BR-CAP-CRM-ACT-013-04
  - BR-CAP-CRM-ACT-017-03
  - BR-CAP-CRM-ACT-012-10
  preconditions: Two users hold the offered role.
  steps: Create through a workflow step, repeat creation, claim as one holder, release and claim as the
    other.
  expected: One task exists, release retains the candidate role and the second holder receives that same
    task.
  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.role-claim.integration.spec.js#keeps
    the candidate role, so the task is offered again; services-crm:modules/tasks/tests/integration/services/workflow-actions/task-service-operations.integration.spec.js#answers
    the repeat with the same task; 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'
  exercises:
  - CAP-CRM-ACT-013
  - CAP-CRM-ACT-017
  - CAP-CRM-ACT-012
  related:
  - CAP-CRM-ACT-017
  - CAP-CRM-ACT-012
- id: ATS-CRM-ACT-013-08
  title: Persist task routing from Unrouted to Offered
  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 role reference has valid syntax without
    an existence check; creation cannot also name a holder. A changed offer requires unfinished, unlocked
    work.
  steps: Create an offer or have the workflow service offer work to a role. Read the resulting record
    and affected projections after commit.
  expected: The resulting task routing has Offered standing. Set the candidate role and clear any existing
    holder on service reassignment.
  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.role-claim.integration.spec.js#refuses
    a create naming both an assignee and a role, naming the field, and writes nothing
  state_model: STATE-CRM-ACT-003
  transition:
    from: unrouted
    to: offered
    trigger: Create an offer or have the workflow service offer work to a role.
- id: ATS-CRM-ACT-013-09
  title: Persist task routing from Offered to Offered 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 Offered standing. The locked task is unfinished, unlocked
    and unheld, and Platform confirms current role holding for the user.
  steps: Claim available work offered only to a role. Read the resulting record and affected projections
    after commit.
  expected: The resulting task routing has Offered claimed standing. Set holder and assignment attribution
    while retaining the candidate role.
  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.role-claim.integration.spec.js#is
    refused 403 with the code task_claim_not_role_holder, and the task stays offered
  state_model: STATE-CRM-ACT-003
  transition:
    from: offered
    to: offered_claimed
    trigger: Claim available work offered only to a role.
- id: ATS-CRM-ACT-013-10
  title: Persist task routing from Offered claimed to Offered
  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 Offered claimed standing. The task is unfinished and update-unlocked;
    release additionally requires a holder.
  steps: Release role-offered work or clear its holder by assignment. Read the resulting record and affected
    projections after commit.
  expected: The resulting task routing has Offered standing. Clear assignment and retain the candidate
    role so work is offered again.
  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.role-claim.integration.spec.js#keeps
    the candidate role, so the task is offered again
  state_model: STATE-CRM-ACT-003
  transition:
    from: offered_claimed
    to: offered
    trigger: Release role-offered work or clear its holder by assignment.
- id: ATS-CRM-ACT-013-11
  title: Persist task routing from Offered claimed 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 Offered claimed standing. The task is unfinished and updates
    are unlocked.
  steps: Assign a different user to held role-offered work. Read the resulting record and affected projections
    after commit.
  expected: The resulting task routing has Held standing. Replace the holder and assignment stamps, clearing
    the candidate role.
  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.role-claim.integration.spec.js#clears
    the role when the task is given to somebody other than its holder
  state_model: STATE-CRM-ACT-003
  transition:
    from: offered_claimed
    to: held
    trigger: Assign a different user to held role-offered work.
- id: ATS-CRM-ACT-013-12
  title: Persist task routing from Queued waiting to Queued offered 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 waiting standing. A changed request requires unfinished,
    unlocked work; an already-satisfied service request returns unchanged.
  steps: Have the workflow service offer queued work to a role. Read the resulting record and affected
    projections after commit.
  expected: The resulting task routing has Queued offered waiting standing. Clear holder and assignment
    stamps, set the role and retain 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/services/persistence/tasks.ts:offerTask
  state_model: STATE-CRM-ACT-003
  transition:
    from: queued_waiting
    to: queued_offered_waiting
    trigger: Have the workflow service offer queued work to a role.
- id: ATS-CRM-ACT-013-13
  title: Persist task routing from Queued claimed to Queued offered 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. A changed request requires unfinished,
    unlocked work; an already-satisfied service request returns unchanged.
  steps: Have the workflow service replace the holder with a role offer. Read the resulting record and
    affected projections after commit.
  expected: The resulting task routing has Queued offered waiting standing. Clear holder and assignment
    stamps, set the role and retain 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/services/persistence/tasks.ts:offerTask
  state_model: STATE-CRM-ACT-003
  transition:
    from: queued_claimed
    to: queued_offered_waiting
    trigger: Have the workflow service replace the holder with a role offer.
- id: ATS-CRM-ACT-013-14
  title: Persist task routing from Queued offered waiting to Queued offered 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 offered waiting standing. A user makes a conditional
    claim of unfinished, unlocked, unheld work; role holding is not consulted.
  steps: Claim work that has both queue and role routing. Read the resulting record and affected projections
    after commit.
  expected: The resulting task routing has Queued offered claimed standing. Set the caller as holder and
    assigner; retain the queue, arrival and role.
  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:claimTask
  state_model: STATE-CRM-ACT-003
  transition:
    from: queued_offered_waiting
    to: queued_offered_claimed
    trigger: Claim work that has both queue and role routing.
- id: ATS-CRM-ACT-013-15
  title: Persist task routing from Queued offered claimed to Queued offered 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 offered claimed standing. The task is unfinished, unlocked
    and held.
  steps: Release held work that retains both routing references. Read the resulting record and affected
    projections after commit.
  expected: The resulting task routing has Queued offered waiting standing. Clear assignment stamps and
    holder while keeping queue arrival and candidate role.
  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:releaseTask
  state_model: STATE-CRM-ACT-003
  transition:
    from: queued_offered_claimed
    to: queued_offered_waiting
    trigger: Release held work that retains both routing references.
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-059'
  transition: covered
  validation: covered
  permission: covered
  edge: 'gap: FND-CRM-ACT-059'
  failure: 'gap: FND-CRM-ACT-059'
  boundary: covered
  concurrency: covered
  invariant: 'gap: FND-CRM-ACT-059'
  interaction: covered
coverage_obligations:
  finding: FND-CRM-ACT-059
  unproved_rules:
  - BR-CAP-CRM-ACT-013-10
  - BR-CAP-CRM-ACT-013-11
  - BR-CAP-CRM-ACT-013-12
  permission_matrix:
    keys:
    - crm.tasks.read
    - 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-017
  scenarios:
  - ATS-CRM-ACT-013-07
  finding: FND-CRM-ACT-059
permission_coverage:
- key: crm.tasks.read
  finding: FND-CRM-ACT-059
  note: The finding covers unproved operation and surface combinations; a permission-category scenario
    is not a complete permission matrix.
- key: crm.tasks.update
  finding: FND-CRM-ACT-059
  note: The finding covers unproved operation and surface combinations; a permission-category scenario
    is not a complete permission matrix.
---

# Offer work to a security role and reserve it by claim: 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-013-01` | `ATS-CRM-ACT-013-01` |
| `BR-CAP-CRM-ACT-013-02` | `ATS-CRM-ACT-013-02` |
| `BR-CAP-CRM-ACT-013-03` | `ATS-CRM-ACT-013-03` |
| `BR-CAP-CRM-ACT-013-04` | `ATS-CRM-ACT-013-04`, `ATS-CRM-ACT-013-07` |
| `BR-CAP-CRM-ACT-013-05` | `ATS-CRM-ACT-013-04` |
| `BR-CAP-CRM-ACT-013-07` | `ATS-CRM-ACT-013-05` |
| `BR-CAP-CRM-ACT-013-09` | `ATS-CRM-ACT-013-06` |
| `BR-CAP-CRM-ACT-013-10` | `FND-CRM-ACT-059` |
| `BR-CAP-CRM-ACT-013-11` | `FND-CRM-ACT-059` |
| `BR-CAP-CRM-ACT-013-12` | `FND-CRM-ACT-059` |

## Interactions With Related Capabilities

Two users hold the offered role. Create through a workflow step, repeat creation, claim as one holder, release and claim as the other.

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