---
id: WF-COM-FUL-001
title: Freeze delivery gates when an order is placed
trigger: Order placement after application preparation.
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-001
  - CAP-COM-FUL-003
  - CAP-COM-FUL-018
moves:
  - STATE-COM-FUL-001
  - STATE-COM-FUL-009
crosses:
  - SVC-COM-FUL-fulfillment
  - SVC-COM-FUL-inventory
idempotency: >-
  A repeated checkout placement returns its retained order. Subject, operation
  and unit uniqueness prevents duplicate obligations, and line-unit claim
  uniqueness prevents another allocation for the same order unit.
concurrency: >-
  Checkout locking serializes repeated placement. Competing stock claims rely on
  item constraints so a shortage refuses the losing placement transaction.
hops:
  - 'n': 1
    actor_or_service: Orders placement (before the transaction)
    action: >-
      Select active product, profile or workspace policy, falling back to the
      built-in policy, and add application preparation and same-order readiness
      requirements.
    anchor: >-
      services-commerce:modules/fulfillment/services/policies/policy-resolution.ts:resolveGate
    seam: sync
    on_failure: Refuse placement before retaining sale records.
    left_inconsistent: No placement state remains.
    observer: Request refusal response.
    provenance: test
    source: >-
      services-commerce:modules/fulfillment/tests/unit/policies/policy-resolution.spec.js#takes
      the product’s policy over the ordering profile’s and the tenant default’s
  - 'n': 2
    actor_or_service: Orders placement transaction
    action: >-
      Convert checkout holds or claim units, retaining permitted backorders and
      rejecting any forbidden shortage.
    anchor: 'services-commerce:modules/orders/services/placement/claims-at-placement.ts'
    seam: sync
    on_failure: Roll back placement and return the item’s claim conflict.
    left_inconsistent: The failed placement retains no partial claim.
    observer: Placement conflict response and checkout history.
    provenance: documented
    source: 'services-commerce:docs/migrations/inventory/README.md#D-P8I-21'
  - 'n': 3
    actor_or_service: Orders placement transaction
    action: >-
      Retain order lines and pending obligations with frozen gates and their
      prerequisite-line links.
    anchor: >-
      services-commerce:modules/fulfillment/services/persistence/obligations.ts:createObligations
    seam: sync
    on_failure: Roll back the placing transaction.
    left_inconsistent: Neither order nor obligation creation survives that failure.
    observer: Retained order history.
    provenance: test
    source: >-
      services-commerce:modules/fulfillment/tests/e2e/fulfillment-policies.e2e.spec.js#freezes
      the product policy on the obligation with the row’s version and source,
      and the replacement changes nothing on it
  - 'n': 4
    actor_or_service: Orders billing and acceptance (after commit)
    action: 'Run billing, then evaluate delivery when the order is accepted.'
    anchor: 'services-commerce:modules/orders/services/orders/accept-order.ts'
    seam: sync
    on_failure: >-
      Leave pending billing to its recovery process; bounded pending scans can
      revisit missed evaluation after ten minutes of inactivity.
    left_inconsistent: Delivery can remain pending without a recovery deadline.
    observer: Billing findings and sweep evaluation results.
    provenance: observed
    source: >-
      services-commerce:modules/fulfillment/services/register/gate-evaluation.ts:evaluateObligationsOfLines
branches:
  - >-
    A line whose policy has no financial condition still waits for the order to
    be accepted.
  - >-
    A migrated order writes its obligations in their final state instead (data
    jobs).
waits:
  - 'The order''s acceptance (billing, a tender, or terms).'
evidence:
  - >-
    services-commerce at c8b66a98:
    modules/orders/services/placement/place-order.ts (TX-P),
    claims-at-placement.ts;
    modules/fulfillment/services/policies/policy-resolution.ts;
    services/persistence/obligations.ts;
    modules/orders/services/orders/accept-order.ts.
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-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]
---

# Freeze Delivery Gates When an Order Is Placed

## What It Does

Placement fixes the delivery conditions of each sold line and commits the stock promise with the order. Application preparation can add approval or readiness requirements; member-priced dependents retain the membership line they need. Billing and gate evaluation then run as later stages.

## The Flow

```mermaid
sequenceDiagram
  participant O as Orders placement
  participant P as Policy resolution
  participant C as Claim functions
  participant R as Register
  O->>P: staff closure each line's gate
  P-->>O: frozen gate, version, source
  O->>C: commit claims (one transaction)
  C-->>O: committed or conflict
  O->>R: write obligations pending
  O-->>O: commit
  O->>R: on acceptance, evaluate obligations
```

## When Something Fails

A refused placement rolls back its order, claims and obligations together. Later billing or evaluation can remain unfinished. Recovery scans are bounded and do not promise completion within ten minutes.
