---
id: STATE-COM-FUL-009
title: Stock allocation unit lifecycle
object: DOM-COM-FUL-005
product_area: commerce
module: fulfillment
revision: 1
status: draft
design_intent: proposed
implementation_evidence: observed
source_sha:
  services-commerce: c8b66a98e2490617aec38ba5c8165dd9bd0a8f9b
states:
  - name: held
    meaning: A checkout item holds this unit until its retained expiry.
  - name: committed
    meaning: >-
      An order line promises this unit from stock after placement or
      replenishment.
  - name: backordered
    meaning: The product permits a promised unit to wait for available stock.
  - name: picked
    meaning: >-
      Warehouse picking has decided the live lines, or a unit allocation is
      picked under its delivery obligation.
  - name: shipped
    meaning: A declared lifecycle state retained by its owning process.
  - name: released
    meaning: >-
      The unit no longer consumes its buyer promise, with a retained release
      reason.
transitions:
  - from: held
    to: committed
    trigger: Placement or stock replenishment retains the order-unit promise.
    guard: >-
      A valid placement claim must convert the checkout ownership under its
      retained quantity checks.
    side_effects:
      - Assign the order-line unit and release the checkout item’s holds.
    who: Placement (claim function)
    provenance: observed
    source: >-
      services-commerce:modules/inventory/db/inventory-allocations.table.ts
      (commerce_commit_claims)
  - from: held
    to: released
    trigger: The owning process releases the eligible work or buyer promise.
    guard: The owning release process must authorize expiry or checkout release.
    side_effects:
      - >-
        Raise an expired-hold finding when the nightly check discovers overdue
        holds.
    who: 'Merchandise application, nightly check'
    provenance: observed
    source: >-
      services-commerce:modules/inventory/services/persistence/inventory-allocations.ts:expireHolds
  - from: committed
    to: picked
    trigger: Picking records the eligible warehouse or allocation result.
    guard: The allocation must be committed to the specified order line and unit.
    side_effects:
      - >-
        Obligation stamped; delivery answered in progress including the
        allocation as the record.
    who: Merchandise application
    provenance: observed
    source: >-
      services-commerce:modules/inventory/services/persistence/inventory-allocations.ts:pickUnitsOfLine
  - from: backordered
    to: committed
    trigger: Placement or stock replenishment retains the order-unit promise.
    guard: Sellable stock must cover each filled waiting unit.
    side_effects:
      - >-
        Delete the waiting backorder row and create a committed row at the
        supplying item for the same order-line unit.
      - >-
        Pick the replenished unit later under its retained obligation when
        shipment creation runs.
    who: Inventory movement workflow
    provenance: observed
    source: >-
      services-commerce:modules/inventory/services/persistence/inventory-allocations.ts:fillBackorders
  - from: picked
    to: shipped
    trigger: Handoff retains allocation departure.
    guard: Every allocation to ship must be picked.
    side_effects:
      - Record stock departure and request the corresponding cost relief.
    who: Shipping handoff
    provenance: observed
    source: >-
      services-commerce:modules/inventory/services/persistence/inventory-allocations.ts:shipUnits
  - from: committed
    to: released
    trigger: The owning process releases the eligible work or buyer promise.
    guard: Cancellation release must identify its named fenced units.
    side_effects:
      - Release reason stored.
    who: 'Void, or the merchandise application''s cancel'
    provenance: observed
    source: >-
      services-commerce:modules/inventory/services/persistence/inventory-allocations.ts:releaseFencedUnitsOfLine
  - from: picked
    to: released
    trigger: The owning process releases the eligible work or buyer promise.
    guard: The cancellation must identify fenced picked units that have not shipped.
    side_effects: []
    who: Merchandise application (cancel)
    provenance: documented
    source: >-
      services-commerce:docs/migrations/inventory/README.md (D-P7-24 amendment
      of D-P8I-13)
  - from: backordered
    to: released
    trigger: The owning process releases the eligible work or buyer promise.
    guard: The owning release must find eligible unshipped claims.
    side_effects: []
    who: Void or cancellation
    provenance: observed
    source: >-
      services-commerce:modules/inventory/db/inventory-allocations.table.ts
      (commerce_release_claims)
invalid:
  - from: shipped
    to: released
    why: >-
      Departed stock returns through disposition movements, while its allocation
      stays shipped.
  - from: committed
    to: shipped
    why: >-
      Departure requires a picked allocation and Shipping’s matching-obligation
      checks.
  - from: released
    to: committed
    why: Released allocations are not reopened as a new stock promise.
concurrency: >-
  Hold selection locks sellable items in allocation order. Placement computes
  the needed claim, while constrained balances refuse competing overconsumption.
invariants:
  - INV-DOM-COM-FUL-005-01
  - INV-DOM-COM-FUL-005-05
  - INV-DOM-COM-FUL-005-06
  - INV-DOM-COM-FUL-005-07
evidence:
  - >-
    services-commerce at c8b66a98:
    modules/inventory/db/inventory-allocations.table.ts;
    services/persistence/inventory-allocations.ts;
    db/migrations/20261018024147_merchandise_and_inventory.sql (claim
    functions); docs/migrations/inventory/README.md (D-P8I-04, D-P8I-05,
    D-P8I-06, D-P8I-21).
---

# Stock Allocation Unit Lifecycle

## The Lifecycle

```mermaid
stateDiagram-v2
  [*] --> held: checkout hold
  [*] --> committed: order placement claim
  [*] --> backordered: short claim allowed
  held --> committed
  held --> released
  backordered --> committed: stock arrives
  committed --> picked: delivery authorized
  picked --> shipped: handoff
  committed --> released
  picked --> released
  backordered --> released
  shipped --> [*]
  released --> [*]
```

## Transitions Explained

Checkout can hold a unit until expiry. Placement commits it or creates a backorder when policy permits. Authorized delivery picks the unit, handoff ships it, and void or cancellation releases eligible units. Stock arrivals fill waiting backorders.

## What Cannot Happen

Shipped units return through disposition movements rather than allocation release. Shipping requires picked allocations and separately checks matching obligations.

## Concurrency and Timing

Claims and holds consume balances under database checks. Nightly reconciliation releases expired holds as a recovery measure; other discrepancies become findings.
