{
  "name": "Commerce Integration Failure Atlas",
  "publisher": "Elogic Commerce",
  "version": "1.1.0",
  "generated_at": "2026-08-01",
  "canonical": "https://elogic.co/commerce-integration-failure-atlas/",
  "record_count": 40,
  "evidence_scope": "All launch records are Evidence Class D reproducible synthetic fixtures.",
  "license": {
    "recommended": "Creative Commons Attribution 4.0",
    "status": "Subject to Elogic Commerce legal approval",
    "url": "https://creativecommons.org/licenses/by/4.0/"
  },
  "records": [
    {
      "id": "CIF-001",
      "slug": "duplicate-order-after-webhook-retry",
      "anchor": "cif-001-duplicate-order-after-webhook-retry",
      "title": "Duplicate order after webhook retry",
      "category": "orders_and_fulfillment",
      "category_label": "Orders and fulfillment",
      "severity": "Critical",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "Commerce → OMS/ERP",
      "symptom": "One customer checkout creates two downstream orders or two fulfillment requests.",
      "root_cause": "The receiver creates the order before it records the event or idempotency key. The sender retries after a timeout, and the second delivery creates the same business action again.",
      "detection": "Search for one commerce order ID mapped to more than one downstream order ID. Alert on repeated event IDs and repeated idempotency keys with different results.",
      "control": "Store the event ID or business idempotency key before the side effect. Return the original result for a safe repeat. Keep a unique constraint on the source order ID.",
      "test": "Given one valid order-created event, when the identical event is delivered twice and the first response is delayed, then only one downstream order exists and both deliveries return the same mapped order ID.",
      "given": "one valid order-created event",
      "when": "the identical event is delivered twice and the first response is delayed",
      "then": "only one downstream order exists and both deliveries return the same mapped order ID.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "idempotency",
        "event-identity",
        "bounded-retries"
      ],
      "system_tags": [
        "commerce",
        "erp",
        "oms"
      ]
    },
    {
      "id": "CIF-002",
      "slug": "order-lost-after-a-partial-failure",
      "anchor": "cif-002-order-lost-after-a-partial-failure",
      "title": "Order lost after a partial failure",
      "category": "orders_and_fulfillment",
      "category_label": "Orders and fulfillment",
      "severity": "Critical",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "Commerce → Queue → ERP",
      "symptom": "The customer receives an order number, but the ERP never receives the order and no visible error remains.",
      "root_cause": "The integration marks the message complete before the downstream write is durable, or it writes one part of the order and fails before the completion state is recorded.",
      "detection": "Reconcile commerce orders against ERP orders by source order ID. Alert when a confirmed commerce order has no downstream mapping after the agreed time window.",
      "control": "Use transactional outbox or equivalent durable handoff. Acknowledge the message only after the downstream result and mapping are stored. Add scheduled reconciliation.",
      "test": "Given a confirmed order, when the ERP call succeeds but the integration process stops before acknowledgement, then a retry restores the same mapping without losing or duplicating the order.",
      "given": "a confirmed order",
      "when": "the ERP call succeeds but the integration process stops before acknowledgement",
      "then": "a retry restores the same mapping without losing or duplicating the order.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "bounded-retries",
        "reconciliation"
      ],
      "system_tags": [
        "commerce",
        "erp",
        "queue"
      ]
    },
    {
      "id": "CIF-003",
      "slug": "cancelled-order-ships-because-of-a-race-condition",
      "anchor": "cif-003-cancelled-order-ships-because-of-a-race-condition",
      "title": "Cancelled order ships because of a race condition",
      "category": "orders_and_fulfillment",
      "category_label": "Orders and fulfillment",
      "severity": "Critical",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "Commerce ↔ OMS/WMS",
      "symptom": "An order is cancelled in commerce but still reaches pick, pack, or shipment in the fulfillment system.",
      "root_cause": "The create-order and cancel-order events travel on different paths or arrive out of order. The fulfillment system accepts the earlier state after the cancellation is already final.",
      "detection": "Find shipments created after a final cancellation timestamp. Track state transitions that move from cancelled back to open or allocated.",
      "control": "Use entity versions or sequence numbers. Reject stale transitions. Define which system owns final fulfillment state and use a cancellation acknowledgement before promising success to the customer.",
      "test": "Given order version 8 is cancelled, when an older version 7 allocation event arrives later, then the OMS rejects the stale event and no shipment is created.",
      "given": "order version 8 is cancelled",
      "when": "an older version 7 allocation event arrives later",
      "then": "the OMS rejects the stale event and no shipment is created.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "ordering-and-version"
      ],
      "system_tags": [
        "commerce",
        "oms",
        "wms"
      ]
    },
    {
      "id": "CIF-004",
      "slug": "split-shipment-overwrites-the-full-order-status",
      "anchor": "cif-004-split-shipment-overwrites-the-full-order-status",
      "title": "Split shipment overwrites the full order status",
      "category": "orders_and_fulfillment",
      "category_label": "Orders and fulfillment",
      "severity": "High",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "WMS/Carrier → OMS → Commerce",
      "symptom": "The first partial shipment marks the whole order as shipped, or the second shipment resets tracking from the first parcel.",
      "root_cause": "The receiver treats a line-level or shipment-level event as an order-level replacement. It does not merge shipment state by shipment ID and order line.",
      "detection": "Compare shipped quantities by line with the order-level status. Alert when order status is complete while open quantity remains.",
      "control": "Model shipments as separate entities. Merge by shipment ID, line ID, and quantity. Derive order status from all shipment states instead of copying one event status.",
      "test": "Given an order with two lines and two shipments, when only the first shipment is confirmed, then one line is shipped, the other remains open, and both tracking records remain available.",
      "given": "an order with two lines and two shipments",
      "when": "only the first shipment is confirmed",
      "then": "one line is shipped, the other remains open, and both tracking records remain available.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "reconciliation"
      ],
      "system_tags": [
        "commerce",
        "oms",
        "wms",
        "carrier"
      ]
    },
    {
      "id": "CIF-005",
      "slug": "duplicate-shipment-after-fulfillment-replay",
      "anchor": "cif-005-duplicate-shipment-after-fulfillment-replay",
      "title": "Duplicate shipment after fulfillment replay",
      "category": "orders_and_fulfillment",
      "category_label": "Orders and fulfillment",
      "severity": "Critical",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "OMS/WMS → Carrier",
      "symptom": "A recovery replay creates a second carrier label, tracking number, or shipment for an order that already shipped.",
      "root_cause": "The replay tool resends a command without checking the effect ledger. The carrier endpoint accepts the repeated label request as a new action.",
      "detection": "Find multiple active labels for the same shipment intent. Compare replay logs with carrier label creation times.",
      "control": "Use a stable shipment idempotency key. Store the carrier result. Make replay default to dry-run and require approval for commands that create external effects.",
      "test": "Given a shipment already has a carrier label, when its create-label command is replayed, then the existing label is returned and no second billable label is created.",
      "given": "a shipment already has a carrier label",
      "when": "its create-label command is replayed",
      "then": "the existing label is returned and no second billable label is created.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "idempotency",
        "reconciliation",
        "replay-safety"
      ],
      "system_tags": [
        "oms",
        "wms",
        "carrier"
      ]
    },
    {
      "id": "CIF-006",
      "slug": "old-order-status-restored-by-an-out-of-order-event",
      "anchor": "cif-006-old-order-status-restored-by-an-out-of-order-event",
      "title": "Old order status restored by an out-of-order event",
      "category": "orders_and_fulfillment",
      "category_label": "Orders and fulfillment",
      "severity": "High",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "ERP/OMS → Commerce",
      "symptom": "An order moves from shipped or cancelled back to processing after delayed integration traffic.",
      "root_cause": "The receiver applies events by arrival time and does not compare entity version, sequence, or allowed state transition.",
      "detection": "Alert on backward state transitions and events whose source version is below the stored version.",
      "control": "Use a monotonic version or sequence per order. Validate transitions against a state machine. Quarantine stale or impossible events for review.",
      "test": "Given stored order version 12 is shipped, when version 10 with status processing arrives, then the event is rejected, logged as stale, and the order remains shipped.",
      "given": "stored order version 12 is shipped",
      "when": "version 10 with status processing arrives",
      "then": "the event is rejected, logged as stale, and the order remains shipped.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "ordering-and-version",
        "reconciliation"
      ],
      "system_tags": [
        "commerce",
        "erp",
        "oms"
      ]
    },
    {
      "id": "CIF-007",
      "slug": "stale-contract-price-cache",
      "anchor": "cif-007-stale-contract-price-cache",
      "title": "Stale contract price cache",
      "category": "pricing_and_promotions",
      "category_label": "Pricing and promotions",
      "severity": "Critical",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "ERP/Pricing → Commerce cache",
      "symptom": "A B2B buyer sees or orders at an old contract price after the ERP price has changed.",
      "root_cause": "Price cache entries do not include account, contract, currency, unit, or effective date, or invalidation fails after a source update.",
      "detection": "Compare quoted and ordered price with the authoritative price response for the same account, SKU, unit, currency, and time.",
      "control": "Use a complete cache key, short and explicit expiry, event-based invalidation, and a final server-side price check before order acceptance.",
      "test": "Given a buyer contract price changes from 100 to 92, when the invalidation event is delayed, then checkout revalidates against the pricing source and does not accept the stale price.",
      "given": "a buyer contract price changes from 100 to 92",
      "when": "the invalidation event is delayed",
      "then": "checkout revalidates against the pricing source and does not accept the stale price.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "system-of-record",
        "reconciliation"
      ],
      "system_tags": [
        "commerce",
        "erp",
        "pricing"
      ]
    },
    {
      "id": "CIF-008",
      "slug": "currency-conversion-mismatch",
      "anchor": "cif-008-currency-conversion-mismatch",
      "title": "Currency conversion mismatch",
      "category": "pricing_and_promotions",
      "category_label": "Pricing and promotions",
      "severity": "High",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "ERP/Pricing ↔ Commerce ↔ Payment",
      "symptom": "The storefront total, authorized amount, and ERP order value differ by rounding or exchange-rate timing.",
      "root_cause": "Systems use different rates, decimal precision, rounding modes, or conversion timestamps. One system converts line values while another converts the final total.",
      "detection": "Reconcile line, tax, discount, shipping, and grand total in both source and settlement currencies. Keep the rate and rounding method used.",
      "control": "Define one conversion owner and one rounding policy. Send the source amount, target amount, rate, timestamp, and precision with the order.",
      "test": "Given a three-line order in EUR settled in USD, when the same rate and half-up rounding are applied, then line totals, tax, grand total, authorization, and ERP value reconcile to the defined tolerance.",
      "given": "a three-line order in EUR settled in USD",
      "when": "the same rate and half-up rounding are applied",
      "then": "line totals, tax, grand total, authorization, and ERP value reconcile to the defined tolerance.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "system-of-record",
        "ordering-and-version",
        "reconciliation",
        "least-privilege"
      ],
      "system_tags": [
        "commerce",
        "erp",
        "pricing",
        "payment"
      ]
    },
    {
      "id": "CIF-009",
      "slug": "tax-inclusive-and-tax-exclusive-price-mix",
      "anchor": "cif-009-tax-inclusive-and-tax-exclusive-price-mix",
      "title": "Tax-inclusive and tax-exclusive price mix",
      "category": "pricing_and_promotions",
      "category_label": "Pricing and promotions",
      "severity": "Critical",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "ERP/PIM → Commerce → Tax",
      "symptom": "Tax is added twice, removed twice, or displayed differently from the final charge.",
      "root_cause": "A price field is sent without a tax-basis flag, or the receiving system assumes the opposite basis for the market or customer type.",
      "detection": "Compare the stored net, tax, and gross values against the configured market rule. Alert when gross is not equal to net plus tax within tolerance.",
      "control": "Include tax basis, jurisdiction, rate source, and currency in the price contract. Keep display calculation separate from final tax calculation.",
      "test": "Given a gross price of 120 with 20% VAT, when the record enters a tax-exclusive market flow, then the system derives 100 net and 20 tax once, not twice.",
      "given": "a gross price of 120 with 20% VAT",
      "when": "the record enters a tax-exclusive market flow",
      "then": "the system derives 100 net and 20 tax once, not twice.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "reconciliation"
      ],
      "system_tags": [
        "commerce",
        "erp",
        "tax",
        "pim"
      ]
    },
    {
      "id": "CIF-010",
      "slug": "promotion-precedence-conflict",
      "anchor": "cif-010-promotion-precedence-conflict",
      "title": "Promotion precedence conflict",
      "category": "pricing_and_promotions",
      "category_label": "Pricing and promotions",
      "severity": "High",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "Commerce ↔ Promotion engine/ERP",
      "symptom": "A coupon, contract price, tier price, bundle rule, and free-shipping rule combine in an unintended order.",
      "root_cause": "The systems use different rule priority, exclusivity, or stacking logic. The integration sends only the final value without the applied-rule ledger.",
      "detection": "Store and compare the ordered list of applied rule IDs, base price, adjustments, and final price. Test rule pairs and boundary dates.",
      "control": "Define precedence centrally. Send rule IDs and adjustment reasons. Make mutually exclusive rules explicit and reject unknown combinations.",
      "test": "Given a contract price and a non-stackable campaign coupon, when both conditions match, then the contract rule wins, the coupon is rejected with a reason, and the final price is identical in commerce and ERP.",
      "given": "a contract price and a non-stackable campaign coupon",
      "when": "both conditions match",
      "then": "the contract rule wins, the coupon is rejected with a reason, and the final price is identical in commerce and ERP.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "reconciliation"
      ],
      "system_tags": [
        "commerce",
        "erp"
      ]
    },
    {
      "id": "CIF-011",
      "slug": "unit-of-measure-price-mismatch",
      "anchor": "cif-011-unit-of-measure-price-mismatch",
      "title": "Unit-of-measure price mismatch",
      "category": "pricing_and_promotions",
      "category_label": "Pricing and promotions",
      "severity": "Critical",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "ERP → Commerce",
      "symptom": "A case, pack, meter, kilogram, or each price is shown or ordered as if it used another unit.",
      "root_cause": "The integration maps a numeric price but loses the sales unit, base unit, conversion factor, or minimum order quantity.",
      "detection": "Compare price per sales unit and price per base unit. Alert when the unit is missing or the conversion factor is zero, negative, or changed without review.",
      "control": "Treat unit of measure as part of the price identity. Store conversion factors with effective dates. Validate quantity multiples at cart and order creation.",
      "test": "Given one case contains 12 each and the case price is 120, when a buyer orders two cases, then quantity is 24 each for inventory and total price is 240, not 20 or 2,880.",
      "given": "one case contains 12 each and the case price is 120",
      "when": "a buyer orders two cases",
      "then": "quantity is 24 each for inventory and total price is 240, not 20 or 2,880.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "ordering-and-version",
        "reconciliation"
      ],
      "system_tags": [
        "commerce",
        "erp"
      ]
    },
    {
      "id": "CIF-012",
      "slug": "oversell-caused-by-inventory-lag",
      "anchor": "cif-012-oversell-caused-by-inventory-lag",
      "title": "Oversell caused by inventory lag",
      "category": "inventory_and_availability",
      "category_label": "Inventory and availability",
      "severity": "Critical",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "ERP/WMS → Commerce",
      "symptom": "The storefront accepts more units than can be fulfilled during fast sales or concurrent orders.",
      "root_cause": "Availability is copied on a schedule and no reservation or final availability check protects the gap between display and order acceptance.",
      "detection": "Track negative available-to-promise, cancellation for no stock, and the age of the last inventory update by SKU and source.",
      "control": "Separate on-hand, reserved, safety stock, and available-to-promise. Use reservations or an authoritative check for scarce items. Reduce cache age during peaks.",
      "test": "Given one unit is available, when two checkouts confirm at the same time, then only one reservation succeeds and the second buyer receives a controlled out-of-stock result.",
      "given": "one unit is available",
      "when": "two checkouts confirm at the same time",
      "then": "only one reservation succeeds and the second buyer receives a controlled out-of-stock result.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "system-of-record"
      ],
      "system_tags": [
        "commerce",
        "erp",
        "wms"
      ]
    },
    {
      "id": "CIF-013",
      "slug": "multi-source-allocation-mismatch",
      "anchor": "cif-013-multi-source-allocation-mismatch",
      "title": "Multi-source allocation mismatch",
      "category": "inventory_and_availability",
      "category_label": "Inventory and availability",
      "severity": "High",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "Commerce ↔ OMS/WMS",
      "symptom": "The storefront promises stock that exists globally but cannot be allocated to the buyer’s location, service level, or legal entity.",
      "root_cause": "Commerce aggregates inventory across sources while the OMS applies routing, region, hazmat, carrier, or warehouse rules that were not included in availability.",
      "detection": "Compare promised source with final allocated source. Track orders that change warehouse, split unexpectedly, or fail allocation after checkout.",
      "control": "Use source-aware availability or an OMS availability service. Include location, channel, service level, and restrictions in the availability request.",
      "test": "Given stock exists only in a warehouse that cannot serve the buyer’s region, when availability is requested for that address, then the item is not promised from that source.",
      "given": "stock exists only in a warehouse that cannot serve the buyer’s region",
      "when": "availability is requested for that address",
      "then": "the item is not promised from that source.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "reconciliation"
      ],
      "system_tags": [
        "commerce",
        "oms",
        "wms"
      ]
    },
    {
      "id": "CIF-014",
      "slug": "backorder-state-lost-between-systems",
      "anchor": "cif-014-backorder-state-lost-between-systems",
      "title": "Backorder state lost between systems",
      "category": "inventory_and_availability",
      "category_label": "Inventory and availability",
      "severity": "High",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "ERP/OMS ↔ Commerce",
      "symptom": "An item allowed for backorder becomes unavailable, or an unavailable item is promised without an expected date.",
      "root_cause": "The integration sends quantity but not backorder policy, expected receipt, promise date, channel rule, or customer eligibility.",
      "detection": "Compare quantity, sellable state, backorder flag, and promise date. Alert when backorder is true without a date or policy source.",
      "control": "Define an availability contract with quantity, state, reason, expected date, and policy version. Treat backorder as a business state, not a negative number.",
      "test": "Given zero on-hand and backorder allowed for a specific account with a 14-day promise, when the buyer opens the product, then the item is orderable with the correct promise and the state persists into the order.",
      "given": "zero on-hand and backorder allowed for a specific account with a 14-day promise",
      "when": "the buyer opens the product",
      "then": "the item is orderable with the correct promise and the state persists into the order.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "ordering-and-version",
        "reconciliation"
      ],
      "system_tags": [
        "commerce",
        "erp",
        "oms"
      ]
    },
    {
      "id": "CIF-015",
      "slug": "reservation-not-released-after-payment-failure",
      "anchor": "cif-015-reservation-not-released-after-payment-failure",
      "title": "Reservation not released after payment failure",
      "category": "inventory_and_availability",
      "category_label": "Inventory and availability",
      "severity": "Critical",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "Commerce ↔ Inventory service ↔ Payment",
      "symptom": "Sellable stock remains blocked after payment decline, timeout, or abandoned checkout.",
      "root_cause": "Reservation creation is durable, but release depends on a callback that can be lost or on a session timeout that is not reconciled.",
      "detection": "Find reservations past their expiry with no paid order. Compare reserved quantity with active payment or order state.",
      "control": "Use explicit reservation expiry, idempotent release, and scheduled cleanup. Link reservation, cart, payment intent, and order with one correlation ID.",
      "test": "Given stock is reserved for a payment attempt, when the payment fails and the callback is lost, then expiry reconciliation releases the reservation once and returns availability.",
      "given": "stock is reserved for a payment attempt",
      "when": "the payment fails and the callback is lost",
      "then": "expiry reconciliation releases the reservation once and returns availability.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "idempotency",
        "bounded-retries",
        "reconciliation",
        "correlation-id"
      ],
      "system_tags": [
        "commerce",
        "payment",
        "inventory"
      ]
    },
    {
      "id": "CIF-016",
      "slug": "inventory-unit-of-measure-mismatch",
      "anchor": "cif-016-inventory-unit-of-measure-mismatch",
      "title": "Inventory unit-of-measure mismatch",
      "category": "inventory_and_availability",
      "category_label": "Inventory and availability",
      "severity": "Critical",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "ERP/WMS → Commerce",
      "symptom": "The storefront shows 120 units when the warehouse has 10 cases of 12, or subtracts one case for an order of one each.",
      "root_cause": "Quantity is transferred without base unit, sales unit, conversion factor, or packaging hierarchy.",
      "detection": "Validate quantity and unit together. Compare calculated base quantity with source on-hand and order decrements.",
      "control": "Use a unit-aware inventory contract. Convert only through versioned master data. Reject quantity records with unknown units.",
      "test": "Given inventory is 10 cases and one case is 12 each, when the storefront sells each units, then availability is 120 each and an order of 5 each leaves 115 each.",
      "given": "inventory is 10 cases and one case is 12 each",
      "when": "the storefront sells each units",
      "then": "availability is 120 each and an order of 5 each leaves 115 each.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "ordering-and-version",
        "reconciliation"
      ],
      "system_tags": [
        "commerce",
        "erp",
        "wms"
      ]
    },
    {
      "id": "CIF-017",
      "slug": "duplicate-customer-identities",
      "anchor": "cif-017-duplicate-customer-identities",
      "title": "Duplicate customer identities",
      "category": "customer_and_b2b_accounts",
      "category_label": "Customer and B2B accounts",
      "severity": "High",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "Commerce ↔ CRM/ERP/Identity",
      "symptom": "One buyer has multiple customer IDs, order histories, price groups, or consent records.",
      "root_cause": "Each system creates a record before a shared identity or match decision exists. Email is used as a universal key even when accounts, regions, or legal entities differ.",
      "detection": "Find multiple active identities with the same verified contact, external ID, tax ID, or account relationship. Track merge and split events.",
      "control": "Define a master identity and immutable cross-system IDs. Use deterministic match rules plus a reviewed exception queue. Never merge only because names look similar.",
      "test": "Given an existing verified customer with CRM ID C-42, when the same person registers through another storefront, then the new login links to C-42 or enters review instead of creating an uncontrolled duplicate.",
      "given": "an existing verified customer with CRM ID C-42",
      "when": "the same person registers through another storefront",
      "then": "the new login links to C-42 or enters review instead of creating an uncontrolled duplicate.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "system-of-record",
        "idempotency"
      ],
      "system_tags": [
        "commerce",
        "erp",
        "crm",
        "identity"
      ]
    },
    {
      "id": "CIF-018",
      "slug": "parent-child-account-hierarchy-drift",
      "anchor": "cif-018-parent-child-account-hierarchy-drift",
      "title": "Parent-child account hierarchy drift",
      "category": "customer_and_b2b_accounts",
      "category_label": "Customer and B2B accounts",
      "severity": "Critical",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "ERP/CRM → Commerce",
      "symptom": "A buyer sees the wrong branches, contracts, invoices, addresses, or approval limits.",
      "root_cause": "The hierarchy update is partial, arrives out of order, or replaces only one side of the parent-child relationship.",
      "detection": "Validate that every child has one valid parent for the effective period. Compare account tree versions across systems.",
      "control": "Transfer hierarchy as versioned relationships with effective dates. Apply the full change atomically or use a staged graph validation before activation.",
      "test": "Given branch B moves from parent A to parent C at midnight, when the new hierarchy activates, then B loses A permissions, gains C permissions, and no interval grants both.",
      "given": "branch B moves from parent A to parent C at midnight",
      "when": "the new hierarchy activates",
      "then": "B loses A permissions, gains C permissions, and no interval grants both.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "ordering-and-version",
        "reconciliation",
        "least-privilege"
      ],
      "system_tags": [
        "commerce",
        "erp",
        "crm"
      ]
    },
    {
      "id": "CIF-019",
      "slug": "buyer-role-permission-lag",
      "anchor": "cif-019-buyer-role-permission-lag",
      "title": "Buyer role permission lag",
      "category": "customer_and_b2b_accounts",
      "category_label": "Customer and B2B accounts",
      "severity": "Critical",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "Identity/CRM → Commerce",
      "symptom": "A removed buyer can still place orders, view prices, approve quotes, or access another role’s data.",
      "root_cause": "Role changes use a long cache or session token and no revocation event reaches the storefront.",
      "detection": "Compare token claims and session age with the current role version. Alert on privileged actions from a revoked or stale role.",
      "control": "Use short-lived authorization claims for sensitive actions, a role version, revocation, and server-side authorization at the action boundary.",
      "test": "Given a buyer’s approval role is removed, when the existing session attempts to approve an order, then the server checks the new role version and denies the action.",
      "given": "a buyer’s approval role is removed",
      "when": "the existing session attempts to approve an order",
      "then": "the server checks the new role version and denies the action.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "ordering-and-version",
        "bounded-retries",
        "reconciliation",
        "least-privilege"
      ],
      "system_tags": [
        "commerce",
        "crm",
        "identity"
      ]
    },
    {
      "id": "CIF-020",
      "slug": "credit-status-lag",
      "anchor": "cif-020-credit-status-lag",
      "title": "Credit status lag",
      "category": "customer_and_b2b_accounts",
      "category_label": "Customer and B2B accounts",
      "severity": "Critical",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "ERP/Credit service → Commerce",
      "symptom": "An account on credit hold places a net-terms order, or an approved account is blocked after the hold is cleared.",
      "root_cause": "Credit state is cached without effective time, or the order checks only the value shown when the cart was created.",
      "detection": "Compare order acceptance time with the authoritative credit status and version. Track manual release of orders blocked or accepted incorrectly.",
      "control": "Perform a final credit check at order submission. Include account, legal entity, currency, exposure, limit, status, version, and effective time.",
      "test": "Given an account moves to credit hold after cart creation, when the buyer submits the order, then the final check blocks net terms and records the current reason.",
      "given": "an account moves to credit hold after cart creation",
      "when": "the buyer submits the order",
      "then": "the final check blocks net terms and records the current reason.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "system-of-record",
        "ordering-and-version",
        "reconciliation"
      ],
      "system_tags": [
        "commerce",
        "erp",
        "credit"
      ]
    },
    {
      "id": "CIF-021",
      "slug": "variant-mapping-collision",
      "anchor": "cif-021-variant-mapping-collision",
      "title": "Variant mapping collision",
      "category": "catalog_and_product_data",
      "category_label": "Catalog and product data",
      "severity": "Critical",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "PIM/ERP → Commerce",
      "symptom": "Two source variants map to one commerce SKU, or one variant overwrites another size, color, or configuration.",
      "root_cause": "The target key is built from a non-unique field, normalized values collide, or the mapping ignores market and product family.",
      "detection": "Enforce uniqueness on source system plus source ID. Report any target SKU receiving more than one active source record.",
      "control": "Use immutable source identifiers and a mapping table. Validate uniqueness before publish. Never derive identity only from display labels.",
      "test": "Given two variants share the label “Blue” but have different source IDs, when both are imported, then they remain distinct and no product data is overwritten.",
      "given": "two variants share the label “Blue” but have different source IDs",
      "when": "both are imported",
      "then": "they remain distinct and no product data is overwritten.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "system-of-record"
      ],
      "system_tags": [
        "commerce",
        "erp",
        "pim"
      ]
    },
    {
      "id": "CIF-022",
      "slug": "missing-locale-fallback",
      "anchor": "cif-022-missing-locale-fallback",
      "title": "Missing locale fallback",
      "category": "catalog_and_product_data",
      "category_label": "Catalog and product data",
      "severity": "Medium",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "PIM/CMS → Commerce",
      "symptom": "A product page shows blank content, the wrong language, or an unpublished source value in one store view.",
      "root_cause": "The integration treats a missing translation as an empty overwrite instead of applying the defined fallback or publication rule.",
      "detection": "Scan required attributes by locale before publish. Track empty values that replace non-empty target content.",
      "control": "Define fallback by field and market. Distinguish missing, intentionally blank, and inherited values. Block publication when regulated or required content is absent.",
      "test": "Given the French short description is missing and fallback to English is allowed, when the product publishes in France, then the approved English value appears and the missing translation is logged.",
      "given": "the French short description is missing and fallback to English is allowed",
      "when": "the product publishes in France",
      "then": "the approved English value appears and the missing translation is logged.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "system-of-record"
      ],
      "system_tags": [
        "commerce",
        "pim",
        "cms"
      ]
    },
    {
      "id": "CIF-023",
      "slug": "catalog-attribute-type-drift",
      "anchor": "cif-023-catalog-attribute-type-drift",
      "title": "Catalog attribute type drift",
      "category": "catalog_and_product_data",
      "category_label": "Catalog and product data",
      "severity": "High",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "PIM → Commerce/Search",
      "symptom": "A number becomes text, a multi-select becomes one value, or a date and unit can no longer be filtered or validated.",
      "root_cause": "The source schema changes without a versioned contract, or the receiver accepts a new type and silently coerces it.",
      "detection": "Validate every payload against the expected schema and unit. Alert on type coercion, unknown enum, and precision loss.",
      "control": "Version schemas. Use contract tests and explicit migration for type changes. Quarantine invalid records instead of publishing partial data.",
      "test": "Given `weight_kg` is numeric, when the source sends “heavy”, then the record is rejected with a schema error and the last valid product remains active.",
      "given": "`weight_kg` is numeric",
      "when": "the source sends “heavy”",
      "then": "the record is rejected with a schema error and the last valid product remains active.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "ordering-and-version"
      ],
      "system_tags": [
        "commerce",
        "pim",
        "search"
      ]
    },
    {
      "id": "CIF-024",
      "slug": "partial-media-synchronization",
      "anchor": "cif-024-partial-media-synchronization",
      "title": "Partial media synchronization",
      "category": "catalog_and_product_data",
      "category_label": "Catalog and product data",
      "severity": "High",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "DAM/PIM → Commerce/CDN",
      "symptom": "A product publishes before its primary image, video, document, alt text, or CDN derivative is available.",
      "root_cause": "The product and media pipelines commit separately, and the page becomes visible after only the product record succeeds.",
      "detection": "Validate required media references and HTTP availability before activation. Track orphan assets and broken derivatives.",
      "control": "Use staged publication. Activate the product only after required assets and metadata pass checks, or keep a deliberate approved placeholder.",
      "test": "Given a product requires one primary image and a safety PDF, when the PDF upload fails, then the product stays staged and does not publish with incomplete required media.",
      "given": "a product requires one primary image and a safety PDF",
      "when": "the PDF upload fails",
      "then": "the product stays staged and does not publish with incomplete required media.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "system-of-record"
      ],
      "system_tags": [
        "commerce",
        "pim",
        "dam",
        "cdn"
      ]
    },
    {
      "id": "CIF-025",
      "slug": "invalid-category-graph",
      "anchor": "cif-025-invalid-category-graph",
      "title": "Invalid category graph",
      "category": "catalog_and_product_data",
      "category_label": "Catalog and product data",
      "severity": "High",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "PIM/ERP → Commerce",
      "symptom": "Navigation loops, duplicate paths, orphan categories, or products disappear because the category tree is invalid.",
      "root_cause": "A parent reference points to a descendant, a deleted parent remains in use, or partial updates apply before graph validation.",
      "detection": "Run cycle detection, orphan checks, unique path checks, and maximum-depth checks before activation.",
      "control": "Build and validate the full graph in staging. Activate a version only when the graph is acyclic and all required references resolve.",
      "test": "Given category A contains B and an update sets A’s parent to B, when the new graph is validated, then activation is blocked and the live tree remains unchanged.",
      "given": "category A contains B and an update sets A’s parent to B",
      "when": "the new graph is validated",
      "then": "activation is blocked and the live tree remains unchanged.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "ordering-and-version"
      ],
      "system_tags": [
        "commerce",
        "erp",
        "pim"
      ]
    },
    {
      "id": "CIF-026",
      "slug": "payment-authorization-and-capture-mismatch",
      "anchor": "cif-026-payment-authorization-and-capture-mismatch",
      "title": "Payment authorization and capture mismatch",
      "category": "payments_tax_and_fraud",
      "category_label": "Payments, tax, and fraud",
      "severity": "Critical",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "Commerce ↔ Payment gateway ↔ ERP",
      "symptom": "The order is captured twice, captured for the wrong amount, or marked paid when only authorization exists.",
      "root_cause": "Authorization, capture, void, and refund are flattened into one paid flag, or retries use different business keys.",
      "detection": "Maintain a payment transaction ledger. Reconcile authorized, captured, voided, refunded, and disputed amounts by payment intent and order.",
      "control": "Model each payment operation separately. Use gateway idempotency keys, amount checks, and allowed state transitions.",
      "test": "Given an order has one authorization for 100, when capture is requested twice with the same key, then one capture of 100 exists and the second call returns the original result.",
      "given": "an order has one authorization for 100",
      "when": "capture is requested twice with the same key",
      "then": "one capture of 100 exists and the second call returns the original result.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "idempotency",
        "ordering-and-version",
        "bounded-retries",
        "reconciliation",
        "least-privilege"
      ],
      "system_tags": [
        "commerce",
        "erp",
        "payment"
      ]
    },
    {
      "id": "CIF-027",
      "slug": "unverified-or-replayed-payment-webhook",
      "anchor": "cif-027-unverified-or-replayed-payment-webhook",
      "title": "Unverified or replayed payment webhook",
      "category": "payments_tax_and_fraud",
      "category_label": "Payments, tax, and fraud",
      "severity": "Critical",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "Payment gateway → Commerce",
      "symptom": "A forged or repeated callback marks an order paid, changes payment state, or triggers fulfillment.",
      "root_cause": "The receiver does not verify the signature, timestamp, source, event ID, or current transaction state.",
      "detection": "Log signature result, event ID, source IP only as supporting data, event age, and state transition. Alert on invalid signatures and repeated events.",
      "control": "Verify the provider signature against the raw body. Enforce replay window and event uniqueness. Fetch authoritative payment state before high-risk actions when supported.",
      "test": "Given a valid captured-payment payload, when the signature is invalid or the timestamp is outside the replay window, then the event is rejected and order state does not change.",
      "given": "a valid captured-payment payload",
      "when": "the signature is invalid or the timestamp is outside the replay window",
      "then": "the event is rejected and order state does not change.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "system-of-record",
        "event-identity",
        "ordering-and-version",
        "replay-safety"
      ],
      "system_tags": [
        "commerce",
        "payment"
      ]
    },
    {
      "id": "CIF-028",
      "slug": "tax-jurisdiction-mismatch",
      "anchor": "cif-028-tax-jurisdiction-mismatch",
      "title": "Tax jurisdiction mismatch",
      "category": "payments_tax_and_fraud",
      "category_label": "Payments, tax, and fraud",
      "severity": "Critical",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "Commerce ↔ Tax service ↔ ERP",
      "symptom": "The tax shown or charged uses the wrong destination, product code, exemption, registration, or legal entity.",
      "root_cause": "Address normalization, nexus, customer exemption, product tax code, or legal entity differs between quote and final order systems.",
      "detection": "Store the tax request and response basis: normalized address, product code, exemption ID, jurisdiction, rate, and calculation version.",
      "control": "Use one final tax calculation owner. Recalculate after address, shipping, item, or exemption changes. Send the tax basis with the order.",
      "test": "Given an exempt B2B account with a valid certificate, when the final order is submitted, then the tax service receives the exemption and the ERP stores the same zero-tax basis.",
      "given": "an exempt B2B account with a valid certificate",
      "when": "the final order is submitted",
      "then": "the tax service receives the exemption and the ERP stores the same zero-tax basis.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "system-of-record",
        "ordering-and-version"
      ],
      "system_tags": [
        "commerce",
        "erp",
        "tax"
      ]
    },
    {
      "id": "CIF-029",
      "slug": "refund-reconciliation-failure",
      "anchor": "cif-029-refund-reconciliation-failure",
      "title": "Refund reconciliation failure",
      "category": "payments_tax_and_fraud",
      "category_label": "Payments, tax, and fraud",
      "severity": "Critical",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "Commerce ↔ Payment ↔ ERP",
      "symptom": "The customer receives a refund, but the ERP credit memo, order balance, tax, or financial ledger does not match.",
      "root_cause": "Each system records a different refund identifier, amount basis, currency, line allocation, or completion state.",
      "detection": "Reconcile refund ID, payment transaction, order, currency, line amounts, shipping, tax, and total. Alert on completed gateway refunds without ERP credit.",
      "control": "Use one refund intent ID across systems. Record requested, accepted, completed, failed, and reversed states. Retry accounting effects safely and compensate when needed.",
      "test": "Given a partial refund of one line plus tax, when the gateway completes the refund and the ERP call times out, then replay creates one credit memo for the exact amount and no second gateway refund.",
      "given": "a partial refund of one line plus tax",
      "when": "the gateway completes the refund and the ERP call times out",
      "then": "replay creates one credit memo for the exact amount and no second gateway refund.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "bounded-retries",
        "reconciliation",
        "replay-safety"
      ],
      "system_tags": [
        "commerce",
        "erp",
        "payment"
      ]
    },
    {
      "id": "CIF-030",
      "slug": "rma-status-divergence",
      "anchor": "cif-030-rma-status-divergence",
      "title": "RMA status divergence",
      "category": "returns_and_refunds",
      "category_label": "Returns and refunds",
      "severity": "High",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "Commerce ↔ OMS/WMS/ERP",
      "symptom": "The customer sees approved while the warehouse sees pending, or a closed return reopens after a delayed update.",
      "root_cause": "Systems use different state names and allowed transitions, and the mapping has no version or transition guard.",
      "detection": "Map each source state to one canonical state. Alert on impossible transitions and status age beyond the service target.",
      "control": "Use a canonical return state machine and versioned mappings. Keep source state and canonical state together for audit.",
      "test": "Given an RMA is closed at version 9, when a delayed version 7 “received” event arrives, then it is quarantined and the return remains closed.",
      "given": "an RMA is closed at version 9",
      "when": "a delayed version 7 “received” event arrives",
      "then": "it is quarantined and the return remains closed.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "ordering-and-version"
      ],
      "system_tags": [
        "commerce",
        "erp",
        "oms",
        "wms"
      ]
    },
    {
      "id": "CIF-031",
      "slug": "refund-completed-without-inventory-adjustment",
      "anchor": "cif-031-refund-completed-without-inventory-adjustment",
      "title": "Refund completed without inventory adjustment",
      "category": "returns_and_refunds",
      "category_label": "Returns and refunds",
      "severity": "Critical",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "Commerce/Payment ↔ WMS/ERP",
      "symptom": "Money is returned, but sellable, damaged, quarantine, or scrap inventory is not updated.",
      "root_cause": "Refund and physical return are treated as one event even when goods are not received, inspected, or restockable.",
      "detection": "Compare refund completion with return receipt, disposition, and inventory movement. Flag financial completion without an expected physical-state record.",
      "control": "Separate financial refund from physical return and disposition. Use explicit states for not received, received, restock, refurbish, quarantine, and scrap.",
      "test": "Given a refund is issued before goods arrive, when the refund completes, then inventory does not increase until the warehouse records a restockable receipt.",
      "given": "a refund is issued before goods arrive",
      "when": "the refund completes",
      "then": "inventory does not increase until the warehouse records a restockable receipt.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "reconciliation"
      ],
      "system_tags": [
        "commerce",
        "erp",
        "wms",
        "payment"
      ]
    },
    {
      "id": "CIF-032",
      "slug": "return-line-mapped-to-the-wrong-sku-or-unit",
      "anchor": "cif-032-return-line-mapped-to-the-wrong-sku-or-unit",
      "title": "Return line mapped to the wrong SKU or unit",
      "category": "returns_and_refunds",
      "category_label": "Returns and refunds",
      "severity": "Critical",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "Commerce → WMS/ERP",
      "symptom": "The warehouse credits or restocks the wrong variant, pack size, or unit.",
      "root_cause": "The return uses display SKU, parent SKU, or order-line position instead of the immutable order-line ID and sold unit.",
      "detection": "Compare return line with original order-line ID, variant ID, sold unit, lot/serial where relevant, and quantity.",
      "control": "Create returns from immutable order-line references. Preserve sold unit and conversion factor. Reject returns that cannot resolve to the original line.",
      "test": "Given an order line contains two cases of SKU X with 12 each per case, when one case is returned, then the return records one case and 12 base units against the original line.",
      "given": "an order line contains two cases of SKU X with 12 each per case",
      "when": "one case is returned",
      "then": "the return records one case and 12 base units against the original line.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "ordering-and-version",
        "reconciliation"
      ],
      "system_tags": [
        "commerce",
        "erp",
        "wms"
      ]
    },
    {
      "id": "CIF-033",
      "slug": "silent-dead-letter-queue",
      "anchor": "cif-033-silent-dead-letter-queue",
      "title": "Silent dead-letter queue",
      "category": "observability_and_recovery",
      "category_label": "Observability and recovery",
      "severity": "Critical",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "Queue / integration platform",
      "symptom": "Messages fail and accumulate, but customers and operations notice the problem before engineering receives an alert.",
      "root_cause": "The dead-letter queue exists but has no owner, age metric, business context, or alert threshold.",
      "detection": "Monitor count, oldest age, failure reason, entity type, and business value. Alert on both sudden spikes and any critical message beyond its service target.",
      "control": "Assign an owner and runbook. Include correlation ID and safe replay data. Keep a dashboard and a scheduled review even when the count is zero.",
      "test": "Given a critical order message exhausts retries, when it enters the dead-letter queue, then an alert includes order ID, reason, age, owner, and a safe replay path.",
      "given": "a critical order message exhausts retries",
      "when": "it enters the dead-letter queue",
      "then": "an alert includes order ID, reason, age, owner, and a safe replay path.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "system-of-record",
        "bounded-retries",
        "dead-letter-handling",
        "correlation-id",
        "replay-safety"
      ],
      "system_tags": [
        "queue",
        "integration"
      ]
    },
    {
      "id": "CIF-034",
      "slug": "unbounded-retry-loop",
      "anchor": "cif-034-unbounded-retry-loop",
      "title": "Unbounded retry loop",
      "category": "observability_and_recovery",
      "category_label": "Observability and recovery",
      "severity": "Critical",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "Any API or queue flow",
      "symptom": "A dependency outage creates a retry storm, duplicate traffic, rising cost, or wider platform failure.",
      "root_cause": "Every error is treated as temporary. Retries have no limit, delay, jitter, circuit breaker, or idempotency control.",
      "detection": "Track attempts per operation, retry rate, repeated error class, downstream saturation, and time spent retrying.",
      "control": "Classify errors. Use exponential backoff with jitter, attempt and time limits, circuit breaking, and dead-letter handling. Make side effects idempotent.",
      "test": "Given the ERP returns a temporary 503, when the call fails repeatedly, then retries follow the bounded schedule, stop at the limit, open the circuit, and preserve one recoverable message.",
      "given": "the ERP returns a temporary 503",
      "when": "the call fails repeatedly",
      "then": "retries follow the bounded schedule, stop at the limit, open the circuit, and preserve one recoverable message.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "idempotency",
        "bounded-retries",
        "dead-letter-handling"
      ],
      "system_tags": [
        "queue"
      ]
    },
    {
      "id": "CIF-035",
      "slug": "missing-correlation-id-across-systems",
      "anchor": "cif-035-missing-correlation-id-across-systems",
      "title": "Missing correlation ID across systems",
      "category": "observability_and_recovery",
      "category_label": "Observability and recovery",
      "severity": "High",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "Commerce ↔ all downstream systems",
      "symptom": "Support cannot trace one order, payment, or product update across logs, queues, and vendor systems.",
      "root_cause": "Each service generates its own request ID and drops the business correlation when making the next call.",
      "detection": "Sample critical flows and verify the same correlation ID appears in logs, message headers, API calls, error records, and support views.",
      "control": "Create a correlation ID at the business-flow boundary. Propagate it without using personal data. Keep local request IDs as separate fields.",
      "test": "Given one checkout creates an order, payment, ERP order, and shipment request, when the flow completes, then all systems can be queried with the same correlation ID.",
      "given": "one checkout creates an order, payment, ERP order, and shipment request",
      "when": "the flow completes",
      "then": "all systems can be queried with the same correlation ID.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "correlation-id"
      ],
      "system_tags": [
        "commerce"
      ]
    },
    {
      "id": "CIF-036",
      "slug": "unsafe-replay-repeats-side-effects",
      "anchor": "cif-036-unsafe-replay-repeats-side-effects",
      "title": "Unsafe replay repeats side effects",
      "category": "observability_and_recovery",
      "category_label": "Observability and recovery",
      "severity": "Critical",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "Replay tool → external services",
      "symptom": "A support replay sends another email, refund, invoice, label, stock movement, or order.",
      "root_cause": "The replay tool republishes the original message without checking which effects already completed.",
      "detection": "Compare replay records with an effect ledger. Alert when the same business key produces a new external effect.",
      "control": "Record each effect and result. Make replay dry-run by default. Require idempotency keys, scoped approval, and compensation for non-idempotent operations.",
      "test": "Given an order event already sent an email and created an ERP order but missed analytics, when replay runs, then only the missing analytics effect is executed.",
      "given": "an order event already sent an email and created an ERP order but missed analytics",
      "when": "replay runs",
      "then": "only the missing analytics effect is executed.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "idempotency",
        "reconciliation",
        "least-privilege",
        "replay-safety"
      ],
      "system_tags": [
        "replay"
      ]
    },
    {
      "id": "CIF-037",
      "slug": "overprivileged-integration-account",
      "anchor": "cif-037-overprivileged-integration-account",
      "title": "Overprivileged integration account",
      "category": "security_and_access",
      "category_label": "Security and access",
      "severity": "Critical",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "Integration user / service account",
      "symptom": "A credential used for one data flow can read or change unrelated customers, orders, configuration, or environments.",
      "root_cause": "The account uses administrator rights because scoped permissions were not designed or tested.",
      "detection": "Review effective permissions, API scopes, object access, environment access, and unused privileges. Monitor actions outside the expected endpoint and entity set.",
      "control": "Apply least privilege. Use separate accounts by environment and major integration. Rotate secrets and review access on a fixed schedule.",
      "test": "Given the inventory integration needs read product and write inventory only, when it attempts to read customer data or change store configuration, then access is denied and logged.",
      "given": "the inventory integration needs read product and write inventory only",
      "when": "it attempts to read customer data or change store configuration",
      "then": "access is denied and logged.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "bounded-retries",
        "least-privilege"
      ],
      "system_tags": [
        "integration"
      ]
    },
    {
      "id": "CIF-038",
      "slug": "secret-exposed-in-logs-or-configuration",
      "anchor": "cif-038-secret-exposed-in-logs-or-configuration",
      "title": "Secret exposed in logs or configuration",
      "category": "security_and_access",
      "category_label": "Security and access",
      "severity": "Critical",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "Application logs / CI/CD / support tools",
      "symptom": "API keys, tokens, passwords, or signed URLs appear in logs, error messages, exported config, or tickets.",
      "root_cause": "The client logs full headers or payloads, exceptions include secrets, or configuration is stored in source control.",
      "detection": "Run secret scanning on repositories, build output, logs, and support exports. Alert on known token formats and high-entropy values.",
      "control": "Use a secret manager, redaction at log boundaries, short-lived credentials where possible, and immediate rotation after exposure.",
      "test": "Given an API call fails with an authorization header and token in memory, when the error is logged, then the token is redacted and the structured log keeps only the safe credential identifier.",
      "given": "an API call fails with an authorization header and token in memory",
      "when": "the error is logged",
      "then": "the token is redacted and the structured log keeps only the safe credential identifier.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "least-privilege"
      ],
      "system_tags": [
        "ci/cd",
        "logs"
      ]
    },
    {
      "id": "CIF-039",
      "slug": "tenant-or-storefront-boundary-error",
      "anchor": "cif-039-tenant-or-storefront-boundary-error",
      "title": "Tenant or storefront boundary error",
      "category": "security_and_access",
      "category_label": "Security and access",
      "severity": "Critical",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "Multi-tenant commerce / integration layer",
      "symptom": "Data from one store, account, region, or legal entity is read or written into another.",
      "root_cause": "Tenant context comes from an untrusted request field, is missing from a cache key, or is not enforced in the data query.",
      "detection": "Test cross-tenant object IDs. Review cache keys, database filters, queue routing, and audit logs for mismatched tenant and entity ownership.",
      "control": "Derive tenant context from trusted authentication. Enforce it at every data boundary. Include tenant in keys, messages, and authorization checks.",
      "test": "Given a token belongs to tenant A, when it requests an order ID owned by tenant B, then the service returns no data, creates no side effect, and logs the denied boundary check.",
      "given": "a token belongs to tenant A",
      "when": "it requests an order ID owned by tenant B",
      "then": "the service returns no data, creates no side effect, and logs the denied boundary check.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "system-of-record",
        "least-privilege"
      ],
      "system_tags": [
        "commerce",
        "integration"
      ]
    },
    {
      "id": "CIF-040",
      "slug": "unvalidated-external-callback",
      "anchor": "cif-040-unvalidated-external-callback",
      "title": "Unvalidated external callback",
      "category": "security_and_access",
      "category_label": "Security and access",
      "severity": "Critical",
      "evidence_class": "D",
      "evidence": "Class D: reproducible synthetic fixture",
      "systems": "Carrier, tax, marketplace, payment, or vendor callback",
      "symptom": "An attacker or wrong partner system can trigger state changes through a public callback URL.",
      "root_cause": "The endpoint trusts payload fields or source IP alone and does not verify signature, audience, timestamp, nonce, schema, or expected state.",
      "detection": "Log verification outcome, callback age, event ID, issuer, audience, and state transition. Alert on repeated invalid attempts.",
      "control": "Use strong signature or mutual authentication, replay protection, strict schema validation, allowlisted event types, and server-side authorization of the resulting action.",
      "test": "Given a callback payload is structurally valid but signed by an unknown key, when it reaches the endpoint, then it is rejected before any order, payment, or shipment state changes.",
      "given": "a callback payload is structurally valid but signed by an unknown key",
      "when": "it reaches the endpoint",
      "then": "it is rejected before any order, payment, or shipment state changes.",
      "version": "1.1.0",
      "last_reviewed": "2026-08-01",
      "evidence_scope": "synthetic_fixture",
      "limitations": "Synthetic test pattern. Official sources support control or delivery behavior where mapped; they do not prove a vendor defect, client incident, breach, or incident frequency.",
      "control_tags": [
        "event-identity",
        "ordering-and-version",
        "bounded-retries",
        "least-privilege",
        "replay-safety"
      ],
      "system_tags": [
        "carrier",
        "payment",
        "tax",
        "marketplace"
      ]
    }
  ]
}