---
id: CAP-CRM-ACT-017
title: Create workflow tasks once and repeat actions according to state
feature: FEAT-CRM-ACT-05
product_area: crm
module: activities-tasks
revision: 2
status: draft
product_intent: proposed
implementation_evidence: observed
supersedes: []
source_sha:
  services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
intent_sources:
  - 'services-crm:docs/workstreams/wa-3a-tasks-action-link.md'
purpose: >-
  Application processes delegate human work through a service contract with safe
  creation retries.
outcomes:
  - A single task for each creation step
  - Repeat responses based on task state
  - Service attribution and explicit refusals
concepts:
  - CON-CRM-ACT-003
actors:
  - ACT-CRM-007
surfaces:
  - api
  - job
preconditions:
  - >-
    The caller is a registered service with invocation authority for the tasks
    service.
postconditions: []
permissions:
  - key: crm.tasks.create
    where_checked: service
    scope: tenant
  - key: crm.tasks.update
    where_checked: service
    scope: tenant
rules:
  - id: BR-CAP-CRM-ACT-017-01
    statement: >-
      Only registered Rhythm services can invoke the tasks service directly;
      HTTP requests and unknown principals are refused.
    kind: permission
    enforced_at:
      - api
      - service
    must_prove: true
    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
    origin: none
  - id: BR-CAP-CRM-ACT-017-02
    statement: >-
      The service supports task creation, completion, cancellation,
      reassignment, role offers, due-day changes and offered-task listing.
    kind: policy
    enforced_at:
      - api
      - service
    must_prove: true
    provenance: observed
    source: >-
      services-crm:modules/tasks/aws/api/tasks-service.schemas.ts:TASK_SERVICE_OPERATIONS
    origin: none
  - id: BR-CAP-CRM-ACT-017-03
    statement: >-
      A workflow creation reference is workspace-unique, so repeated or
      concurrent creates return one task and identify whether that delivery
      created it.
    kind: invariant
    enforced_at:
      - service
      - database
    must_prove: true
    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
    origin: none
  - id: BR-CAP-CRM-ACT-017-04
    statement: >-
      Repeating completion, cancellation, reassignment or due-day changes
      returns the task unchanged when the requested state already holds.
    kind: invariant
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      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
    origin: none
  - id: BR-CAP-CRM-ACT-017-05
    statement: >-
      Inapplicable actions return specific refusals for incompatible closing,
      closed-task reassignment or redating, and update locks.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    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
    origin: none
  - id: BR-CAP-CRM-ACT-017-06
    statement: >-
      A task can be addressed by task reference, originating creation step or
      both, with disagreement between the two refused.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    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
    origin: none
  - id: BR-CAP-CRM-ACT-017-07
    statement: >-
      A service request provides the holder once, through either supported user
      form or a role offer.
    kind: validation
    enforced_at:
      - api
    must_prove: true
    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
    origin: none
  - id: BR-CAP-CRM-ACT-017-08
    statement: >-
      Workflow creation cannot specify a queue, initial status or task
      identifier.
    kind: validation
    enforced_at:
      - api
    must_prove: true
    provenance: observed
    source: 'services-crm:modules/tasks/aws/api/tasks-service.schemas.ts:createRequest'
    origin: none
  - id: BR-CAP-CRM-ACT-017-09
    statement: >-
      A task’s cross-application subject requires both a record kind and a
      record reference.
    kind: validation
    enforced_at:
      - service
      - database
    must_prove: true
    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
    origin: none
  - id: BR-CAP-CRM-ACT-017-10
    statement: >-
      Service writes attribute record stamps to the service principal, retaining
      the originating person only as execution provenance.
    kind: invariant
    enforced_at:
      - service
      - database
    must_prove: true
    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
    origin: none
  - id: BR-CAP-CRM-ACT-017-11
    statement: Services can assign and close tasks but cannot hold or claim them.
    kind: permission
    enforced_at:
      - service
      - database
    must_prove: false
    provenance: test
    source: >-
      services-crm:modules/tasks/tests/integration/services/persistence/tasks.workflow-actions.integration.spec.js#refuses
      a service the claim of a queued task, because a claim makes the caller the
      assignee
    origin: none
  - id: BR-CAP-CRM-ACT-017-12
    statement: >-
      Non-create actions retain no delivery reference, so a repeat after an
      intervening change is evaluated anew against current task state.
    kind: invariant
    enforced_at:
      - service
    must_prove: true
    provenance: observed
    source: >-
      services-crm:modules/tasks/services/workflow-actions/task-service-operations.ts:runTaskServiceOperation
    origin: none
scenarios:
  - id: SC-CAP-CRM-ACT-017-01
    given: A workflow creation step identifies a review task’s subject.
    when: Deliver its create request twice.
    then: Only one task is stored and the repeated answer reports no creation.
    provenance: test
    source: >-
      services-crm:modules/tasks/tests/e2e/tasks-service.e2e.spec.js#answers the
      repeat 200 with the same task, unchanged, not created by it
edge_cases:
  - id: SC-CAP-CRM-ACT-017-02
    given: A person cancelled the workflow’s task.
    when: Deliver a completion action.
    then: The action reports incompatible closure and preserves Cancelled.
    provenance: test
    source: >-
      services-crm:modules/tasks/tests/integration/services/workflow-actions/task-service-operations.integration.spec.js#refuses
      to complete a task a person cancelled (409), leaving it cancelled
constraints: []
depends_on:
  - CAP-CRM-ACT-010
  - CAP-CRM-ACT-011
  - CAP-CRM-ACT-012
related:
  - CAP-CRM-ACT-013
journeys:
  - JNY-CRM-ACT-005
open_questions: []
evidence:
  - >-
    services-crm at a8d1364f1dd44b723bb5f9acba12f983e9ec8d69: 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-IAM-001, TC-IAM-005, TC-IAM-006, TC-LOG-001, TC-LOG-002, TC-LOG-003, TC-LOG-004, TC-LOG-005, TC-MON-001, TC-MON-002, TC-PI-001, TC-PI-002, TC-PI-003, TC-PI-004, TC-PI-005, TC-PRV-001, TC-PRV-002, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-TEN-004]
---

# Create workflow tasks once and repeat actions according to state

## Purpose

Application processes delegate human work through a service contract with safe creation retries.

## How It Works

Another registered Rhythm service invokes the task contract directly. It requests creation, closure, reassignment, redating or offered-work listing. Creation identifies the originating workflow step. Repeated and concurrent creation deliveries recover the task already associated with that step. Other actions compare the requested result with the task’s current state. If that result already holds, they return without another change. An intervening person-driven change can make a later delivery act again or be refused. CRM does not retain a delivery identity for those actions. Writes identify the service principal, with an originating person retained as provenance. External workflow executors and their response handling remain outside the examined source scope.

## Relationships

- Task recording and lifecycle own the resulting work and state.
- Role offers route tasks to eligible claimants.
- Platform integrations own workflow execution and delivery handling.
