---
id: STATE-COM-FUL-010
title: Shelf count 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: open
    meaning: The record is active and available for its next staff or workflow action.
  - name: completed
    meaning: The owning process has retained the required completed outcome.
  - name: cancelled
    meaning: >-
      The owning process withdrew the work under its permitted cancellation
      checks.
transitions:
  - from: open
    to: completed
    trigger: The owning workflow retains its required final successful result.
    guard: Completion must find an open count.
    side_effects:
      - >-
        Write a correction movement for each differing count line under that
        line’s stable key.
      - Counted items stamped including the count time.
    who: Administrator (inventory update)
    provenance: observed
    source: >-
      services-commerce:modules/inventory/services/persistence/inventory-counts.ts:completeCount
  - from: open
    to: cancelled
    trigger: The owning process withdraws work before departure or delivery permits it.
    guard: Cancellation must find an open count.
    side_effects: []
    who: Administrator
    provenance: observed
    source: >-
      services-commerce:modules/inventory/services/persistence/inventory-counts.ts:cancelCount
  - from: open
    to: open
    trigger: >-
      The owning process records another allowed update without changing this
      state.
    guard: Counted items must belong to the selected warehouse and location scope.
    side_effects:
      - >-
        Snapshot the current on-hand quantity as each count line’s expected
        quantity.
    who: Administrator
    provenance: observed
    source: >-
      services-commerce:modules/inventory/services/persistence/inventory-counts.ts:recordCountLines
invalid:
  - from: completed
    to: open
    why: >-
      Completion remains final for this action; use the owning replacement or
      correction process.
  - from: cancelled
    to: completed
    why: Cancelled work cannot be restarted through this lifecycle.
concurrency: >-
  Completion locks the count and compares observations with current on-hand. The
  recorded expectation can be older than intervening stock movements.
invariants:
  - INV-DOM-COM-FUL-005-10
evidence:
  - >-
    services-commerce at c8b66a98:
    modules/inventory/db/inventory-counts.table.ts,
    inventory-count-lines.table.ts; services/persistence/inventory-counts.ts.
---

# Shelf Count Lifecycle

## The Lifecycle

```mermaid
stateDiagram-v2
  [*] --> open
  open --> open: lines recorded
  open --> completed
  open --> cancelled
  completed --> [*]
  cancelled --> [*]
```

## Transitions Explained

A count opens without lines. Recording or recounting stores the observed quantity and the expectation at that moment. Completion compares the count with current on-hand and writes correction movements; cancellation leaves the ledger alone.

## What Cannot Happen

Terminal counts refuse edits and another completion. Counts use the movement ledger rather than assigning balances directly.

## Concurrency and Timing

Stock can move while staff count. Completion uses current balances and stable correction keys, so it does not treat the earlier recorded expectation as current truth.
