---
id: WF-COM-FUL-003
title: Dispatch an authorization and record the application's answer
trigger: 'Retained authorization dispatch, callback or acknowledgement expiry.'
product_area: commerce
module: fulfillment
revision: 1
status: draft
design_intent: proposed
implementation_evidence: observed
inference: []
source_sha:
  services-commerce: c8b66a98e2490617aec38ba5c8165dd9bd0a8f9b
implements:
  - CAP-COM-FUL-004
  - CAP-COM-FUL-005
moves:
  - STATE-COM-FUL-001
  - STATE-COM-FUL-002
crosses:
  - SVC-COM-FUL-fulfillment
  - SVC-COM-FUL-operations
idempotency: >-
  Applications use the authorization identity as the repeat key. Dispatch rows
  are unique per authorization, and the worker applies only current in-flight
  answers; repeated terminal pointers are stale.
concurrency: >-
  Dispatch runs with reserved concurrency one and skip-locked claims. Workers
  can overlap; conditional outcome application prevents a second current
  terminal answer, but follow-up writes occur later.
hops:
  - 'n': 1
    actor_or_service: Obligation dispatcher
    action: >-
      Claim oldest retained dispatch entries, publish authorization pointers and
      remove accepted entries in the dispatcher transaction.
    anchor: >-
      services-commerce:modules/fulfillment/services/register/obligation-dispatcher.ts:dispatchObligations
    seam: schedule
    on_failure: >-
      Keep refused entries; a thrown publish rolls back removal for later
      scheduling.
    left_inconsistent: Authorized delivery waits for another dispatcher run.
    observer: Dispatcher logs and dispatch-entry age.
    provenance: observed
    source: >-
      services-commerce:modules/fulfillment/services/register/obligation-dispatcher.ts
  - 'n': 2
    actor_or_service: Obligation worker
    action: >-
      Load current authorization and sale records, skip stale work, build the
      supported operation envelope and invoke its application.
    anchor: >-
      services-commerce:modules/fulfillment/services/register/obligation-worker.ts:workObligationItem
    seam: queue
    on_failure: >-
      Known unavailable or retryable results return queue-item failure under the
      receive budget.
    left_inconsistent: >-
      The authorization remains in flight, with an attempt recorded where that
      path writes one.
    observer: Delivery attempts and queue metrics.
    provenance: test
    source: >-
      services-commerce:modules/fulfillment/tests/integration/services/register/obligation-worker.integration.spec.js#fails
      the obligation with the participant’s code, raises obligation_failed, and
      acknowledges the item
  - 'n': 3
    actor_or_service: Obligation worker
    action: >-
      Apply the current answer with its attempt, then write history, findings
      and enforcement or document follow-up.
    anchor: >-
      services-commerce:modules/fulfillment/services/persistence/obligations.ts:recordObligationOutcome
    seam: sync
    on_failure: Later failure can return the item failed after the outcome commits.
    left_inconsistent: >-
      Terminal delivery can lack later history, findings or enforcement
      settlement; a retry then appears stale.
    observer: 'Obligation outcome, attempts and order history.'
    provenance: observed
    source: >-
      services-commerce:modules/fulfillment/services/register/obligation-worker.ts
  - 'n': 4
    actor_or_service: Obligation worker (fifth receive)
    action: >-
      On the final known retry path, record exhaustion and its finding, then
      leave the queue item failed for dead-letter handling.
    anchor: >-
      services-commerce:modules/fulfillment/services/register/obligation-worker.ts:processObligationBatch
    seam: queue
    on_failure: An arbitrary throw can reach dead-lettering without the exhaustion record.
    left_inconsistent: The message can remain in the dead-letter queue for fourteen days.
    observer: Exhaustion findings and dead-letter depth.
    provenance: documented
    source: 'services-commerce:docs/migrations/obligation-register/README.md#D-P4-07'
  - 'n': 5
    actor_or_service: Delivering application callbacks
    action: >-
      Accept authorized outcome callbacks and readiness reports, applying
      current answers and evaluating readiness-dependent gates.
    anchor: >-
      services-commerce:modules/fulfillment/services/register/obligation-callbacks.ts
    seam: sync
    on_failure: Reject obsolete authorization with a conflict response.
    left_inconsistent: The old instruction changes no current delivery state.
    observer: Callback response and attempts.
    provenance: documented
    source: 'services-commerce:docs/migrations/obligation-register/README.md#D-P4-09'
  - 'n': 6
    actor_or_service: Register sweep (a pass of Orders' checkout sweeper)
    action: >-
      Inspect overdue in-flight records, redispatch once with a renewed
      deadline, then abandon another expired acknowledgement.
    anchor: >-
      services-commerce:modules/fulfillment/services/register/register-sweeper.ts:sweepRegister
    seam: schedule
    on_failure: Bounded reads and a failed run can delay examination.
    left_inconsistent: Overdue obligations remain unresolved until a later successful scan.
    observer: Acknowledgement findings and order history.
    provenance: observed
    source: >-
      services-commerce:modules/fulfillment/services/persistence/obligations.ts:redispatchAuthorization
  - 'n': 7
    actor_or_service: Register (after commit)
    action: >-
      Settle same-order dependents after terminal prerequisite delivery
      outcomes.
    anchor: >-
      services-commerce:modules/fulfillment/services/register/prerequisite-settlement.ts:settlePrerequisiteDependents
    seam: sync
    on_failure: Log settlement errors without undoing the delivery outcome.
    left_inconsistent: >-
      Dependent readiness or blocking can remain unrecorded until another
      outcome or staff action.
    observer: Settlement logs.
    provenance: observed
    source: >-
      services-commerce:modules/fulfillment/services/register/prerequisite-settlement.ts
branches:
  - >-
    Terminate and allocation-release operations are acknowledged including a
    warning and delivered to no one.
  - >-
    An in-process application (the entitlements register) is invoked in the
    existing function including the existing wire encoding.
waits:
  - >-
    The acknowledgement deadline: the application's declared service level, one
    hour by default and a day for shipped units.
evidence:
  - >-
    services-commerce at c8b66a98: modules/fulfillment/services/register/*.ts;
    aws/resources/obligations-queue.sqs.ts (visibility 90 s, five receives,
    dead-letter 14 days); aws/logic/fulfillment-functions.lambda.ts;
    docs/migrations/obligation-register/README.md (D-P4-07, D-P4-08, D-P4-09,
    D-P4-11, D-P4-12).
controls: [TC-IAM-006, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-AZ-005, TC-AZ-006, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-CRY-001, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-DAT-004, TC-LOG-001, TC-LOG-002, TC-LOG-003, TC-LOG-004, TC-LOG-005, TC-AVL-004, TC-MON-001, TC-MON-002, TC-MON-004, TC-PI-001, TC-PI-002, TC-PI-003, TC-PI-004, TC-PI-005, TC-PRV-001, TC-PRV-002]
---

# Dispatch an Authorization and Record the Application's Answer

## What It Does

The dispatcher sends retained authorization pointers to the queue. The worker loads current records, invokes the owning application with the relevant operation contract and conditionally applies its answer. Long-running work uses callbacks, while overdue acknowledgements use the register sweep.

## The Flow

```mermaid
sequenceDiagram
  participant T as Authorizing transaction
  participant D as Dispatcher
  participant Q as Obligations queue
  participant W as Worker
  participant P as Delivering application
  participant S as Register sweep
  T->>D: nudge after commit
  D->>Q: pointer per authorization
  Q->>W: deliver (up to five times)
  W->>P: envelope under the authorization
  P-->>W: completed, in progress or failed
  W->>W: conditional outcome, attempt
  P->>W: later callback (long-running)
  S->>Q: re-dispatch once past deadline
  S->>S: then fail as acknowledgement lost
```

## When Something Fails

Known transient paths use queue retries and record exhaustion at the receive limit. An arbitrary throw can bypass that record. History, findings and enforcement settlement follow the committed outcome, so a later error can leave missing records that a stale redelivery does not repair.
