---
id: CAP-CRM-ACT-012
title: Assign shared work and claim it from a queue
feature: FEAT-CRM-ACT-03
product_area: crm
module: activities-tasks
revision: 2
status: draft
product_intent: proposed
implementation_evidence: inconsistent
supersedes:
  - react-console acceptance inventory CAP-CRM-ACT-012
source_sha:
  services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
intent_sources:
  - 'services-crm:docs/milestones/CRM-M8-activities-and-tasks.md#E-10'
purpose: Teams route tasks and reserve shared work for one person at a time.
outcomes:
  - Attributable assignment
  - One successful claimant for queued work
  - Queue position retained on release
concepts:
  - CON-CRM-ACT-003
actors:
  - ACT-CRM-001
  - ACT-CRM-006
surfaces:
  - console
  - api
preconditions:
  - The task remains open and permits updates.
postconditions: []
permissions:
  - key: crm.tasks.update
    where_checked: api
    scope: tenant
  - key: crm.tasks.update
    where_checked: console
    scope: tenant
rules:
  - id: BR-CAP-CRM-ACT-012-01
    proved_by: [ATS-CRM-ACT-010-13, ATS-CRM-ACT-012-01, TST-CRM-ACT-015, TST-CRM-ACT-017, TST-CRM-ACT-025]
    statement: >-
      Assignment records the assigning actor and time, preserves the original
      stamps when the holder is unchanged, and clears them when assignment is
      removed.
    kind: invariant
    enforced_at:
      - service
      - database
    must_prove: true
    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
    origin: none
  - id: BR-CAP-CRM-ACT-012-02
    proved_by: [ATS-CRM-ACT-012-02, TST-CRM-ACT-017, TST-CRM-ACT-025, TST-CRM-ACT-053]
    statement: >-
      A task may have a holder, queue, both or neither, and queue membership
      carries its entry time for arrival ordering.
    kind: invariant
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      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
    origin: none
  - id: BR-CAP-CRM-ACT-012-03
    proved_by: [ATS-CRM-ACT-012-02, TST-CRM-ACT-017, TST-CRM-ACT-025, TST-CRM-ACT-053]
    statement: >-
      Changing queues records a new entry time, while edits within the same
      queue retain the earlier place.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    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
    origin: none
  - id: BR-CAP-CRM-ACT-012-04
    proved_by: [ATS-CRM-ACT-012-03, TST-CRM-ACT-025]
    statement: >-
      The assignment action can change the holder and queue together but rejects
      closed tasks.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    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
    origin: none
  - id: BR-CAP-CRM-ACT-012-05
    proved_by: []
    statement: >-
      Assignments reject stale versions when one is supplied; without a version,
      the last assignment takes effect.
    kind: validation
    enforced_at:
      - api
      - service
    must_prove: true
    provenance: test
    source: >-
      services-crm:modules/tasks/tests/e2e/tasks.e2e.spec.js#answers 409 for an
      assignment at a version the task has moved past
    origin: none
  - id: BR-CAP-CRM-ACT-012-06
    proved_by: [ATS-CRM-ACT-012-04, TST-CRM-ACT-015, TST-CRM-ACT-017, TST-CRM-ACT-025]
    statement: >-
      A holder must have a valid Rhythm user identifier, and a service principal
      cannot hold work.
    kind: validation
    enforced_at:
      - api
      - service
      - database
    must_prove: true
    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
    origin: none
  - id: BR-CAP-CRM-ACT-012-07
    proved_by: [ATS-CRM-ACT-012-05]
    statement: >-
      The product should check workspace membership and task eligibility with
      Platform; assignment currently validates identifier syntax only.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      react-console:acceptance/crm/playwright/journeys/cross-application/CRM-ACC-0711.spec.ts#CRM-ACC-0711
    origin: 'services-crm:docs/milestones/CRM-M8-activities-and-tasks.md#E-10'
    note: Implementation still lacks the recorded Platform eligibility requirement.
  - id: BR-CAP-CRM-ACT-012-08
    proved_by: [ATS-CRM-ACT-012-06, TST-CRM-ACT-024, TST-CRM-ACT-054]
    statement: >-
      A queued open task without a holder can be claimed, and simultaneous
      attempts produce one winner with the others informed of the holder.
    kind: invariant
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-crm:modules/tasks/tests/integration/services/persistence/tasks.concurrency.integration.spec.js#lets
      exactly one of them have it
    origin: none
  - id: BR-CAP-CRM-ACT-012-09
    proved_by: [ATS-CRM-ACT-012-07, TST-CRM-ACT-015, TST-CRM-ACT-025]
    statement: >-
      An unqueued task with no role offer must be assigned; claims are rejected
      for closed tasks and full update locks.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    provenance: observed
    source: 'services-crm:modules/tasks/services/persistence/tasks.ts:claimTask'
    origin: none
  - id: BR-CAP-CRM-ACT-012-10
    proved_by: [ATS-CRM-ACT-012-08, ATS-CRM-ACT-012-10, ATS-CRM-ACT-013-07, TST-CRM-ACT-015, TST-CRM-ACT-024, TST-CRM-ACT-025]
    statement: >-
      Release clears the holder while preserving the queue position, is
      available to any caller with update authority, and rejects a task with no
      holder.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    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
    origin: none
  - id: BR-CAP-CRM-ACT-012-11
    proved_by: []
    statement: >-
      Claim requires a signed-in user, while release can be performed by an
      authorized service because it sets no new holder.
    kind: permission
    enforced_at:
      - service
    must_prove: false
    provenance: test
    source: >-
      services-crm:modules/tasks/tests/integration/services/persistence/tasks.integration.spec.js#is
      refused a claim
    origin: none
  - id: BR-CAP-CRM-ACT-012-12
    proved_by: [ATS-CRM-ACT-012-09, ATS-CRM-ACT-016-09, TST-CRM-ACT-054]
    statement: Inactive queues still permit task creation and claims.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      react-console:acceptance/crm/playwright/journeys/cross-application/CRM-ACC-0710.spec.ts#CRM-ACC-0710
    origin: none
    note: >-
      The finding preserves the difference between observed behavior and the
      earlier acceptance or product expectation.
  - id: BR-CAP-CRM-ACT-012-13
    proved_by: []
    statement: >-
      The console shows Claim for open unassigned queued work and Release for
      open assigned queued work, subject to task update permission.
    kind: permission
    enforced_at:
      - console
    must_prove: false
    provenance: test
    source: >-
      react-console:lib/tasks/types.test.ts#is offered on an open task waiting
      unclaimed in a queue
    origin: none
scenarios:
  - id: SC-CAP-CRM-ACT-012-01
    given: Membership services has two waiting tasks.
    when: 'Claim the earlier task, release it and claim it again.'
    then: Its queue entry position does not change.
    provenance: test
    source: >-
      react-console:acceptance/crm/playwright/journeys/cross-application/CRM-ACC-0709.spec.ts#CRM-ACC-0709
  - id: SC-CAP-CRM-ACT-012-02
    given: Three workers target the same queued task.
    when: Deliver their claims concurrently.
    then: One worker becomes holder and the other attempts identify that holder.
    provenance: test
    source: >-
      react-console:acceptance/crm/playwright/journeys/cross-application/CRM-ACC-0710.spec.ts#CRM-ACC-0710
edge_cases:
  - id: SC-CAP-CRM-ACT-012-03
    given: A valid-looking user reference belongs to another customer.
    when: Assign a task to that reference.
    then: >-
      Assignment succeeds despite selector exclusion, and no holder display name
      is resolved.
    provenance: test
    source: >-
      react-console:acceptance/crm/playwright/journeys/cross-application/CRM-ACC-0711.spec.ts#CRM-ACC-0711
constraints: []
depends_on:
  - CAP-CRM-ACT-010
  - CAP-CRM-ACT-016
related:
  - CAP-CRM-ACT-013
  - CAP-CRM-ACT-015
journeys:
  - JNY-CRM-ACT-003
open_questions:
  - OQ-CRM-ACT-003
evidence:
  - >-
    services-crm at a8d1364f1dd44b723bb5f9acba12f983e9ec8d69: Independently
    reviewed declarations, behavior and assertions identified in this
    capability’s row citations.
  - >-
    react-console at baf6dae382d6f41dce976c7f848667ccc37e076f: Independently
    reviewed declarations, behavior and assertions identified in this
    capability’s row citations.
controls: [TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-AZ-006, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-LOG-001, TC-LOG-002, TC-LOG-003, TC-LOG-004, TC-LOG-005, TC-PI-001, TC-PI-002, TC-PI-003, TC-PI-005, TC-PRV-001, TC-PRV-002, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-TEN-004]
exercised_by: [FAS-CRM-ACT-03-01, FAS-CRM-ACT-03-02, FAS-CRM-ACT-03-04, FAS-CRM-ACT-03-05, FAS-CRM-ACT-04-02, FAS-CRM-ACT-04-06]
suites: [TST-CRM-ACT-015, TST-CRM-ACT-017, TST-CRM-ACT-024, TST-CRM-ACT-025, TST-CRM-ACT-053, TST-CRM-ACT-054]
---

# Assign shared work and claim it from a queue

## Purpose

Teams route tasks and reserve shared work for one person at a time.

## How It Works

A coordinator assigns work to a colleague or places it in a queue. Queue entry gives the task an arrival position. A worker can claim an unassigned open task from that queue. Simultaneous claims leave one successful holder. Release removes the holder without moving the task to the back. Moving the task to another queue establishes a new arrival position there. Closed work must be reopened before assignment changes. Assignment checks user identifier syntax but does not yet confirm workspace eligibility. The product should implement the recorded eligibility requirement. Inactive queues continue accepting work until Product settles their retirement behavior.

## Relationships

- Task configuration defines the available queues.
- The Tasks screen presents queue views and claim controls.
- Overdue attention uses queue responsibility for unclaimed work.
