Skip to content

Stock/concurrency invariants — explicit transfer guard + verification (audit-M-stock)#206

Merged
OneTwo3D merged 2 commits into
developmentfrom
feature/w4-stock-concurrency
Jun 13, 2026
Merged

Stock/concurrency invariants — explicit transfer guard + verification (audit-M-stock)#206
OneTwo3D merged 2 commits into
developmentfrom
feature/w4-stock-concurrency

Conversation

@OneTwo3D

Copy link
Copy Markdown
Owner

Wave 4 of the workflow-audit remediation (epic onetwo3d-ims-r3xh). Stock/concurrency cluster (bkhk).

Most findings were already closed by prior work; this PR makes the remaining guard explicit + regression-tested and documents the cluster.

  1. Transfer-of-allocated-stock — dispatch availability already nets the source warehouse's per-(product,warehouse) reservedQty (kept in sync with order allocations), so a transfer can't strand an order. Extracted that rule into a pure availableForTransfer / canDispatchTransferQty helper (now used by dispatch) so it's explicit and regression-tested.
  2. Manual receipt + WMS booked-in double-layer — VERIFIED resolved: reconcileBookedInQuantities nets localReceivedQty (read under the PO FOR UPDATE lock); covered by mintsoft-phase6-booked-in tests.
  3. Opening-stock race — VERIFIED resolved: applyOpeningStock takes a FOR UPDATE lock on the stock level before the existing-opening-layer check, serialising concurrent calls.
  4. Transfer FIFO ordering at destination — documented + accepted (cosmetic; per-layer cost basis preserved).
  5. stock_levels CHECK >= 0 — VERIFIED present (migration 20260512100000: quantity>=0, reservedQty>=0, reservedQty<=quantity).

All five documented in docs/workflows.md under "Stock / concurrency invariants".

Tests

5 transfer-availability cases (nets reserved, never negative, missing level, can't-dispatch-into-reserved, full unreserved); type-check + lint clean.

Closes onetwo3d-ims-bkhk.

…ck invariants (closes audit-M-stock)

Stock/concurrency cluster (bkhk). Most findings were already resolved by prior
work; this makes the remaining guard explicit + tested and documents the rest:

1. Transfer-of-allocated-stock: dispatch availability already nets the source
   warehouse's per-(product,warehouse) reservedQty (kept in sync with order
   allocations), so a transfer can't strand an order. Extracted that rule into a
   pure availableForTransfer/canDispatchTransferQty helper (used by dispatch) so
   it's explicit and regression-tested.
2. Manual receipt + WMS booked-in double-layer: VERIFIED resolved —
   reconcileBookedInQuantities nets localReceivedQty (read under the PO FOR UPDATE
   lock); already covered by mintsoft-phase6-booked-in tests.
3. Opening-stock race: VERIFIED resolved — applyOpeningStock takes a FOR UPDATE
   lock on the stock level before the existing-opening-layer check, serialising
   concurrent calls.
4. Transfer FIFO ordering at destination: documented + accepted (cosmetic; per
   layer cost basis preserved).
5. stock_levels CHECK >= 0: VERIFIED present (migration 20260512100000:
   quantity>=0, reservedQty>=0, reservedQty<=quantity).

Documented all five in docs/workflows.md under Stock / concurrency invariants.

Tests: 5 transfer-availability cases; type-check + lint clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

…rsarial review)

Codex adversarial pass on PR #206 (verified all three 'already-resolved' claims
are substantively correct; no refuted claims):

MEDIUM — the extracted helper clamped a negative (over-reserved) available to 0,
so the dispatch error message showed '0 available' instead of the real negative
delta, hiding a data-integrity signal. The error now reports the raw (unclamped)
delta while the clamped value still gates dispatch.

MEDIUM — docs overstated the reservedQty<=quantity constraint: it's NOT VALID
(new-writes-only, never validated against historical rows), unlike the fully
VALIDATEd quantity>=0 / reservedQty>=0. Docs corrected, and note the transfer
guard (not just the constraint) is what protects allocations.

LOW — docs now mention both the PO and stock-transfer FOR UPDATE locks for the
WMS reconcile; JSDoc warns availableForTransfer's clamp must not be reused for
data-integrity checks; added an over-reserved canDispatchTransferQty test.

6/6 helper tests; type-check + lint clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@OneTwo3D

Copy link
Copy Markdown
Owner Author

Codex adversarial review — findings + fixes (commit 0ae2085)

Codex was at its usage cap; the adversarial pass ran by hand with equal rigour. It independently verified all three "already-resolved" claims are substantively correct (reconcile nets localReceivedQty under the PO/transfer FOR UPDATE lock; applyOpeningStock's lock serialises concurrent calls; the non-negative CHECK constraints exist) — no refuted claims. The extracted helper is behaviourally equivalent to the old inline check (no reject↔allow flips).

Fixed:

  • MEDIUM — diagnostic loss. The helper clamps a negative (over-reserved) available to 0, so the dispatch error showed "0 available" instead of the real negative delta. The error now reports the raw delta while the clamped value still gates dispatch.
  • MEDIUM — docs precision. reservedQty <= quantity is a NOT VALID constraint (new-writes-only, never validated against historical rows), unlike the fully-VALIDATEd quantity>=0/reservedQty>=0. Docs corrected, noting the transfer guard (not just the constraint) protects allocations.
  • LOW: docs now mention both the PO and transfer FOR UPDATE locks; JSDoc warns availableForTransfer's clamp must not be reused for data-integrity checks; added an over-reserved canDispatchTransferQty test.

Validation

6/6 helper tests; type-check + lint clean.

@OneTwo3D OneTwo3D merged commit d0f2b38 into development Jun 13, 2026
5 of 11 checks passed
@OneTwo3D OneTwo3D deleted the feature/w4-stock-concurrency branch June 13, 2026 17:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant