---
id: STATE-COM-FUL-005
title: Shipment and shipment line lifecycle
object: DOM-COM-FUL-004
product_area: commerce
module: fulfillment
revision: 1
status: draft
design_intent: proposed
implementation_evidence: observed
source_sha:
  services-commerce: c8b66a98e2490617aec38ba5c8165dd9bd0a8f9b
states:
  - name: open
    meaning: The record is active and available for its next staff or workflow action.
  - name: released
    meaning: Shipment work is released for warehouse picking.
  - name: picking
    meaning: Shipment lines are assigned to warehouse picking work.
  - name: picked
    meaning: >-
      Warehouse picking has decided the live lines, or a unit allocation is
      picked under its delivery obligation.
  - name: packing
    meaning: Some eligible quantities have been assigned to parcels.
  - name: packed
    meaning: >-
      The parcel or live shipment contents are packed; carrier purchase intent
      is tracked separately.
  - name: labelled
    meaning: >-
      A parcel has a retained purchased label, or every live shipment parcel is
      labelled.
  - name: manifested
    meaning: Carrier preparation is closed and departure can be confirmed.
  - name: handed_to_carrier
    meaning: >-
      Carrier departure is retained with its participating stock and delivery
      effects.
  - name: collected
    meaning: Pickup departure is retained with its named collector.
  - name: delivered
    meaning: The carrier or permitted manual report records delivery.
  - name: exception
    meaning: Carrier tracking reports a shipment problem.
  - name: returned_to_sender
    meaning: Carrier tracking reports return towards the sender.
  - name: cancelled
    meaning: >-
      The owning process withdrew the work under its permitted cancellation
      checks.
  - name: allocated
    meaning: >-
      A shipment line owns its assigned order-unit range before warehouse
      release.
    record: shipment_line
  - name: released_to_warehouse
    meaning: A shipment line is ready to enter a warehouse pick list.
    record: shipment_line
  - name: short
    meaning: Warehouse picking retained fewer units than the shipment line expected.
    record: shipment_line
  - name: cancellation_pending
    meaning: >-
      A conditional fence reserves the shipment line for cancellation rather
      than handoff.
    record: shipment_line
transitions:
  - from: open
    to: released
    trigger: The owning process releases the eligible work or buyer promise.
    guard: Release requires an open shipment.
    side_effects:
      - Release the shipment lines to warehouse work.
      - Append shipment release to history.
    who: Warehouse staff (shipment update)
    provenance: observed
    source: >-
      services-commerce:modules/shipping/services/fulfillment/shipment-creation.ts:releaseShipment
  - from: released
    to: picking
    trigger: Warehouse staff gather available shipment lines into picking work.
    guard: >-
      Picking gathers released lines that the current precheck does not find on
      another live list.
    side_effects:
      - Start picking on the participating shipment lines.
      - Append pick-list creation to history.
    who: Warehouse staff (pick list create)
    provenance: observed
    source: >-
      services-commerce:modules/shipping/services/fulfillment/picking.ts:createPickListForWarehouse
  - from: picking
    to: picked
    trigger: Picking records the eligible warehouse or allocation result.
    guard: Every live line must have finished picking.
    side_effects:
      - Raise a stock finding for each reported picking shortage.
    who: Picker (pick list update)
    provenance: observed
    source: >-
      services-commerce:modules/shipping/services/fulfillment/picking.ts:recordPickOnList
  - from: picked
    to: packing
    trigger: Packing assigns some eligible quantities to parcels.
    guard: >-
      Packing requires eligible picked lines and quantities within the unpacked
      remainder.
    side_effects:
      - Parcels and their contents retained; weights derived once unstated.
    who: Warehouse staff
    provenance: observed
    source: >-
      services-commerce:modules/shipping/services/fulfillment/packing.ts:packShipment
  - from: picked
    to: packed
    trigger: The packing call completes the remaining live shipment quantities.
    guard: >-
      The packing call must finish every live line to move the shipment directly
      to packed.
    side_effects:
      - Mark completed lines packed and update parcel count and weight.
    who: Warehouse staff
    provenance: observed
    source: >-
      services-commerce:modules/shipping/services/fulfillment/packing.ts:packShipment
  - from: packing
    to: packed
    trigger: The packing call completes the remaining live shipment quantities.
    guard: The remaining packing call must finish every live line.
    side_effects: []
    who: Warehouse staff
    provenance: observed
    source: >-
      services-commerce:modules/shipping/services/fulfillment/packing.ts:packShipment
  - from: packed
    to: labelled
    trigger: Carrier purchase success or staff settlement retains a purchased label.
    guard: Successful purchase must leave every live parcel labelled.
    side_effects:
      - Mark the affected shipment lines labelled.
    who: Label purchase
    provenance: observed
    source: >-
      services-commerce:modules/shipping/services/fulfillment/labels.ts:purchaseLabelForPackage
  - from: labelled
    to: packed
    trigger: A successful label void leaves shipment preparation incomplete.
    guard: Successful void must leave a live parcel unlabelled.
    side_effects:
      - Return the affected shipment lines to packed preparation.
    who: Label void
    provenance: observed
    source: >-
      services-commerce:modules/shipping/services/fulfillment/labels.ts:voidLabelOfPackage
  - from: labelled
    to: manifested
    trigger: Staff close carrier preparation.
    guard: Manifestation requires a labelled carrier shipment.
    side_effects:
      - Mark the shipment lines and parcels manifested in the same transaction.
    who: Warehouse staff
    provenance: observed
    source: >-
      services-commerce:modules/shipping/services/fulfillment/handoff.ts:manifestShipment
  - from: manifested
    to: handed_to_carrier
    trigger: Staff confirm physical carrier departure.
    guard: >-
      Every departing line must be ready and unfenced; matching obligations must
      remain in flight.
    side_effects:
      - Allocations shipped; shipment movements retained; on hand down.
      - Apply physical-unit completion through the obligation register.
      - Request cost relief from the configured cost provider.
      - Update shipped quantities and the order’s shipping summary.
    who: Warehouse staff (handoff)
    provenance: test
    source: >-
      services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#hands
      off: the line handed to the carrier with its whole quantity shipped, the
      units shipped in the ledger, one shipment movement of minus three on the
      item, three fewer on hand
  - from: packed
    to: collected
    trigger: Staff hand a packed pickup to its named collector.
    guard: >-
      Pickup handover requires packed work, a named collector and unfenced
      lines.
    side_effects:
      - 'The existing stock, obligation, cost and order effects as a handoff.'
    who: Administrator (sensitive handover)
    provenance: documented
    source: 'services-commerce:docs/migrations/shipping/README.md#D-P8S-14'
  - from: handed_to_carrier
    to: delivered
    trigger: Explicit carrier tracking or a manual report records delivery.
    guard: Tracking must report all live parcels delivered.
    side_effects:
      - Mark the participating shipment lines delivered.
    who: Staff requesting tracking
    provenance: observed
    source: >-
      services-commerce:modules/shipping/services/fulfillment/labels.ts:trackPackage
  - from: handed_to_carrier
    to: exception
    trigger: Explicit tracking records a carrier problem.
    guard: The reported problem must affect a departed carrier shipment.
    side_effects: []
    who: Staff requesting tracking
    provenance: observed
    source: >-
      services-commerce:modules/shipping/services/fulfillment/labels.ts:trackPackage
  - from: handed_to_carrier
    to: returned_to_sender
    trigger: Explicit tracking records return towards the sender.
    guard: The reported return must affect a departed carrier shipment.
    side_effects: []
    who: Staff requesting tracking
    provenance: observed
    source: >-
      services-commerce:modules/shipping/services/fulfillment/labels.ts:trackPackage
  - from: open
    to: cancelled
    trigger: The owning process withdraws work before departure or delivery permits it.
    guard: Cancellation must find no departed line.
    side_effects:
      - >-
        Fence and cancel shipment lines, clearing shipment assignments while
        keeping the order’s unit promises.
      - Attempt label void and remove parcels when the carrier confirms it.
    who: Administrator (sensitive cancel) or the cancellation
    provenance: observed
    source: >-
      services-commerce:modules/shipping/services/fulfillment/shipment-creation.ts:cancelShipment
  - from: manifested
    to: cancelled
    trigger: The owning process withdraws work before departure or delivery permits it.
    guard: Cancellation must find no departed line.
    side_effects:
      - >-
        Apply the same explicitly described disposition effects as the preceding
        disposition edge.
    who: Administrator or the cancellation
    provenance: observed
    source: >-
      services-commerce:modules/shipping/services/fulfillment/cancellation-fence.ts:cancelFencedShipmentLines
  - from: allocated
    to: released_to_warehouse
    record: shipment_line
    trigger: Staff releases the open shipment.
    guard: Only allocated shipment lines are selected.
    side_effects:
      - Release the selected lines to warehouse work.
    provenance: observed
    source: >-
      services-commerce:modules/shipping/services/fulfillment/shipment-creation.ts:releaseShipment
  - from: released_to_warehouse
    to: picking
    record: shipment_line
    trigger: A pick list is created for the released work.
    guard: The membership precheck must not find the line on another live pick list.
    side_effects:
      - Attach the line to the created list and start picking.
    provenance: observed
    source: >-
      services-commerce:modules/shipping/services/fulfillment/picking.ts:createPickListForWarehouse
  - from: picking
    to: picked
    record: shipment_line
    trigger: Staff records a complete pick on the list.
    guard: The pick-list writer must accept the reported quantity and list state.
    side_effects:
      - 'Store picked quantity, time and shipment-line history.'
    provenance: observed
    source: >-
      services-commerce:modules/shipping/services/fulfillment/picking.ts:recordPickOnList
  - from: picking
    to: short
    record: shipment_line
    trigger: Staff reports a shortage on the pick-list line.
    guard: The pick-list writer must accept the shortage record.
    side_effects:
      - >-
        Store picked quantity and shortage diagnosis, and raise the stock
        finding.
    provenance: observed
    source: >-
      services-commerce:modules/shipping/services/fulfillment/picking.ts:recordPickOnList
  - from: picking
    to: released_to_warehouse
    record: shipment_line
    trigger: Staff abandons an unfinished pick list.
    guard: Only pending pick-list lines return to warehouse release.
    side_effects:
      - Return the selected shipment lines to available picking work.
    provenance: observed
    source: >-
      services-commerce:modules/shipping/services/fulfillment/picking.ts:cancelPickList
  - from: allocated
    to: cancellation_pending
    record: shipment_line
    trigger: An order-line cancellation places a fence.
    guard: >-
      The line must remain in a cancellable state when the conditional locked
      write runs.
    side_effects:
      - Store the fence and block physical departure on that line.
    provenance: observed
    source: >-
      services-commerce:modules/shipping/services/persistence/shipments.ts:fenceLinesForCancellation
  - from: released_to_warehouse
    to: cancellation_pending
    record: shipment_line
    trigger: An order-line cancellation places a fence.
    guard: >-
      The line must remain in a cancellable state when the conditional locked
      write runs.
    side_effects:
      - Store the fence and block physical departure on that line.
    provenance: observed
    source: >-
      services-commerce:modules/shipping/services/persistence/shipments.ts:fenceLinesForCancellation
  - from: picking
    to: cancellation_pending
    record: shipment_line
    trigger: An order-line cancellation places a fence.
    guard: >-
      The line must remain in a cancellable state when the conditional locked
      write runs.
    side_effects:
      - Store the fence and block physical departure on that line.
    provenance: observed
    source: >-
      services-commerce:modules/shipping/services/persistence/shipments.ts:fenceLinesForCancellation
  - from: picked
    to: cancellation_pending
    record: shipment_line
    trigger: An order-line cancellation places a fence.
    guard: >-
      The line must remain in a cancellable state when the conditional locked
      write runs.
    side_effects:
      - Store the fence and block physical departure on that line.
    provenance: observed
    source: >-
      services-commerce:modules/shipping/services/persistence/shipments.ts:fenceLinesForCancellation
  - from: packing
    to: cancellation_pending
    record: shipment_line
    trigger: An order-line cancellation places a fence.
    guard: >-
      The line must remain in a cancellable state when the conditional locked
      write runs.
    side_effects:
      - Store the fence and block physical departure on that line.
    provenance: observed
    source: >-
      services-commerce:modules/shipping/services/persistence/shipments.ts:fenceLinesForCancellation
  - from: packed
    to: cancellation_pending
    record: shipment_line
    trigger: An order-line cancellation places a fence.
    guard: >-
      The line must remain in a cancellable state when the conditional locked
      write runs.
    side_effects:
      - Store the fence and block physical departure on that line.
    provenance: observed
    source: >-
      services-commerce:modules/shipping/services/persistence/shipments.ts:fenceLinesForCancellation
  - from: labelled
    to: cancellation_pending
    record: shipment_line
    trigger: An order-line cancellation places a fence.
    guard: >-
      The line must remain in a cancellable state when the conditional locked
      write runs.
    side_effects:
      - Store the fence and block physical departure on that line.
    provenance: observed
    source: >-
      services-commerce:modules/shipping/services/persistence/shipments.ts:fenceLinesForCancellation
  - from: manifested
    to: cancellation_pending
    record: shipment_line
    trigger: An order-line cancellation places a fence.
    guard: >-
      The line must remain in a cancellable state when the conditional locked
      write runs.
    side_effects:
      - Store the fence and block physical departure on that line.
    provenance: observed
    source: >-
      services-commerce:modules/shipping/services/persistence/shipments.ts:fenceLinesForCancellation
  - from: short
    to: cancellation_pending
    record: shipment_line
    trigger: An order-line cancellation places a fence.
    guard: >-
      The line must remain in a cancellable state when the conditional locked
      write runs.
    side_effects:
      - Store the fence and block physical departure on that line.
    provenance: observed
    source: >-
      services-commerce:modules/shipping/services/persistence/shipments.ts:fenceLinesForCancellation
  - from: cancellation_pending
    to: cancelled
    record: shipment_line
    trigger: Cancellation work settles its fenced lines.
    guard: The line must retain the matching fence and cancellation-pending state.
    side_effects:
      - Finalize cancellation of the fenced line.
    provenance: observed
    source: >-
      services-commerce:modules/shipping/services/persistence/shipments.ts:cancelFencedLines
invalid:
  - from: handed_to_carrier
    to: cancelled
    why: The owning workflow’s state checks refuse this progression.
  - from: collected
    to: handed_to_carrier
    why: Pickup collection has no carrier lifecycle.
  - from: open
    to: picking
    why: The owning workflow’s state checks refuse this progression.
  - from: packed
    to: manifested
    why: The owning workflow’s state checks refuse this progression.
concurrency: >-
  Cancellation and departure use conditional updates on the same shipment-line
  rows. Their transaction outcome determines which act can proceed.
invariants:
  - INV-DOM-COM-FUL-004-03
  - INV-DOM-COM-FUL-004-04
  - INV-DOM-COM-FUL-004-05
  - INV-DOM-COM-FUL-004-07
evidence:
  - >-
    services-commerce at c8b66a98: modules/shipping/db/shipments.table.ts,
    shipment-lines.table.ts; services/fulfillment/*.ts;
    services/persistence/shipments.ts; docs/migrations/shipping/README.md
    (D-P8S-10, D-P8S-11, D-P8S-13, D-P8S-14).
  - >-
    services-commerce:modules/shipping/services/fulfillment/labels.ts:trackPackage
    (exception and returned-to-sender update the header);
    modules/shipping/services/fulfillment/picking.ts;
    modules/shipping/services/persistence/shipments.ts.
---

# Shipment and Shipment Line Lifecycle

## The Lifecycle

```mermaid
stateDiagram-v2
  [*] --> open: made from committed units
  open --> released
  released --> picking
  picking --> picked
  picked --> packing
  picked --> packed
  packing --> packed
  packed --> labelled: carrier
  labelled --> packed: label voided
  labelled --> manifested
  manifested --> handed_to_carrier: handoff
  packed --> collected: pick-up handover
  handed_to_carrier --> delivered
  handed_to_carrier --> exception
  handed_to_carrier --> returned_to_sender
  open --> cancelled
  manifested --> cancelled
  cancelled --> [*]
```

Shipment lines start allocated and use their own warehouse-release, shortage and cancellation-fence states. The additional line transitions below describe those differences; the shared packing, labelling and departure progressions are described by their owning service edges. Carrier exception and returned-to-sender values are declared for lines, but tracking currently changes the shipment header for those outcomes rather than asserting a line transition.

```mermaid
stateDiagram-v2
  [*] --> allocated
  allocated --> released_to_warehouse: release work
  released_to_warehouse --> picking: create list
  picking --> picked: complete pick
  picking --> short: record shortage
  picking --> released_to_warehouse: abandon pending work
  allocated --> cancellation_pending: place fence
  short --> cancellation_pending: place fence
  cancellation_pending --> cancelled: settle fenced work
```

## Transitions Explained

Warehouse work advances from shipment creation through release, picking, packing and carrier preparation. Carrier handoff requires manifestation; customer collection uses a packed pickup. Shipment lines additionally represent shortages and cancellation fences.

## What Cannot Happen

Workflow guards enforce the ordinary sequence, while database checks protect pickup distinctions and departure timestamps. These are weaker than a database transition table for every warehouse state.

## Concurrency and Timing

Handoff and cancellation decide on the same shipment-line rows. Tracking runs when requested and has no scheduled poller.
