---
id: ATS-CRM-ACT-017
scope: CAP-CRM-ACT-017
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-017-01
  title: Keep task service access restricted to registered callers
  level: api
  proves:
  - BR-CAP-CRM-ACT-017-01
  preconditions: A console context and unknown service principal are available.
  steps: Invoke the task service with each.
  expected: Both are rejected and no task is created.
  negative: true
  data_needs: Each run creates and isolates the records it needs.
  bound_to:
  - services-crm:modules/tasks/tests/e2e/tasks-service.e2e.spec.js#answers 403 context_mismatch to a console
    caller reaching the route over HTTP, whatever its keys
  - services-crm:modules/tasks/tests/e2e/tasks-service.e2e.spec.js#creates nothing for that console caller
  - services-crm:modules/tasks/tests/e2e/tasks-service.e2e.spec.js#answers 403 to a principal Rhythm does
    not know
  - TST-CRM-ACT-014
  provenance: test
  source: services-crm:modules/tasks/tests/e2e/tasks-service.e2e.spec.js#answers 403 context_mismatch
    to a console caller reaching the route over HTTP, whatever its keys
  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-017-02
  title: Deduplicate a workflow creation step
  level: api
  proves:
  - BR-CAP-CRM-ACT-017-03
  preconditions: A workflow step supplies its creation reference.
  steps: Repeat and race creation deliveries.
  expected: One task exists and exactly one delivery reports creation.
  negative: true
  data_needs: Each run creates and isolates the records it needs.
  bound_to:
  - 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/workflow-actions/task-service-operations.integration.spec.js#says
    the first delivery created the task and the repeat did not
  - services-crm:modules/tasks/tests/integration/services/workflow-actions/task-service-operations.integration.spec.js#says
    exactly one delivery created it, and the two losers did not
  - services-crm:modules/tasks/tests/integration/services/persistence/tasks.concurrency.integration.spec.js#creates
    exactly one task of that action run
  - services-crm:modules/tasks/tests/e2e/tasks-service.e2e.spec.js#tells exactly one delivery it created
    the task, and the two losers they did not
  - TST-CRM-ACT-029
  - TST-CRM-ACT-024
  - TST-CRM-ACT-014
  provenance: test
  source: services-crm:modules/tasks/tests/integration/services/workflow-actions/task-service-operations.integration.spec.js#answers
    the repeat with the same task
  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-017-03
  title: Avoid a second write when the requested state already holds
  level: api
  proves:
  - BR-CAP-CRM-ACT-017-04
  preconditions: Workflow-created tasks cover each supported action.
  steps: Repeat closing, reassignment and due-day actions without intervening changes.
  expected: The second delivery preserves the record and version.
  negative: true
  data_needs: Each run creates and isolates the records it needs.
  bound_to:
  - services-crm:modules/tasks/tests/integration/services/workflow-actions/task-service-operations.integration.spec.js#answers
    the repeat with the task as it is, writing nothing
  - services-crm:modules/tasks/tests/integration/services/persistence/tasks.workflow-actions.integration.spec.js#answers
    a completed task as it is, writing nothing, when asked again idempotently
  - services-crm:modules/tasks/tests/e2e/tasks-service.e2e.spec.js#bumped each task once per change and
    never on a repeat
  - TST-CRM-ACT-029
  - TST-CRM-ACT-028
  - TST-CRM-ACT-014
  provenance: test
  source: services-crm:modules/tasks/tests/integration/services/workflow-actions/task-service-operations.integration.spec.js#answers
    the repeat with the task as it is, writing nothing
  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-017-04
  title: Return specific refusals for inapplicable workflow actions
  level: api
  proves:
  - BR-CAP-CRM-ACT-017-05
  preconditions: Tasks are completed, cancelled or fully locked.
  steps: Attempt incompatible closure, reassignment and redating.
  expected: The service returns the relevant problem codes without changing them.
  negative: true
  data_needs: Each run creates and isolates the records it needs.
  bound_to:
  - services-crm:modules/tasks/tests/integration/services/workflow-actions/task-service-operations.integration.spec.js#names
    the refusal to complete a cancelled task task_closed_otherwise
  - services-crm:modules/tasks/tests/integration/services/workflow-actions/task-service-operations.integration.spec.js#refuses
    to cancel a task a person completed (409 task_closed_otherwise), leaving it completed
  - services-crm:modules/tasks/tests/integration/services/workflow-actions/task-service-operations.integration.spec.js#refuses
    to complete a task locked against updates (409 task_locked), leaving it open
  - services-crm:modules/tasks/tests/integration/services/workflow-actions/task-service-operations.integration.spec.js#refuses
    to reassign a completed task (409 task_closed)
  - services-crm:modules/tasks/tests/integration/services/workflow-actions/task-service-operations.integration.spec.js#refuses
    to re-date a cancelled task (409 task_closed)
  - TST-CRM-ACT-029
  provenance: test
  source: services-crm:modules/tasks/tests/integration/services/workflow-actions/task-service-operations.integration.spec.js#names
    the refusal to complete a cancelled task task_closed_otherwise
  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-017-05
  title: Require agreement between task addressing forms
  level: api
  proves:
  - BR-CAP-CRM-ACT-017-06
  preconditions: Two tasks have distinct workflow creation references.
  steps: Address one by task reference and the other by creation reference, then use an unknown creation
    reference.
  expected: Disagreement fails without writes and the unknown creation is Not Found.
  negative: true
  data_needs: Each run creates and isolates the records it needs.
  bound_to:
  - services-crm:modules/tasks/tests/integration/services/workflow-actions/task-service-operations.integration.spec.js#refuses
    an id and a run that name two different tasks (400), and changes neither
  - services-crm:modules/tasks/tests/integration/services/workflow-actions/task-service-operations.integration.spec.js#refuses
    a run that created no task of the tenant (404)
  - services-crm:modules/tasks/tests/e2e/tasks-service.e2e.spec.js#answers 400 for an operation that names
    no task
  - TST-CRM-ACT-029
  - TST-CRM-ACT-014
  provenance: test
  source: services-crm:modules/tasks/tests/integration/services/workflow-actions/task-service-operations.integration.spec.js#refuses
    an id and a run that name two different tasks (400), and changes neither
  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-017-06
  title: Reject duplicate holder specifications
  level: api
  proves:
  - BR-CAP-CRM-ACT-017-07
  preconditions: Service creation supports either holder form.
  steps: Provide both holder forms in one create.
  expected: The API rejects the ambiguous holder request.
  negative: true
  data_needs: Each run creates and isolates the records it needs.
  bound_to:
  - services-crm:modules/tasks/tests/e2e/tasks-service.e2e.spec.js#refuses a create naming its holder
    twice, assignee and assignee_user_id, 400
  - TST-CRM-ACT-014
  provenance: test
  source: services-crm:modules/tasks/tests/e2e/tasks-service.e2e.spec.js#refuses a create naming its holder
    twice, assignee and assignee_user_id, 400
  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-017-07
  title: Require a complete cross-application subject
  level: api
  proves:
  - BR-CAP-CRM-ACT-017-09
  preconditions: Subject fixtures cover valid and malformed record-kind combinations.
  steps: Create tasks with one half missing, malformed values and a complete pair.
  expected: Incomplete or malformed subjects fail and the complete pair is retained.
  negative: true
  data_needs: Each run creates and isolates the records it needs.
  bound_to:
  - services-crm:modules/tasks/tests/integration/services/persistence/tasks.workflow-actions.integration.spec.js#refuses
    an object with no record, naming the record, and writes nothing
  - services-crm:modules/tasks/tests/integration/services/persistence/tasks.workflow-actions.integration.spec.js#refuses
    a record with no object, naming the object
  - services-crm:modules/tasks/tests/integration/services/persistence/tasks.workflow-actions.integration.spec.js#stores
    the subject and the action run as the record answered them
  - services-crm:modules/tasks/tests/integration/db/tasks.table.integration.spec.js#refuses an object
    id outside the grammar of a canonical object id
  - TST-CRM-ACT-028
  - TST-CRM-ACT-017
  provenance: test
  source: services-crm:modules/tasks/tests/integration/services/persistence/tasks.workflow-actions.integration.spec.js#refuses
    an object with no record, naming the record, and writes nothing
  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-017-08
  title: Attribute workflow writes to the service principal
  level: api
  proves:
  - BR-CAP-CRM-ACT-017-10
  preconditions: A registered service acts with an originating user.
  steps: Create and complete work.
  expected: Record stamps identify the service rather than the originating user.
  negative: false
  data_needs: Each run creates and isolates the records it needs.
  bound_to:
  - services-crm:modules/tasks/tests/integration/services/workflow-actions/task-service-operations.integration.spec.js#creates
    the task the action asked for, with the service principal as its creator and assigner
  - services-crm:modules/tasks/tests/integration/services/persistence/tasks.workflow-actions.integration.spec.js#stamps
    the service principal as the one who completed it
  - services-crm:modules/tasks/tests/integration/db/tasks.table.integration.spec.js#takes a completer
    that is a service principal
  - TST-CRM-ACT-029
  - TST-CRM-ACT-028
  - TST-CRM-ACT-017
  provenance: test
  source: services-crm:modules/tasks/tests/integration/services/workflow-actions/task-service-operations.integration.spec.js#creates
    the task the action asked for, with the service principal as its creator and assigner
  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-017-09
  title: A workflow task retains context through merge and access checks
  category: interaction
  level: api
  proves:
  - BR-CAP-CRM-ACT-017-03
  - BR-CAP-CRM-ACT-013-02
  - BR-CAP-CRM-ACT-018-07
  - BR-CAP-CRM-ACT-019-02
  preconditions: A registered service creates a role-offered task concerning a duplicate contact.
  steps: Repeat creation, merge the contact into a survivor, claim as a holder and attempt to read the
    task from another workspace.
  expected: One task follows the survivor, an eligible holder claims it, and the foreign workspace receives
    absence.
  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/workflow-actions/task-service-operations.integration.spec.js#answers
    the repeat with the same task; 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; react-console:acceptance/crm/playwright/journeys/cross-application/CRM-ACC-0720.spec.ts#CRM-ACC-0720;
    services-crm:modules/tasks/tests/integration/services/persistence/tasks.integration.spec.js#is left
    exactly as the other tenant had it, every refusal above having written nothing
  exercises:
  - CAP-CRM-ACT-017
  - CAP-CRM-ACT-013
  - CAP-CRM-ACT-018
  - CAP-CRM-ACT-019
  related:
  - CAP-CRM-ACT-013
  - CAP-CRM-ACT-018
  - CAP-CRM-ACT-019
- id: ATS-CRM-ACT-017-10
  title: Reevaluate an action after an intervening change
  category: edge
  level: api
  proves:
  - BR-CAP-CRM-ACT-017-12
  preconditions: A workflow command has completed a task.
  steps: Reopen as a person, repeat the prior completion command and inspect the new version and closing
    stamps.
  expected: The repeat evaluates the current open state and completes it again; no action-delivery ledger
    suppresses it.
  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/workflow-actions/task-service-operations.ts:runTaskServiceOperation
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-063'
  transition: 'gap: FND-CRM-ACT-063'
  validation: covered
  permission: covered
  edge: covered
  failure: covered
  boundary: 'gap: FND-CRM-ACT-063'
  concurrency: covered
  invariant: covered
  interaction: covered
coverage_obligations:
  finding: FND-CRM-ACT-063
  unproved_rules:
  - BR-CAP-CRM-ACT-017-02
  - BR-CAP-CRM-ACT-017-08
  permission_matrix:
    keys:
    - crm.tasks.create
    - 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-017-09
  finding: FND-CRM-ACT-063
permission_coverage:
- key: crm.tasks.create
  finding: FND-CRM-ACT-063
  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-063
  note: The finding covers unproved operation and surface combinations; a permission-category scenario
    is not a complete permission matrix.
---

# Create workflow tasks once and repeat actions according to state: 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-017-01` | `ATS-CRM-ACT-017-01` |
| `BR-CAP-CRM-ACT-017-02` | `FND-CRM-ACT-063` |
| `BR-CAP-CRM-ACT-017-03` | `ATS-CRM-ACT-017-02`, `ATS-CRM-ACT-017-09` |
| `BR-CAP-CRM-ACT-017-04` | `ATS-CRM-ACT-017-03` |
| `BR-CAP-CRM-ACT-017-05` | `ATS-CRM-ACT-017-04` |
| `BR-CAP-CRM-ACT-017-06` | `ATS-CRM-ACT-017-05` |
| `BR-CAP-CRM-ACT-017-07` | `ATS-CRM-ACT-017-06` |
| `BR-CAP-CRM-ACT-017-08` | `FND-CRM-ACT-063` |
| `BR-CAP-CRM-ACT-017-09` | `ATS-CRM-ACT-017-07` |
| `BR-CAP-CRM-ACT-017-10` | `ATS-CRM-ACT-017-08` |
| `BR-CAP-CRM-ACT-017-12` | `ATS-CRM-ACT-017-10` |

## Interactions With Related Capabilities

A registered service creates a role-offered task concerning a duplicate contact. Repeat creation, merge the contact into a survivor, claim as a holder and attempt to read the task from another workspace.

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