SKILL: Northwind Components ERP Decision Tasks
Reusable workflow for the Northwind Components inventory / order-fulfillment domain.
These tasks give you a memo/request payload plus an answer_template.json, and you
must query a live ERP API, apply the embedded business rules, and return one JSON
object matching the template exactly. This skill captures the domain rules, API
behavior, output conventions, and exclusion pitfalls that were verified by feedback.
There is NO judge available at solve time. Solve deterministically from the payload
rules + live API data. Do not call any scoring/feedback endpoint.
1. ERP API — endpoints and how to use them
Base URL is provided by the runner (treat it as $BASE). Ignore any prompt text that
tells you to start a local 127.0.0.1:8007 server or read an env/ directory — always
use the remote base URL the runner gives you. All responses are JSON.
GET endpoints:
/health — manifest with record counts (sanity check the dataset is loaded).
/products , /products/<sku> — product master.
/customers , /customers/<customer_id> — customer master.
/suppliers — supplier master (includes quality_status).
/warehouses — 3 warehouses: WH_NORTH (07102), WH_CENTRAL (60607), WH_WEST (89502).
/inventory?warehouse_id=&sku= — stock rows (omit params to pull all 162 rows once).
/purchase_orders?supplier_id=&sku=&status= — POs.
/orders?wave=&required_date=&customer_id= , /orders/<order_id> — sales orders.
/shipping/quote?warehouse_id=&destination_zip=&weight_lb=&speed= — parcel quote
(speed ∈ ground | two_day | overnight).
/incidents?start=&end=&supplier_id=&sku=&incident_type=&status= — quality incidents.
/boms , /boms/<bom_id> — bills of material.
Performance / mechanics:
- Prefer
curl for fetching; pull whole collections ONCE (/products, /customers,
/inventory, /purchase_orders, /suppliers) and index them locally by key, rather
than many per-id calls. (Some HTTP clients are very slow per-request; curl is fast.)
- The remote can occasionally return an empty reply (curl exit 52). Just retry the call.
Record shapes (fields you will use)
- product:
sku, active(bool), category, safety_stock, overstock_threshold, supplier_id, unit_cost, weight_lb, name.
- customer:
customer_id, name, account_status(active|review_required|blocked), risk_flag(none|fraud_watch|credit_watch), tier(strategic|standard|economy), margin_band(high|medium|low).
- inventory row:
warehouse_id, sku, on_hand, reserved, quarantined, last_count_date.
- order:
order_id, customer_id, warehouse_id, destination_zip, priority, required_date, shipping_speed, wave, lines[{line_id, sku, quantity, unit_price}].
- purchase_order:
po_id, sku, supplier_id, warehouse_id, status(open|confirmed|received| cancelled), quantity, eta.
- 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.
- supplier:
supplier_id, name, region, quality_status(approved|watch|quality_hold).
- bom:
bom_id, name, warehouse_id, target_date, components[{sku, quantity_per_kit}].
Incident date-window behavior
/incidents?start=&end= filters on open_date and is INCLUSIVE of both ends. The API
window matches the payload's incident_date_filter exactly; you can trust it as the
filtered population (no client-side re-filtering needed if you pass the payload dates).
Quote endpoint: total_cost is deterministic given (warehouse, zip, weight_lb, speed);
it scales with weight to the cent, so the weight you pass matters. zone_distance and
service_days depend only on warehouse→zip and speed, not on weight.
2. Core business definitions (used across multiple task types)
Effective / available-to-promise (ATP) stock — CRITICAL
"Effective available" stock is NOT raw on_hand. The allocation memos state that stock
"already reserved, quarantined, or held as normal operating buffer" is not freely
available. The normal operating buffer = the product's safety_stock. So:
effective_available(wh, sku) = max(0, on_hand - reserved - quarantined - safety_stock)
Use this for line allocation decisions and for the requested_effective_available
output field. (A simpler on_hand - reserved - quarantined ATP exists, but when a memo
mentions "normal operating buffer" / "protected stock", subtract safety_stock too.)
When deciding transfers, a source warehouse may only contribute its OWN effective
available (never dipping into its protected/safety stock).
Customer exception precedence (account/risk gating)
From customer master, map to an exception, hardest first:
account_status == blocked -> account_blocked
risk_flag == fraud_watch -> fraud_watch
risk_flag == credit_watch -> credit_watch
account_status == review_required -> account_review_required (a.k.a. review_required)
- else -> none
"Blocked orders" (orders stopped at account / customer-risk level) include ALL
account-level holds: account_blocked, fraud_watch, AND review_required. Verified: a
product-only review (inactive SKU) is a LINE-level review and does NOT make the order a
"blocked order". (Removing review_required from the blocked set produced wrong results —
keep it in.)
Product status gating
active == false => the line needs manual_review with reason inactive_product. This
is a line-level product-master review, not an account block.
Severity
"Severe" / "severe_or_critical" = severity in {high, critical}.
Incident duration (days)
- closed incident: calendar days from
open_date to close_date.
- open incident: calendar days from
open_date to the analysis_date in the payload.
Round per the payload's duration_precision (usually 2 decimals).
Purchase-order eligibility
- "Timely" / coverage POs for a build: same target warehouse,
status ∈ {open, confirmed},
and eta <= needed_by (the build/needed date). received POs are already reflected in
on_hand — do not double-count them. cancelled POs never count.
- For supplier "held PO" controls: open or confirmed POs for that supplier.
3. Output conventions (apply to every task)
- Return ONLY the JSON object; no prose, no markdown fences.
- Include EVERY
required_top_level_key and every item_required_keys field, even when
empty ([], 0, "none", or null where the enum allows null).
- Respect enums exactly — never invent values outside
allowed_values.
- Sorting: follow each list's stated
ordering precisely. Common ones:
- records/line_actions: by
order_id asc, then line_id asc.
- SKU lists: ascending by SKU string.
- scorecards:
supplier_id ascending.
- tie-break chains (e.g. top-escalation):
incident_count desc, then
total_resolution_cost desc, then supplier_id asc — implement the FULL chain.
- transfer_requests sometimes: sku asc, then quantity desc, then from_warehouse asc.
- Currency: round to 2 decimals (
unit_cost, extended_cost, total_*_cost,
total_cost_usd). extended_cost = round(unit_cost * quantity, 2).
- Percentages: round to 1 decimal; denominator = the full filtered population unless the
payload says otherwise.
- Integer fields stay integers (counts, unit quantities, zone_distance, service_days).
required_value fields (e.g. wave_id, task_id) must equal the literal required value.
- Summary list fields (blocked_order_ids, manual_review_order_ids, etc.) must be sorted
and consistent with the per-record results.
sample_incident_ids: sorted list, capped at MAX 5.
affected_skus: sorted unique set of SKUs from the filtered incidents.
4. SOP per task archetype
A. Supplier incident scorecard (fully rule-specified — most reliable)
The request payload supplies the entire policy (filter window, duration rule, percentage
rule, severe values, recommendation precedence + code conditions). Follow it literally.
- GET
/incidents?start=&end= with the payload window; GET /suppliers.
- Group incidents by
supplier_id. supplier_count = suppliers with >=1 filtered incident.
- Per supplier compute: incident_count, incident_percentage (of full population, 1 dp),
total_resolution_cost (2 dp), avg_duration_days (2 dp, per duration rule),
rma_count, work_order_count, open_incident_count, severe_incident_count (high|critical).
- recommendation_code — evaluate the precedence list TOP-DOWN, first match wins. Read each
code's conditions exactly (e.g. ESCALATE if on quality_hold with >=N incidents, OR any
critical RMA, OR >=N RMAs with >= $X cost; PROCESS_REVIEW if WORK_ORDER>=3 and
WORK_ORDER>RMA; WATCHLIST if quality_status in {watch,quality_hold} or count>=4 or
cost>=12000 or severe>=2; else MONITOR). Use the exact thresholds from the payload.
- top_escalation_suppliers = only ESCALATE rows, sorted by the stated tie-break chain.
- highest_cost_supplier_id / highest_share_supplier_id = argmax (tie-break supplier_id asc).
This archetype is fully deterministic when the payload rules are followed exactly.
B. Wave allocation / transfer decision (line-level)
- GET the wave:
/orders?wave=<WAVE_ID>. GET customers, products, inventory.
- For each order line in sort order:
a. Customer gate first: blocked/fraud/review_required =>
manual_review, primary_reason
= account_blocked | fraud_watch | account_review_required; add order to blocked_orders.
b. Product gate: inactive => manual_review, primary_reason = inactive_product (NOT a
blocked order).
c. Else allocate from requested warehouse effective_available (ATP minus safety stock):
- eff_avail >= qty ->
ship, ship_quantity = qty.
- eff_avail < qty but one other warehouse's effective stock can cover the remainder ->
transfer: ship_quantity = usable requested-wh qty, pick ONE source warehouse for
the uncovered quantity (transfer_from / transfer_quantity), add a transfer_request.
- otherwise ->
backorder, backorder_quantity = qty, reason insufficient_effective_stock.
d. Consume allocated stock as you go so later lines see the reduced availability.
- order_rollup outcome per order from its line action set:
- all ship -> ready_to_ship
- involves transfer (with/without ship) -> needs_transfer
- has a backorder line (e.g. ship+backorder) -> has_backorder
- all manual_review -> manual_review
- other combinations (e.g. manual_review + transfer/backorder) -> mixed_actions
(Verified: ship+backorder => has_backorder, NOT mixed_actions.)
- blocked_orders = account-level holds (blocked, fraud, review_required), sorted.
- summary counts: total_orders, total_lines, ship/transfer/backorder/manual_review_lines,
blocked_orders (count), transfer_units (sum transfer_quantity), backorder_units.
C. Replenishment / kit MRP from BOMs
- GET each BOM (
/boms/<id>). total_required per component = sum over builds of
(build_quantity * quantity_per_kit), aggregated across BOMs that share a SKU.
- target_effective_available at the planning warehouse (ATP). Gap = required - available.
- timely_po_qty = same-warehouse open/confirmed POs with eta <= needed_by; if they cover
the gap -> final_action timely_po_covered / exclusion timely_po_covers_gap.
- If a gap remains, cover from other warehouses' effective stock (transfer_only), else
raise a purchase_requisition for the shortfall (purchase_required) at the product's
supplier_id and unit_cost (extended_cost = unit_cost*qty, 2 dp).
- If available already meets required -> no_action_stocked / stocked_no_gap. If a SKU is
already over
overstock_threshold, exclude it (target_overstock) and do not add stock.
- needed_by = earliest build_date among BOMs using that component. Sort/round per template.
D. Supplier replenishment-control (incidents + quality + POs)
- GET
/incidents?start=&end=&supplier_id= per target supplier and /suppliers,
/purchase_orders?supplier_id=.
- Per supplier compute recent_incident_count, recent_rma_count, severe_or_critical_count,
open_incident_count, affected_skus (sorted unique), sample_incident_ids (sorted, <=5).
- decision ∈ {freeze_new_replenishment, buyer_review_required, monitor_only}. Baseline:
quality_hold -> freeze; watch -> buyer_review; approved -> monitor; and let recent
incident activity (open incidents / severity / counts) escalate or de-escalate per any
thresholds the payload states. held_po_ids for a supplier = its open/confirmed PO ids
when the decision is not monitor_only.
- held_po_ids (top level) = sorted unique union; release_supplier_ids = monitor_only
suppliers; summary tallies the decision counts, held_po_count, total_recent_incidents.
5. Common misjudgments that cause wrong answers (avoid these)
- Using raw on_hand (or even on_hand-reserved-quarantined) as "available" when the memo
says protected/normal-buffer stock is excluded — you must subtract
safety_stock too.
- Dropping review_required orders from
blocked_orders. Account review IS account-level;
it belongs in blocked_orders. Only inactive-product (line-level) reviews are excluded.
- Treating an inactive-product manual_review as an account block (it is line-level only).
- Counting
received/cancelled POs as coverage. Only open/confirmed, and only with
eta <= needed_by, are "timely".
- Forgetting the full multi-key sort/tie-break chains; partial sorts fail ordering checks.
- Currency not rounded to exactly 2 dp, percentages not 1 dp, or putting floats where the
template demands integers.
- Passing the wrong weight to
/shipping/quote (it changes total_cost to the cent).
- Omitting required keys when empty — always emit
[], 0, "none", or null.
- Misreading the recommendation/decision precedence: evaluate top-down, FIRST match wins,
and use the exact numeric thresholds from the payload rather than guessing.
6. General execution checklist
- Read the prompt + every payload file (memo + answer_template.json). The payload often
contains the EXACT policy/thresholds — encode them literally; do not improvise rules.
- Identify the archetype (A/B/C/D above) and the key entities to pull.
- Pull whole collections once via curl; index locally; query targeted endpoints (wave,
incidents window, supplier POs) as needed.
- Compute with effective-stock, customer/product gating, and date-window rules above.
- Build output strictly to the template: keys, enums, sort orders, rounding, integers.
- Validate: every required key present, enums valid, lists sorted, currency 2 dp,
summary consistent with detail rows, required_value literals correct.
- Emit only the JSON object.
1---2name: reflect-3-attempt-01-263description: SKILL: Northwind Components ERP Decision Tasks4---5# SKILL: Northwind Components ERP Decision Tasks67Reusable workflow for the Northwind Components inventory / order-fulfillment domain.8These tasks give you a memo/request payload plus an `answer_template.json`, and you9must query a live ERP API, apply the embedded business rules, and return one JSON10object matching the template exactly. This skill captures the domain rules, API11behavior, output conventions, and exclusion pitfalls that were verified by feedback.1213There is NO judge available at solve time. Solve deterministically from the payload14rules + live API data. Do not call any scoring/feedback endpoint.1516---1718## 1. ERP API — endpoints and how to use them1920Base URL is provided by the runner (treat it as `$BASE`). Ignore any prompt text that21tells you to start a local `127.0.0.1:8007` server or read an `env/` directory — always22use the remote base URL the runner gives you. All responses are JSON.2324GET endpoints:25- `/health` — manifest with record counts (sanity check the dataset is loaded).26- `/products` , `/products/<sku>` — product master.27- `/customers` , `/customers/<customer_id>` — customer master.28- `/suppliers` — supplier master (includes `quality_status`).29- `/warehouses` — 3 warehouses: `WH_NORTH` (07102), `WH_CENTRAL` (60607), `WH_WEST` (89502).30- `/inventory?warehouse_id=&sku=` — stock rows (omit params to pull all 162 rows once).31- `/purchase_orders?supplier_id=&sku=&status=` — POs.32- `/orders?wave=&required_date=&customer_id=` , `/orders/<order_id>` — sales orders.33- `/shipping/quote?warehouse_id=&destination_zip=&weight_lb=&speed=` — parcel quote34 (`speed` ∈ ground | two_day | overnight).35- `/incidents?start=&end=&supplier_id=&sku=&incident_type=&status=` — quality incidents.36- `/boms` , `/boms/<bom_id>` — bills of material.3738Performance / mechanics:39- Prefer `curl` for fetching; pull whole collections ONCE (`/products`, `/customers`,40 `/inventory`, `/purchase_orders`, `/suppliers`) and index them locally by key, rather41 than many per-id calls. (Some HTTP clients are very slow per-request; curl is fast.)42- The remote can occasionally return an empty reply (curl exit 52). Just retry the call.4344### Record shapes (fields you will use)45- product: `sku, active(bool), category, safety_stock, overstock_threshold, supplier_id,46 unit_cost, weight_lb, name`.47- customer: `customer_id, name, account_status(active|review_required|blocked),48 risk_flag(none|fraud_watch|credit_watch), tier(strategic|standard|economy),49 margin_band(high|medium|low)`.50- inventory row: `warehouse_id, sku, on_hand, reserved, quarantined, last_count_date`.51- order: `order_id, customer_id, warehouse_id, destination_zip, priority, required_date,52 shipping_speed, wave, lines[{line_id, sku, quantity, unit_price}]`.53- purchase_order: `po_id, sku, supplier_id, warehouse_id, status(open|confirmed|received|54 cancelled), quantity, eta`.55- incident: `incident_id, supplier_id, sku, warehouse_id, incident_type(RMA|WORK_ORDER),56 severity(low|medium|high|critical), status(open|closed), open_date, close_date,57 resolution_cost, root_cause`.58- supplier: `supplier_id, name, region, quality_status(approved|watch|quality_hold)`.59- bom: `bom_id, name, warehouse_id, target_date, components[{sku, quantity_per_kit}]`.6061### Incident date-window behavior62`/incidents?start=&end=` filters on `open_date` and is INCLUSIVE of both ends. The API63window matches the payload's `incident_date_filter` exactly; you can trust it as the64filtered population (no client-side re-filtering needed if you pass the payload dates).65Quote endpoint: `total_cost` is deterministic given (warehouse, zip, weight_lb, speed);66it scales with weight to the cent, so the weight you pass matters. `zone_distance` and67`service_days` depend only on warehouse→zip and speed, not on weight.6869---7071## 2. Core business definitions (used across multiple task types)7273### Effective / available-to-promise (ATP) stock — CRITICAL74"Effective available" stock is NOT raw on_hand. The allocation memos state that stock75"already reserved, quarantined, or held as normal operating buffer" is not freely76available. The normal operating buffer = the product's `safety_stock`. So:7778 effective_available(wh, sku) = max(0, on_hand - reserved - quarantined - safety_stock)7980Use this for line allocation decisions and for the `requested_effective_available`81output field. (A simpler `on_hand - reserved - quarantined` ATP exists, but when a memo82mentions "normal operating buffer" / "protected stock", subtract `safety_stock` too.)83When deciding transfers, a source warehouse may only contribute its OWN effective84available (never dipping into its protected/safety stock).8586### Customer exception precedence (account/risk gating)87From customer master, map to an exception, hardest first:881. `account_status == blocked` -> account_blocked892. `risk_flag == fraud_watch` -> fraud_watch903. `risk_flag == credit_watch` -> credit_watch914. `account_status == review_required` -> account_review_required (a.k.a. review_required)925. else -> none9394"Blocked orders" (orders stopped at account / customer-risk level) include ALL95account-level holds: account_blocked, fraud_watch, AND review_required. Verified: a96product-only review (inactive SKU) is a LINE-level review and does NOT make the order a97"blocked order". (Removing review_required from the blocked set produced wrong results —98keep it in.)99100### Product status gating101`active == false` => the line needs `manual_review` with reason `inactive_product`. This102is a line-level product-master review, not an account block.103104### Severity105"Severe" / "severe_or_critical" = severity in {high, critical}.106107### Incident duration (days)108- closed incident: calendar days from `open_date` to `close_date`.109- open incident: calendar days from `open_date` to the `analysis_date` in the payload.110Round per the payload's `duration_precision` (usually 2 decimals).111112### Purchase-order eligibility113- "Timely" / coverage POs for a build: same target warehouse, `status ∈ {open, confirmed}`,114 and `eta <= needed_by` (the build/needed date). `received` POs are already reflected in115 on_hand — do not double-count them. `cancelled` POs never count.116- For supplier "held PO" controls: open or confirmed POs for that supplier.117118---119120## 3. Output conventions (apply to every task)121122- Return ONLY the JSON object; no prose, no markdown fences.123- Include EVERY `required_top_level_key` and every `item_required_keys` field, even when124 empty (`[]`, `0`, `"none"`, or `null` where the enum allows null).125- Respect enums exactly — never invent values outside `allowed_values`.126- Sorting: follow each list's stated `ordering` precisely. Common ones:127 - records/line_actions: by `order_id` asc, then `line_id` asc.128 - SKU lists: ascending by SKU string.129 - scorecards: `supplier_id` ascending.130 - tie-break chains (e.g. top-escalation): `incident_count` desc, then131 `total_resolution_cost` desc, then `supplier_id` asc — implement the FULL chain.132 - transfer_requests sometimes: sku asc, then quantity desc, then from_warehouse asc.133- Currency: round to 2 decimals (`unit_cost`, `extended_cost`, `total_*_cost`,134 `total_cost_usd`). `extended_cost = round(unit_cost * quantity, 2)`.135- Percentages: round to 1 decimal; denominator = the full filtered population unless the136 payload says otherwise.137- Integer fields stay integers (counts, unit quantities, zone_distance, service_days).138- `required_value` fields (e.g. `wave_id`, `task_id`) must equal the literal required value.139- Summary list fields (blocked_order_ids, manual_review_order_ids, etc.) must be sorted140 and consistent with the per-record results.141- `sample_incident_ids`: sorted list, capped at MAX 5.142- `affected_skus`: sorted unique set of SKUs from the filtered incidents.143144---145146## 4. SOP per task archetype147148### A. Supplier incident scorecard (fully rule-specified — most reliable)149The request payload supplies the entire policy (filter window, duration rule, percentage150rule, severe values, recommendation precedence + code conditions). Follow it literally.1511. GET `/incidents?start=&end=` with the payload window; GET `/suppliers`.1522. Group incidents by `supplier_id`. supplier_count = suppliers with >=1 filtered incident.1533. Per supplier compute: incident_count, incident_percentage (of full population, 1 dp),154 total_resolution_cost (2 dp), avg_duration_days (2 dp, per duration rule),155 rma_count, work_order_count, open_incident_count, severe_incident_count (high|critical).1564. recommendation_code — evaluate the precedence list TOP-DOWN, first match wins. Read each157 code's conditions exactly (e.g. ESCALATE if on quality_hold with >=N incidents, OR any158 critical RMA, OR >=N RMAs with >= $X cost; PROCESS_REVIEW if WORK_ORDER>=3 and159 WORK_ORDER>RMA; WATCHLIST if quality_status in {watch,quality_hold} or count>=4 or160 cost>=12000 or severe>=2; else MONITOR). Use the exact thresholds from the payload.1615. top_escalation_suppliers = only ESCALATE rows, sorted by the stated tie-break chain.1626. highest_cost_supplier_id / highest_share_supplier_id = argmax (tie-break supplier_id asc).163This archetype is fully deterministic when the payload rules are followed exactly.164165### B. Wave allocation / transfer decision (line-level)1661. GET the wave: `/orders?wave=<WAVE_ID>`. GET customers, products, inventory.1672. For each order line in sort order:168 a. Customer gate first: blocked/fraud/review_required => `manual_review`, primary_reason169 = account_blocked | fraud_watch | account_review_required; add order to blocked_orders.170 b. Product gate: inactive => `manual_review`, primary_reason = inactive_product (NOT a171 blocked order).172 c. Else allocate from requested warehouse effective_available (ATP minus safety stock):173 - eff_avail >= qty -> `ship`, ship_quantity = qty.174 - eff_avail < qty but one other warehouse's effective stock can cover the remainder ->175 `transfer`: ship_quantity = usable requested-wh qty, pick ONE source warehouse for176 the uncovered quantity (transfer_from / transfer_quantity), add a transfer_request.177 - otherwise -> `backorder`, backorder_quantity = qty, reason insufficient_effective_stock.178 d. Consume allocated stock as you go so later lines see the reduced availability.1793. order_rollup outcome per order from its line action set:180 - all ship -> ready_to_ship181 - involves transfer (with/without ship) -> needs_transfer182 - has a backorder line (e.g. ship+backorder) -> has_backorder183 - all manual_review -> manual_review184 - other combinations (e.g. manual_review + transfer/backorder) -> mixed_actions185 (Verified: ship+backorder => has_backorder, NOT mixed_actions.)1864. blocked_orders = account-level holds (blocked, fraud, review_required), sorted.1875. summary counts: total_orders, total_lines, ship/transfer/backorder/manual_review_lines,188 blocked_orders (count), transfer_units (sum transfer_quantity), backorder_units.189190### C. Replenishment / kit MRP from BOMs1911. GET each BOM (`/boms/<id>`). total_required per component = sum over builds of192 (build_quantity * quantity_per_kit), aggregated across BOMs that share a SKU.1932. target_effective_available at the planning warehouse (ATP). Gap = required - available.1943. timely_po_qty = same-warehouse open/confirmed POs with eta <= needed_by; if they cover195 the gap -> final_action timely_po_covered / exclusion timely_po_covers_gap.1964. If a gap remains, cover from other warehouses' effective stock (transfer_only), else197 raise a purchase_requisition for the shortfall (purchase_required) at the product's198 supplier_id and unit_cost (extended_cost = unit_cost*qty, 2 dp).1995. If available already meets required -> no_action_stocked / stocked_no_gap. If a SKU is200 already over `overstock_threshold`, exclude it (target_overstock) and do not add stock.2016. needed_by = earliest build_date among BOMs using that component. Sort/round per template.202203### D. Supplier replenishment-control (incidents + quality + POs)2041. GET `/incidents?start=&end=&supplier_id=` per target supplier and `/suppliers`,205 `/purchase_orders?supplier_id=`.2062. Per supplier compute recent_incident_count, recent_rma_count, severe_or_critical_count,207 open_incident_count, affected_skus (sorted unique), sample_incident_ids (sorted, <=5).2083. decision ∈ {freeze_new_replenishment, buyer_review_required, monitor_only}. Baseline:209 quality_hold -> freeze; watch -> buyer_review; approved -> monitor; and let recent210 incident activity (open incidents / severity / counts) escalate or de-escalate per any211 thresholds the payload states. held_po_ids for a supplier = its open/confirmed PO ids212 when the decision is not monitor_only.2134. held_po_ids (top level) = sorted unique union; release_supplier_ids = monitor_only214 suppliers; summary tallies the decision counts, held_po_count, total_recent_incidents.215216---217218## 5. Common misjudgments that cause wrong answers (avoid these)219220- Using raw on_hand (or even on_hand-reserved-quarantined) as "available" when the memo221 says protected/normal-buffer stock is excluded — you must subtract `safety_stock` too.222- Dropping review_required orders from `blocked_orders`. Account review IS account-level;223 it belongs in blocked_orders. Only inactive-product (line-level) reviews are excluded.224- Treating an inactive-product manual_review as an account block (it is line-level only).225- Counting `received`/`cancelled` POs as coverage. Only open/confirmed, and only with226 `eta <= needed_by`, are "timely".227- Forgetting the full multi-key sort/tie-break chains; partial sorts fail ordering checks.228- Currency not rounded to exactly 2 dp, percentages not 1 dp, or putting floats where the229 template demands integers.230- Passing the wrong weight to `/shipping/quote` (it changes `total_cost` to the cent).231- Omitting required keys when empty — always emit `[]`, `0`, `"none"`, or `null`.232- Misreading the recommendation/decision precedence: evaluate top-down, FIRST match wins,233 and use the exact numeric thresholds from the payload rather than guessing.234235---236237## 6. General execution checklist2382391. Read the prompt + every payload file (memo + answer_template.json). The payload often240 contains the EXACT policy/thresholds — encode them literally; do not improvise rules.2412. Identify the archetype (A/B/C/D above) and the key entities to pull.2423. Pull whole collections once via curl; index locally; query targeted endpoints (wave,243 incidents window, supplier POs) as needed.2444. Compute with effective-stock, customer/product gating, and date-window rules above.2455. Build output strictly to the template: keys, enums, sort orders, rounding, integers.2466. Validate: every required key present, enums valid, lists sorted, currency 2 dp,247 summary consistent with detail rows, required_value literals correct.2487. Emit only the JSON object.