---
id: WF-COM-FUL-012
title: Hand goods to the carrier or the collector
trigger: Staff manifest or confirm physical departure.
product_area: commerce
module: fulfillment
revision: 1
status: draft
design_intent: confirmed
origin: >-
  Decision L, Andrew 2026-10-18 ("add it now", the counter handover) and
  Decision O, Andrew 2026-10-18 (relief at zero with a finding, as built):
  services-commerce:docs/migrations/shipping/README.md#2026-10-18 — Progress
  checkpoint (section 9 of the 14-section walk: shipping, purchasing and cost)
implementation_evidence: observed
inference: []
source_sha:
  services-commerce: c8b66a98e2490617aec38ba5c8165dd9bd0a8f9b
implements:
  - CAP-COM-FUL-014
moves:
  - STATE-COM-FUL-005
  - STATE-COM-FUL-006
  - STATE-COM-FUL-009
  - STATE-COM-FUL-001
crosses:
  - SVC-COM-FUL-shipping
  - SVC-COM-FUL-inventory
  - SVC-COM-FUL-fulfillment
idempotency: >-
  Repeated handoff is refused by departure state. Movement keys identify the
  shipment line and stock item, preventing a second physical movement.
concurrency: >-
  Cancellation and departure use conditional updates on the same shipment-line
  rows. Their transaction outcome determines which act can proceed.
hops:
  - 'n': 1
    actor_or_service: Shipping API (manifest)
    action: Manifest a labelled carrier shipment with its live lines and parcels.
    anchor: >-
      services-commerce:modules/shipping/services/fulfillment/handoff.ts:manifestShipment
    seam: sync
    on_failure: Refuse incomplete labelling or pickup manifestation.
    left_inconsistent: No failed manifest change remains.
    observer: Manifest history.
    provenance: observed
    source: 'services-commerce:modules/shipping/services/fulfillment/handoff.ts'
  - 'n': 2
    actor_or_service: 'Shipping API (handoff or handover, one transaction)'
    action: >-
      Lock the shipment and conditionally advance ready lines, rejecting fences
      and invalid matching obligations.
    anchor: >-
      services-commerce:modules/shipping/services/persistence/shipments.ts:handoffLinesOfShipment
    seam: sync
    on_failure: Rollback and subsequently record handoff refusal and a stock finding.
    left_inconsistent: >-
      No stock leaves through a refused handoff; absent obligation matches are
      not counted.
    observer: Inventory finding and handoff history.
    provenance: observed
    source: >-
      services-commerce:modules/shipping/services/fulfillment/handoff.ts:obligationsOfUnits
  - 'n': 3
    actor_or_service: Same transaction
    action: >-
      Ship picked allocations, write per-item movements, invoke cost relief and
      complete each matching unit obligation.
    anchor: >-
      services-commerce:modules/shipping/services/fulfillment/handoff.ts:handoffShipment
    seam: sync
    on_failure: Rollback participating handoff writes on refusal.
    left_inconsistent: The failed handoff transaction retains no partial movement.
    observer: 'Stock movements, obligations and cost-provider result.'
    provenance: test
    source: >-
      services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#completes
      every unit’s obligation through the register (the allocation as the
      record), and emits one deferred cost relief fact per item
  - 'n': 4
    actor_or_service: Same transaction
    action: >-
      Update shipped order quantities, shipment and parcel departure, retaining
      the collector for pickup.
    anchor: >-
      services-commerce:modules/shipping/services/fulfillment/handoff.ts:handoverShipment
    seam: sync
    on_failure: Rollback the shared departure transaction.
    left_inconsistent: The failed local departure makes no partial order update.
    observer: Order shipping quantities and shipment card.
    provenance: documented
    source: 'services-commerce:docs/migrations/shipping/README.md#D-P8S-14'
  - 'n': 5
    actor_or_service: Register completion (inside the handoff's transaction)
    action: >-
      Invoke dependent settlement from register completion within the enclosing
      handoff transaction.
    anchor: >-
      services-commerce:modules/fulfillment/services/register/prerequisite-settlement.ts:settlePrerequisiteDependents
    seam: sync
    on_failure: Log dependent continuation errors.
    left_inconsistent: A dependent write can remain missing even when handoff later commits.
    observer: Dependent-settlement logs.
    provenance: inferred
    source: >-
      services-commerce:modules/fulfillment/services/register/obligation-callbacks.ts:completeObligation
      (the handoff uses the callback's own completion)
branches:
  - >-
    Cost relief is the purchasing cost provider's (layers by default); units no
    layer covers are relieved at zero including a finding; the fixture defers
    relief and the nightly cost pass finds a shipment movement without relief.
  - >-
    Counter handover needs a named collector and the sensitive handover
    permission.
waits: []
evidence:
  - >-
    services-commerce at c8b66a98:
    modules/shipping/services/fulfillment/handoff.ts, cancellation-fence.ts;
    services/cost/cost-relief-port.ts;
    modules/inventory/services/persistence/inventory-allocations.ts:shipUnits;
    docs/migrations/shipping/README.md (D-P8S-09, D-P8S-10, D-P8S-11, D-P8S-14).
controls: [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-CRY-004, 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-VEN-001, TC-VEN-002, TC-VEN-003, TC-PRV-001, TC-PRV-002]
---

# Hand Goods to the Carrier or the Collector

## What It Does

Carrier dispatch closes a labelled manifest and then hands over all ready shipment lines. Pickup hands over a packed shipment to a named collector. The shared transaction ships allocations, writes movements, invokes cost relief, completes matching obligations and updates the order.

## The Flow

```mermaid
sequenceDiagram
  participant S as Staff
  participant H as Shipping API
  participant L as Shipment lines
  participant I as Stock ledgers
  participant C as Cost provider
  participant R as Register
  S->>H: manifest, then confirm handoff
  H->>L: manifested to handed over (conditional)
  H->>I: ship units, shipment movements
  H->>C: relieve cost (same transaction)
  H->>R: complete each unit's obligation
  H->>H: order quantities, history
  H-->>S: handed off, or refused with the reason
```

## When Something Fails

Any refusal within handoff rolls back its transaction, followed by a retained refusal finding and history event. Matching obligations are checked for valid state, but missing matches are not counted. Cost behavior depends on the selected provider, including the fixture that permits deferred relief.
