SKILL: Northwind Components ERP — Inventory / Order-Fulfillment Operations
Reusable workflow for solving Northwind Components ERP tasks (expedite dispatch, kit
replenishment, supplier incident scorecards, mixed-warehouse allocation, procurement quality
control). Rules below were verified/refined against task feedback. Read the task prompt.txt,
its input/payloads/* memo, and the answer_template.json, then follow the matching SOP.
Do NOT call any scoring/judge endpoint at solve time. Build the answer purely from the ERP API
and the task payloads, and emit only the JSON the template requires.
1. ERP API (read-only data source)
Base URL is provided by the runner. Ignore any "start a local env / 127.0.0.1" wording in prompts;
use the runner-provided base URL. All endpoints return JSON.
GET endpoints:
/health
/products , /products/<sku>
fields: sku, name, category, active(bool), supplier_id, unit_cost, weight_lb,
safety_stock, overstock_threshold
/customers , /customers/<id>
fields: customer_id, name, account_status(active|review_required|blocked),
risk_flag(none|credit_watch|fraud_watch), tier(strategic|standard|economy), margin_band
/suppliers — supplier_id, name, region, quality_status(approved|watch|quality_hold)
/warehouses — warehouse_id(WH_NORTH|WH_CENTRAL|WH_WEST), name, region, zip
/inventory?warehouse_id=&sku= — per (warehouse,sku): on_hand, reserved, quarantined,
last_count_date. One row per warehouse/sku. Missing row => treat as 0 stock.
/purchase_orders?supplier_id=&sku=&status= — po_id, sku, supplier_id, warehouse_id,
quantity, eta, status(open|confirmed|received|cancelled)
/orders?wave=&required_date=&customer_id= , /orders/<order_id>
order: order_id, wave, customer_id, warehouse_id, destination_zip, priority,
required_date, shipping_speed(ground|two_day|overnight), lines[{line_id,sku,quantity,unit_price}]
/shipping/quote?warehouse_id=&destination_zip=&weight_lb=&speed= (speed: ground|two_day|overnight)
returns: zone_distance(int), service_days(int), total_cost(float), base_rate, fuel_surcharge_rate
/incidents?start=&end=&supplier_id=&sku=&incident_type=&status= — the date window applies to
open_date. incident: incident_id, supplier_id, sku, warehouse_id, incident_type(RMA|WORK_ORDER),
severity(low|medium|high|critical), status(open|closed), open_date, close_date, resolution_cost,
root_cause
/boms , /boms/<bom_id> — bom_id, name, warehouse_id, target_date,
components[{sku, quantity_per_kit}]
Practical notes:
- It is efficient to pull whole collections once (
/products, /inventory, /customers,
/purchase_orders, /incidents, /boms, /suppliers) and index them in memory.
- Date fields are
YYYY-MM-DD; lexicographic string comparison is a valid date comparison.
/incidents?start=&end= filters on open_date; you can also filter locally with the same logic.
2. THE core inventory rule (most important, cost the most score)
Effective available for planning/fulfillment =
on_hand − reserved − quarantined − safety_stock.
Reserved, quarantined, AND safety_stock (the "normal operating buffer") are all NON-freely-available.
- This value may be negative; report the raw signed integer — do NOT clamp to 0.
- A line is a shortage / cannot ship in full when
effective_available < line.quantity.
- When deciding inter-warehouse transfers, a source warehouse can only contribute its own
effective available (same formula); never draw a source below its safety/reserved/quarantine.
- Verified: omitting the
− safety_stock term is the single most common scoring error. Always
subtract it for any "available to fulfill/build/transfer" decision.
When a separate "freely available without safety" figure is ever needed it would be
on_hand − reserved − quarantined, but the planning/allocation tasks here use the
safety-subtracted figure.
3. Customer / account exception precedence
For order-release decisions, evaluate customer state first (it can stop the whole order):
| Condition |
exception code |
effect |
| account_status == blocked |
account_blocked |
hard stop, order-level block |
| risk_flag == fraud_watch |
fraud_watch |
hard stop, order-level block |
| account_status == review_required |
review_required / account_review_required |
order-level review (blocked) |
| risk_flag == credit_watch |
credit_watch |
review/hold (account-level) |
| else |
none |
proceed to inventory/product checks |
- "Order-level block" = every line on the order gets the account/risk reason, the order goes into
the wave's blocked/manual-review list, and inventory is not auto-released.
- Inactive product (
product.active == false) is a line-only review (manual_review with reason
inactive_product); it does NOT put the order in the account-level blocked list.
4. SOP A — Expedite dispatch-control wave (per-order decision)
Inputs: a queue memo listing a SUBSET of order_ids for a wave (use ONLY the memo's order_ids, even
though /orders?wave= returns more), plus live ERP records.
Per order:
- For each line compute
effective_available = on_hand − reserved − quarantined − safety_stock
at the order's warehouse. Build three SKU lists (each SKU in at most one list):
inactive_skus: product.active == false
shortage_skus: effective_available < line.quantity
low_stock_skus: can cover the line but the post-fulfillment buffer is thin
(effective_available ≥ qty yet still below safety margin)
- inventory_status (order-level rollup of the lists):
inactive+shortage →
inactive_and_shortage; inactive only → inactive_sku;
shortage only → shortage; low only → low_stock; else ready.
- customer_exception per Section 3 (enum: none|review_required|account_blocked|fraud_watch|credit_watch).
- final_decision / next_action — account hard-stops dominate inventory:
- account_blocked or fraud_watch →
reject_hold / hold_credit_or_fraud
- credit_watch or review_required →
manual_review / send_account_review
- inactive SKU present →
manual_review / escalate_product_master
- shortage →
backorder / create_backorder
- low_stock →
delayed_release / delay_and_monitor
- else ready →
ship_now / release_to_pick
- shipping_quote: GET
/shipping/quote with the order's warehouse_id, destination_zip,
weight_lb = Σ(line.quantity × product.weight_lb), and the order's shipping_speed.
Emit {zone_distance:int, service_days:int, total_cost_usd: round(total_cost,2)}. Produce a
quote for every order even when the decision is not "ship".
- summary: order_count; decision_counts (all 5 keys, integers); total_shipping_cost_usd
(Σ rounded, 2dp); blocked_order_ids (account_blocked), manual_review_order_ids,
backorder_order_ids, inactive_sku_order_ids — each sorted ascending.
Sort records by order_id; all SKU lists sorted ascending.
(Note: the exact shortage/low boundary and decision precedence for this wave were the hardest to
pin down; always subtract safety_stock per Section 2 before classifying.)
5. SOP B — Kit-build replenishment from BOMs
Inputs: production memo with planning_site (warehouse), and target_builds[{bom_id,
target_build_quantity, target_build_date}].
- kit_targets: for each target build, look up the BOM → {bom_id, kit_name(=bom.name),
warehouse_id(=bom.warehouse_id), build_quantity, build_date}. Sort by bom_id.
- Per component SKU across all target BOMs:
total_required = Σ over BOMs (quantity_per_kit × build_quantity)
needed_by = earliest target_build_date among BOMs that use the SKU
target_effective_available = on_hand − reserved − quarantined − safety_stock at the
planning site (Section 2; can be negative)
timely_po_qty = Σ quantity of POs that are same-warehouse AND status in {open, confirmed}
(exclude received/cancelled) AND eta ≤ needed_by. coverage_po_ids = those po_ids sorted.
- gap_before_po = total_required − target_effective_available; gap = gap_before_po − timely_po_qty
- final_action / exclusion_reason:
- target_effective_available ≥ overstock_threshold →
overstock_excluded / target_overstock
- gap_before_po ≤ 0 →
no_action_stocked / stocked_no_gap
- gap ≤ 0 (timely POs close it) →
timely_po_covered / timely_po_covers_gap
- else cover the gap by inter-warehouse transfer first, then purchase:
transfer_qty from another warehouse's effective available (Section 2; protect source safety);
purchase_requisition_qty = remaining gap.
transfer_only if fully covered by transfer,
else purchase_required.
- transfer_requests: {sku, from_warehouse_id, to_warehouse_id(=site), quantity, needed_by}.
purchase_requisitions: {sku, supplier_id(=product.supplier_id), warehouse_id(=site), quantity,
needed_by, unit_cost(2dp), extended_cost = round(unit_cost×quantity,2)}.
excluded_components: {sku, reason, supporting_po_ids} for the three exclusion reasons.
- summary: component_count; total_purchase_units; total_purchase_cost(2dp); total_transfer_units;
timely_po_covered_units = Σ of the gap that timely POs actually closed (the gap_before_po for
timely_po_covered SKUs) — NOT the full PO quantity.
- Sort: component_plan & purchase_requisitions & excluded_components by sku asc;
transfer_requests by sku asc, then quantity desc, then from_warehouse_id asc.
task_id and plan_date must match the template's required values.
6. SOP C — Supplier incident scorecard (deterministic; scores perfectly)
Inputs: a request payload with the date filter, duration rule, precision rules, severe-severity
set, and an explicit recommendation policy with a precedence list. Follow the payload literally.
- Filter incidents to
start_date ≤ open_date ≤ end_date (inclusive). This filtered set is the
population; its size is the percentage denominator.
- Group by supplier_id (only suppliers with ≥1 filtered incident appear).
- Per supplier:
- incident_count; incident_percentage = count×100/N rounded to 1 decimal
- rma_count (incident_type==RMA), work_order_count (==WORK_ORDER)
- open_incident_count (status==open)
- severe_incident_count (severity in the payload's severe set, typically {high,critical})
- total_resolution_cost = Σ resolution_cost (2dp)
- avg_duration_days = mean of per-incident durations (2dp), where duration =
(close_date − open_date) days for closed, (analysis_date − open_date) days for open
- recommendation_code by the payload precedence (first match wins). Example policy used:
- ESCALATE_SUPPLIER: (quality_status==quality_hold AND count≥3) OR any critical RMA OR
(rma_count≥3 AND total_cost≥15000)
- PROCESS_REVIEW: work_order_count≥3 AND work_order_count>rma_count
- WATCHLIST: quality_status in {watch,quality_hold} OR count≥4 OR total_cost≥12000 OR severe≥2
- MONITOR: otherwise
Always read the actual thresholds from the request payload — they are authoritative.
- summary: filtered_incident_count, supplier_count, total_resolution_cost(2dp),
overall_rma_count, overall_work_order_count.
top_escalation_suppliers: only ESCALATE rows, ordered incident_count desc, total_resolution_cost
desc, supplier_id asc → list of supplier_id strings.
highest_cost_supplier_id = max total_resolution_cost; highest_share_supplier_id = max
incident_count. supplier_scorecard sorted supplier_id asc.
7. SOP D — Mixed-warehouse line allocation (scores perfectly)
Inputs: a wave of orders; classify every line as ship | transfer | backorder | manual_review.
Per order (account state first, Section 3):
- If order has an account/risk stop (account_blocked, fraud_watch, review_required): set EVERY
line action =
manual_review with that primary_reason, and add order_id to blocked_orders.
- Else per line, with
requested_effective_available = on_hand − reserved − quarantined − safety_stock at the requested warehouse (Section 2; report this signed integer):
- product inactive →
manual_review, primary_reason inactive_product (NOT a blocked order)
- requested eff ≥ qty →
ship, ship_quantity = qty
- else ship the usable requested qty (max(0, eff)); for the remainder, if ONE other warehouse's
running effective available can cover it →
transfer (transfer_from = that source,
transfer_quantity = remainder), primary_reason insufficient_effective_stock
- else
backorder (backorder_quantity = remainder), primary_reason insufficient_effective_stock
Maintain a running per-(warehouse,sku) remaining-availability map so ship/transfer allocations
across lines don't double-spend the same stock.
- transfer_requests: {order_id, line_id, sku, from_warehouse, to_warehouse(=requested), quantity}.
- order_rollup outcome — handle
mixed_actions carefully (this was the subtle scoring trap):
- actions == {ship} → ready_to_ship
- actions ⊆ {ship,transfer} and a transfer present → needs_transfer
- actions == {manual_review} → manual_review
- actions ⊆ {ship,transfer,backorder} and a backorder present → has_backorder
- else →
mixed_actions (e.g. manual_review combined with backorder/ship/transfer)
- blocked_orders = order-level account/risk stops only (sorted unique); line-only inactive reviews
are NOT blocked orders.
- summary integers: total_orders, total_lines, ship_lines, transfer_lines, backorder_lines,
manual_review_lines, blocked_orders(count), transfer_units(Σ transfer_quantity),
backorder_units(Σ backorder_quantity).
Sort line_actions and transfer_requests by (order_id, line_id); order_rollup & blocked by order_id.
8. SOP E — Procurement quality-control decision (partially specified)
Inputs: an analysis window, a list of target supplier_ids, and decision_choices
(freeze_new_replenishment | buyer_review_required | monitor_only). The memo gives little numeric
policy; compute the data fields exactly and apply conservative status-driven logic.
Per supplier (incidents filtered to start ≤ open_date ≤ end):
- recent_incident_count, recent_rma_count, severe_or_critical_count (high|critical),
open_incident_count (status==open), affected_skus (sorted unique incident SKUs),
sample_incident_ids (sorted, max 5).
- held_po_ids = the supplier's open/confirmed purchase order ids (sorted) when the supplier is
frozen.
- decision:
freeze_new_replenishment when quality_status == quality_hold (verified) — hold its
open/confirmed POs.
buyer_review_required when quality_status == watch with elevated recent risk
(e.g. RMAs, open incidents, or multiple severe/critical incidents).
monitor_only otherwise.
- summary: suppliers_reviewed, freeze_count, buyer_review_count, monitor_count, held_po_count,
total_recent_incidents. held_po_ids(top-level) = sorted unique across suppliers;
release_supplier_ids = suppliers whose decision is monitor_only.
CAUTION (unresolved): the exact watch→{buyer_review vs monitor} threshold and whether held_po_ids
should be filtered to affected SKUs are not fully nailed down. Prefer the supplier's quality_status
as the primary driver, compute every numeric field precisely, and keep held_po_ids = the frozen
supplier's full open/confirmed PO set unless the payload says otherwise.
9. Output formatting conventions (apply to every task)
- Emit ONLY the JSON object matching
answer_template.json. No prose, no extra keys, all required
keys present.
- Honor
required_value fields exactly (e.g. wave_id, task_id literals).
- Currency / cost fields: round to 2 decimals. Percentages: round to 1 decimal unless told otherwise.
Durations: 2 decimals.
- Integer fields (counts, quantities, units, zone_distance, service_days,
requested_effective_available) must be integers — including negative effective-availability values.
- Enums: use only the template's allowed values; never invent new ones.
- Apply every stated sort order exactly (usually order_id/line_id/sku/supplier_id ascending, with
the documented multi-key tiebreakers). Sort SKU/id lists ascending and de-duplicate.
- Build summary counts/totals from the per-record results you actually emitted (keep them consistent).
10. Common scoring pitfalls (and the fix)
- Forgetting
− safety_stock in effective availability → cascades wrong everywhere. Always
subtract reserved + quarantined + safety_stock (Section 2).
- Clamping negative effective availability to 0 → keep it signed.
- Using ALL wave orders when the memo lists a subset → use only the memo's order_ids.
- Counting received/cancelled POs as coverage → only open/confirmed POs count, and (for timely
coverage) only those with eta ≤ needed_by.
timely_po_covered_units reported as full PO quantity instead of the gap actually closed.
- order_rollup: labeling an order has_backorder/needs_transfer when it also has a manual_review
line → that mix is
mixed_actions.
- Treating a line-only inactive-product review as an account-level blocked order → it is not.
- Incident windows filter on
open_date; open-incident duration runs to the analysis_date, not
today.
1---2name: reflect-3-attempt-02-303description: SKILL: Northwind Components ERP — Inventory / Order-Fulfillment Operations4---5# SKILL: Northwind Components ERP — Inventory / Order-Fulfillment Operations67Reusable workflow for solving Northwind Components ERP tasks (expedite dispatch, kit8replenishment, supplier incident scorecards, mixed-warehouse allocation, procurement quality9control). Rules below were verified/refined against task feedback. Read the task `prompt.txt`,10its `input/payloads/*` memo, and the `answer_template.json`, then follow the matching SOP.1112> Do NOT call any scoring/judge endpoint at solve time. Build the answer purely from the ERP API13> and the task payloads, and emit only the JSON the template requires.1415---1617## 1. ERP API (read-only data source)1819Base URL is provided by the runner. Ignore any "start a local env / 127.0.0.1" wording in prompts;20use the runner-provided base URL. All endpoints return JSON.2122GET endpoints:23- `/health`24- `/products` , `/products/<sku>`25 fields: sku, name, category, active(bool), supplier_id, unit_cost, weight_lb,26 safety_stock, overstock_threshold27- `/customers` , `/customers/<id>`28 fields: customer_id, name, account_status(active|review_required|blocked),29 risk_flag(none|credit_watch|fraud_watch), tier(strategic|standard|economy), margin_band30- `/suppliers` — supplier_id, name, region, quality_status(approved|watch|quality_hold)31- `/warehouses` — warehouse_id(WH_NORTH|WH_CENTRAL|WH_WEST), name, region, zip32- `/inventory?warehouse_id=&sku=` — per (warehouse,sku): on_hand, reserved, quarantined,33 last_count_date. One row per warehouse/sku. Missing row => treat as 0 stock.34- `/purchase_orders?supplier_id=&sku=&status=` — po_id, sku, supplier_id, warehouse_id,35 quantity, eta, status(open|confirmed|received|cancelled)36- `/orders?wave=&required_date=&customer_id=` , `/orders/<order_id>`37 order: order_id, wave, customer_id, warehouse_id, destination_zip, priority,38 required_date, shipping_speed(ground|two_day|overnight), lines[{line_id,sku,quantity,unit_price}]39- `/shipping/quote?warehouse_id=&destination_zip=&weight_lb=&speed=` (speed: ground|two_day|overnight)40 returns: zone_distance(int), service_days(int), total_cost(float), base_rate, fuel_surcharge_rate41- `/incidents?start=&end=&supplier_id=&sku=&incident_type=&status=` — the date window applies to42 `open_date`. incident: incident_id, supplier_id, sku, warehouse_id, incident_type(RMA|WORK_ORDER),43 severity(low|medium|high|critical), status(open|closed), open_date, close_date, resolution_cost,44 root_cause45- `/boms` , `/boms/<bom_id>` — bom_id, name, warehouse_id, target_date,46 components[{sku, quantity_per_kit}]4748Practical notes:49- It is efficient to pull whole collections once (`/products`, `/inventory`, `/customers`,50 `/purchase_orders`, `/incidents`, `/boms`, `/suppliers`) and index them in memory.51- Date fields are `YYYY-MM-DD`; lexicographic string comparison is a valid date comparison.52- `/incidents?start=&end=` filters on open_date; you can also filter locally with the same logic.5354---5556## 2. THE core inventory rule (most important, cost the most score)5758**Effective available for planning/fulfillment =59`on_hand − reserved − quarantined − safety_stock`.**6061Reserved, quarantined, AND safety_stock (the "normal operating buffer") are all NON-freely-available.62- This value may be **negative**; report the raw signed integer — do NOT clamp to 0.63- A line is a **shortage / cannot ship in full** when `effective_available < line.quantity`.64- When deciding inter-warehouse transfers, a source warehouse can only contribute its own65 effective available (same formula); never draw a source below its safety/reserved/quarantine.66- Verified: omitting the `− safety_stock` term is the single most common scoring error. Always67 subtract it for any "available to fulfill/build/transfer" decision.6869When a separate "freely available without safety" figure is ever needed it would be70`on_hand − reserved − quarantined`, but the planning/allocation tasks here use the71safety-subtracted figure.7273---7475## 3. Customer / account exception precedence7677For order-release decisions, evaluate customer state first (it can stop the whole order):7879| Condition | exception code | effect |80|----------------------------------------|---------------------------|-------------------------------------|81| account_status == blocked | account_blocked | hard stop, order-level block |82| risk_flag == fraud_watch | fraud_watch | hard stop, order-level block |83| account_status == review_required | review_required / account_review_required | order-level review (blocked)|84| risk_flag == credit_watch | credit_watch | review/hold (account-level) |85| else | none | proceed to inventory/product checks |8687- "Order-level block" = every line on the order gets the account/risk reason, the order goes into88 the wave's blocked/manual-review list, and inventory is not auto-released.89- Inactive product (`product.active == false`) is a **line-only** review (manual_review with reason90 inactive_product); it does NOT put the order in the account-level blocked list.9192---9394## 4. SOP A — Expedite dispatch-control wave (per-order decision)9596Inputs: a queue memo listing a SUBSET of order_ids for a wave (use ONLY the memo's order_ids, even97though `/orders?wave=` returns more), plus live ERP records.9899Per order:1001. For each line compute `effective_available = on_hand − reserved − quarantined − safety_stock`101 at the order's warehouse. Build three SKU lists (each SKU in at most one list):102 - `inactive_skus`: product.active == false103 - `shortage_skus`: effective_available < line.quantity104 - `low_stock_skus`: can cover the line but the post-fulfillment buffer is thin105 (effective_available ≥ qty yet still below safety margin)1062. inventory_status (order-level rollup of the lists):107 inactive+shortage → `inactive_and_shortage`; inactive only → `inactive_sku`;108 shortage only → `shortage`; low only → `low_stock`; else `ready`.1093. customer_exception per Section 3 (enum: none|review_required|account_blocked|fraud_watch|credit_watch).1104. final_decision / next_action — account hard-stops dominate inventory:111 - account_blocked or fraud_watch → `reject_hold` / `hold_credit_or_fraud`112 - credit_watch or review_required → `manual_review` / `send_account_review`113 - inactive SKU present → `manual_review` / `escalate_product_master`114 - shortage → `backorder` / `create_backorder`115 - low_stock → `delayed_release` / `delay_and_monitor`116 - else ready → `ship_now` / `release_to_pick`1175. shipping_quote: GET `/shipping/quote` with the order's warehouse_id, destination_zip,118 `weight_lb = Σ(line.quantity × product.weight_lb)`, and the order's shipping_speed.119 Emit `{zone_distance:int, service_days:int, total_cost_usd: round(total_cost,2)}`. Produce a120 quote for every order even when the decision is not "ship".1216. summary: order_count; decision_counts (all 5 keys, integers); total_shipping_cost_usd122 (Σ rounded, 2dp); blocked_order_ids (account_blocked), manual_review_order_ids,123 backorder_order_ids, inactive_sku_order_ids — each sorted ascending.124125Sort `records` by order_id; all SKU lists sorted ascending.126(Note: the exact shortage/low boundary and decision precedence for this wave were the hardest to127pin down; always subtract safety_stock per Section 2 before classifying.)128129## 5. SOP B — Kit-build replenishment from BOMs130131Inputs: production memo with planning_site (warehouse), and target_builds[{bom_id,132target_build_quantity, target_build_date}].1331341. kit_targets: for each target build, look up the BOM → {bom_id, kit_name(=bom.name),135 warehouse_id(=bom.warehouse_id), build_quantity, build_date}. Sort by bom_id.1362. Per component SKU across all target BOMs:137 - `total_required` = Σ over BOMs (quantity_per_kit × build_quantity)138 - `needed_by` = earliest target_build_date among BOMs that use the SKU139 - `target_effective_available` = on_hand − reserved − quarantined − safety_stock at the140 planning site (Section 2; can be negative)141 - `timely_po_qty` = Σ quantity of POs that are same-warehouse AND status in {open, confirmed}142 (exclude received/cancelled) AND `eta ≤ needed_by`. coverage_po_ids = those po_ids sorted.143 - gap_before_po = total_required − target_effective_available; gap = gap_before_po − timely_po_qty1443. final_action / exclusion_reason:145 - target_effective_available ≥ overstock_threshold → `overstock_excluded` / target_overstock146 - gap_before_po ≤ 0 → `no_action_stocked` / stocked_no_gap147 - gap ≤ 0 (timely POs close it) → `timely_po_covered` / timely_po_covers_gap148 - else cover the gap by inter-warehouse transfer first, then purchase:149 transfer_qty from another warehouse's effective available (Section 2; protect source safety);150 purchase_requisition_qty = remaining gap. `transfer_only` if fully covered by transfer,151 else `purchase_required`.1524. transfer_requests: {sku, from_warehouse_id, to_warehouse_id(=site), quantity, needed_by}.153 purchase_requisitions: {sku, supplier_id(=product.supplier_id), warehouse_id(=site), quantity,154 needed_by, unit_cost(2dp), extended_cost = round(unit_cost×quantity,2)}.155 excluded_components: {sku, reason, supporting_po_ids} for the three exclusion reasons.1565. summary: component_count; total_purchase_units; total_purchase_cost(2dp); total_transfer_units;157 `timely_po_covered_units` = Σ of the gap that timely POs actually closed (the gap_before_po for158 timely_po_covered SKUs) — NOT the full PO quantity.1596. Sort: component_plan & purchase_requisitions & excluded_components by sku asc;160 transfer_requests by sku asc, then quantity desc, then from_warehouse_id asc.161 task_id and plan_date must match the template's required values.162163## 6. SOP C — Supplier incident scorecard (deterministic; scores perfectly)164165Inputs: a request payload with the date filter, duration rule, precision rules, severe-severity166set, and an explicit recommendation policy with a precedence list. Follow the payload literally.1671681. Filter incidents to `start_date ≤ open_date ≤ end_date` (inclusive). This filtered set is the169 population; its size is the percentage denominator.1702. Group by supplier_id (only suppliers with ≥1 filtered incident appear).1713. Per supplier:172 - incident_count; incident_percentage = count×100/N rounded to 1 decimal173 - rma_count (incident_type==RMA), work_order_count (==WORK_ORDER)174 - open_incident_count (status==open)175 - severe_incident_count (severity in the payload's severe set, typically {high,critical})176 - total_resolution_cost = Σ resolution_cost (2dp)177 - avg_duration_days = mean of per-incident durations (2dp), where duration =178 (close_date − open_date) days for closed, (analysis_date − open_date) days for open1794. recommendation_code by the payload precedence (first match wins). Example policy used:180 - ESCALATE_SUPPLIER: (quality_status==quality_hold AND count≥3) OR any critical RMA OR181 (rma_count≥3 AND total_cost≥15000)182 - PROCESS_REVIEW: work_order_count≥3 AND work_order_count>rma_count183 - WATCHLIST: quality_status in {watch,quality_hold} OR count≥4 OR total_cost≥12000 OR severe≥2184 - MONITOR: otherwise185 Always read the actual thresholds from the request payload — they are authoritative.1865. summary: filtered_incident_count, supplier_count, total_resolution_cost(2dp),187 overall_rma_count, overall_work_order_count.188 top_escalation_suppliers: only ESCALATE rows, ordered incident_count desc, total_resolution_cost189 desc, supplier_id asc → list of supplier_id strings.190 highest_cost_supplier_id = max total_resolution_cost; highest_share_supplier_id = max191 incident_count. supplier_scorecard sorted supplier_id asc.192193## 7. SOP D — Mixed-warehouse line allocation (scores perfectly)194195Inputs: a wave of orders; classify every line as ship | transfer | backorder | manual_review.196197Per order (account state first, Section 3):1981. If order has an account/risk stop (account_blocked, fraud_watch, review_required): set EVERY199 line action = `manual_review` with that primary_reason, and add order_id to `blocked_orders`.2002. Else per line, with `requested_effective_available = on_hand − reserved − quarantined −201 safety_stock` at the requested warehouse (Section 2; report this signed integer):202 - product inactive → `manual_review`, primary_reason `inactive_product` (NOT a blocked order)203 - requested eff ≥ qty → `ship`, ship_quantity = qty204 - else ship the usable requested qty (max(0, eff)); for the remainder, if ONE other warehouse's205 running effective available can cover it → `transfer` (transfer_from = that source,206 transfer_quantity = remainder), primary_reason insufficient_effective_stock207 - else `backorder` (backorder_quantity = remainder), primary_reason insufficient_effective_stock208 Maintain a running per-(warehouse,sku) remaining-availability map so ship/transfer allocations209 across lines don't double-spend the same stock.2103. transfer_requests: {order_id, line_id, sku, from_warehouse, to_warehouse(=requested), quantity}.2114. order_rollup outcome — handle `mixed_actions` carefully (this was the subtle scoring trap):212 - actions == {ship} → ready_to_ship213 - actions ⊆ {ship,transfer} and a transfer present → needs_transfer214 - actions == {manual_review} → manual_review215 - actions ⊆ {ship,transfer,backorder} and a backorder present → has_backorder216 - else → `mixed_actions` (e.g. manual_review combined with backorder/ship/transfer)2175. blocked_orders = order-level account/risk stops only (sorted unique); line-only inactive reviews218 are NOT blocked orders.2196. summary integers: total_orders, total_lines, ship_lines, transfer_lines, backorder_lines,220 manual_review_lines, blocked_orders(count), transfer_units(Σ transfer_quantity),221 backorder_units(Σ backorder_quantity).222 Sort line_actions and transfer_requests by (order_id, line_id); order_rollup & blocked by order_id.223224## 8. SOP E — Procurement quality-control decision (partially specified)225226Inputs: an analysis window, a list of target supplier_ids, and decision_choices227(freeze_new_replenishment | buyer_review_required | monitor_only). The memo gives little numeric228policy; compute the data fields exactly and apply conservative status-driven logic.229230Per supplier (incidents filtered to `start ≤ open_date ≤ end`):231- recent_incident_count, recent_rma_count, severe_or_critical_count (high|critical),232 open_incident_count (status==open), affected_skus (sorted unique incident SKUs),233 sample_incident_ids (sorted, max 5).234- held_po_ids = the supplier's open/confirmed purchase order ids (sorted) when the supplier is235 frozen.236- decision:237 - `freeze_new_replenishment` when quality_status == quality_hold (verified) — hold its238 open/confirmed POs.239 - `buyer_review_required` when quality_status == watch with elevated recent risk240 (e.g. RMAs, open incidents, or multiple severe/critical incidents).241 - `monitor_only` otherwise.242- summary: suppliers_reviewed, freeze_count, buyer_review_count, monitor_count, held_po_count,243 total_recent_incidents. held_po_ids(top-level) = sorted unique across suppliers;244 release_supplier_ids = suppliers whose decision is monitor_only.245246CAUTION (unresolved): the exact watch→{buyer_review vs monitor} threshold and whether held_po_ids247should be filtered to affected SKUs are not fully nailed down. Prefer the supplier's quality_status248as the primary driver, compute every numeric field precisely, and keep held_po_ids = the frozen249supplier's full open/confirmed PO set unless the payload says otherwise.250251---252253## 9. Output formatting conventions (apply to every task)254255- Emit ONLY the JSON object matching `answer_template.json`. No prose, no extra keys, all required256 keys present.257- Honor `required_value` fields exactly (e.g. wave_id, task_id literals).258- Currency / cost fields: round to 2 decimals. Percentages: round to 1 decimal unless told otherwise.259 Durations: 2 decimals.260- Integer fields (counts, quantities, units, zone_distance, service_days,261 requested_effective_available) must be integers — including negative effective-availability values.262- Enums: use only the template's allowed values; never invent new ones.263- Apply every stated sort order exactly (usually order_id/line_id/sku/supplier_id ascending, with264 the documented multi-key tiebreakers). Sort SKU/id lists ascending and de-duplicate.265- Build summary counts/totals from the per-record results you actually emitted (keep them consistent).266267## 10. Common scoring pitfalls (and the fix)2682691. Forgetting `− safety_stock` in effective availability → cascades wrong everywhere. Always270 subtract reserved + quarantined + safety_stock (Section 2).2712. Clamping negative effective availability to 0 → keep it signed.2723. Using ALL wave orders when the memo lists a subset → use only the memo's order_ids.2734. Counting received/cancelled POs as coverage → only open/confirmed POs count, and (for timely274 coverage) only those with eta ≤ needed_by.2755. `timely_po_covered_units` reported as full PO quantity instead of the gap actually closed.2766. order_rollup: labeling an order has_backorder/needs_transfer when it also has a manual_review277 line → that mix is `mixed_actions`.2787. Treating a line-only inactive-product review as an account-level blocked order → it is not.2798. Incident windows filter on `open_date`; open-incident duration runs to the analysis_date, not280 today.