Northwind Components ERP Task Group Skill
1. Environment & API Access
- Read
environment_access.md first. It overrides any localhost/127.0.0.1 references in task prompts. Use only the remote base URL declared there (e.g. http://34.46.77.124:8007).
- Do not read, list, or inspect
env/ source directories. Do not run setup.sh or server.py.
- Base URL: Use the URL from
environment_access.md. All endpoints are read-only GET.
- Do not invent endpoints. The canonical list is:
GET /, GET /health
GET /products, GET /products/<sku>
GET /customers, GET /customers/<customer_id>
GET /warehouses
GET /inventory?warehouse_id=&sku= (both params optional; returns list)
GET /purchase_orders?supplier_id=&sku=&status= (returns list)
GET /orders?wave=&required_date=&customer_id= (returns list), GET /orders/<order_id>
GET /shipping/quote?warehouse_id=&destination_zip=&weight_lb=&speed=
GET /incidents?start=&end=&supplier_id=&sku=&incident_type=&status= (returns list)
GET /suppliers
GET /boms, GET /boms/<bom_id>
2. Core Data Models
Order
{
"order_id": "SO-XXXXX",
"customer_id": "CUST-XXXX",
"destination_zip": "XXXXX",
"lines": [{"line_id": 1, "quantity": 10, "sku": "NW-XXXX", "unit_price": 123.45}],
"priority": "normal|high|critical|low",
"required_date": "YYYY-MM-DD",
"shipping_speed": "ground|two_day|overnight",
"warehouse_id": "WH_NORTH|WH_CENTRAL|WH_WEST",
"wave": "STRING"
}
Product
{
"sku": "NW-XXXX",
"name": "...",
"category": "...",
"active": true|false,
"supplier_id": "SUP-XXX",
"unit_cost": 123.45,
"weight_lb": 12.34,
"safety_stock": 10,
"overstock_threshold": 100
}
Customer
{
"customer_id": "CUST-XXXX",
"name": "...",
"account_status": "active|blocked|review_required",
"risk_flag": "none|fraud_watch|credit_watch",
"tier": "strategic|standard|economy",
"margin_band": "high|medium|low"
}
Inventory Record
{
"sku": "NW-XXXX",
"warehouse_id": "WH_...",
"on_hand": 100,
"reserved": 20,
"quarantined": 5,
"last_count_date": "YYYY-MM-DD"
}
- Effective available =
on_hand - reserved - quarantined. This is the only quantity usable for wave release, transfer sourcing, or stock checks.
Supplier
{
"supplier_id": "SUP-XXX",
"name": "...",
"quality_status": "approved|watch|quality_hold",
"region": "..."
}
Incident
{
"incident_id": "INC-XXXXX",
"supplier_id": "SUP-XXX",
"sku": "NW-XXXX",
"warehouse_id": "WH_...",
"incident_type": "RMA|WORK_ORDER",
"severity": "low|medium|high|critical",
"status": "open|closed",
"open_date": "YYYY-MM-DD",
"close_date": "YYYY-MM-DD|null",
"resolution_cost": 1234.56,
"root_cause": "..."
}
Purchase Order
{
"po_id": "PO-XXXXX",
"supplier_id": "SUP-XXX",
"sku": "NW-XXXX",
"warehouse_id": "WH_...",
"quantity": 100,
"status": "open|confirmed|cancelled|received",
"eta": "YYYY-MM-DD"
}
- For coverage calculations, only
open and confirmed POs count as "timely."
BOM
{
"bom_id": "BOM-XXX",
"name": "...",
"warehouse_id": "WH_...",
"target_date": "YYYY-MM-DD",
"components": [{"sku": "NW-XXXX", "quantity_per_kit": 4}]
}
Shipping Quote
{
"zone_distance": 3,
"service_days": 1,
"total_cost": 225.67,
"base_rate": 77.95,
"fuel_surcharge_rate": 0.0925,
"carrier": "Northwind Parcel"
}
speed must be exactly ground, two_day, or overnight.
weight_lb is the total order weight (sum of line.quantity * product.weight_lb).
3. Controlled Vocabularies (Exact Strings)
Inventory Status
ready, low_stock, shortage, inactive_sku, inactive_and_shortage
Customer Exception
none, review_required, account_blocked, fraud_watch, credit_watch
- Mapping rule:
account_status == "blocked" → account_blocked
risk_flag == "fraud_watch" → fraud_watch
risk_flag == "credit_watch" → credit_watch
account_status == "review_required" → review_required
- otherwise →
none
Final Decision (Expedite)
ship_now, delayed_release, manual_review, backorder, reject_hold
Next Action (Expedite)
release_to_pick, delay_and_monitor, send_account_review, create_backorder, hold_credit_or_fraud, escalate_product_master
Line Action (Allocation)
ship, transfer, backorder, manual_review
Primary Reason (Allocation)
none, account_blocked, account_review_required, fraud_watch, inactive_product, insufficient_effective_stock
Final Action (Kit Replenishment)
no_action_stocked, transfer_only, purchase_required, timely_po_covered, overstock_excluded
Exclusion Reason (Kit Replenishment)
none, target_overstock, timely_po_covers_gap, stocked_no_gap
Recommendation Code (Supplier Scorecard)
ESCALATE_SUPPLIER, PROCESS_REVIEW, WATCHLIST, MONITOR
Supplier Decision (Quality Hold Review)
freeze_new_replenishment, buyer_review_required, monitor_only
4. Sorting Rules (Mandatory)
- Records by order: ascending by
order_id.
- Lines within order: ascending by
line_id.
- SKU lists: ascending alphabetical.
- Supplier lists / scorecard rows: ascending by
supplier_id.
- Transfer requests: ascending by
sku, then descending by quantity, then ascending by from_warehouse_id.
- Component plan / excluded components: ascending by
sku.
- Kit targets: ascending by
bom_id.
- PO ID lists: ascending.
- Incident ID lists: ascending.
- Order ID lists (summary blocks): ascending.
5. Rounding Rules
- Currency (USD): always round to exactly 2 decimal places in output.
- Percentages: round to 1 decimal place.
- Durations (days): round to 2 decimal places.
- Integers: do not round; use exact integer arithmetic.
6. Workflow Patterns by Task Type
6.1 Expedite Queue Decision (train_001 style)
- Read the queue memo to get the
wave_id and the list of order_ids to evaluate.
- Fetch the wave's orders via
/orders?wave=... or individual /orders/<id> calls.
- For each order:
- Fetch customer via
/customers/<customer_id>.
- For each line SKU, fetch product via
/products/<sku> and inventory via /inventory?warehouse_id=...&sku=....
- Determine
inventory_status:
- If any SKU
active == false → includes inactive_sku.
- If effective available < requested quantity → includes
shortage.
- If effective available >= quantity but < safety_stock →
low_stock.
- Otherwise
ready.
- Combine
inactive_sku + shortage → inactive_and_shortage.
- Determine
customer_exception using the mapping in §3.
- Determine
final_decision and next_action based on exception + inventory:
account_blocked → reject_hold / send_account_review (or hold_credit_or_fraud if credit_watch)
fraud_watch / credit_watch → reject_hold / hold_credit_or_fraud
review_required → manual_review / send_account_review
inactive_sku → backorder or manual_review / escalate_product_master
shortage → backorder / create_backorder
low_stock → delayed_release / delay_and_monitor
- All clear →
ship_now / release_to_pick
- Populate
shortage_skus, inactive_skus, low_stock_skus (sorted ascending).
- Call
/shipping/quote?warehouse_id=...&destination_zip=...&weight_lb=...&speed=... for the shipping object.
- Build
summary:
order_count
decision_counts with exact keys: ship_now, delayed_release, manual_review, backorder, reject_hold
total_shipping_cost_usd (sum of all record shipping quotes, 2 decimals)
blocked_order_ids, manual_review_order_ids, backorder_order_ids, inactive_sku_order_ids (sorted ascending)
6.2 Kit Replenishment / Production Planning (train_002 style)
- Read the production memo to get
planning_site (e.g. WH_WEST) and target builds (bom_id, build_quantity, build_date).
- Fetch each BOM via
/boms/<bom_id>.
- For each component SKU:
total_required = Σ(build_quantity × quantity_per_kit) across all target BOMs.
- Fetch inventory at
planning_site and all other warehouses.
target_effective_available = on_hand - reserved - quarantined at planning_site.
- Fetch POs via
/purchase_orders?sku=...&status=open and status=confirmed. Sum timely_po_qty for POs at the planning site.
- Determine
overstock_excluded if effective stock + incoming POs would push total above overstock_threshold.
- Compute gap =
total_required - target_effective_available - timely_po_qty.
- If gap > 0 and another warehouse has effective available without dropping below its own safety stock, create a
transfer_request with transfer_qty = min(gap, other_effective_available).
- If gap still > 0 after transfers, create a
purchase_requisition with:
quantity = remaining gap
unit_cost from /products/<sku> unit_cost
extended_cost = quantity * unit_cost (rounded to 2 decimals)
needed_by = earliest build_date
supplier_id from product
warehouse_id = planning site
- Set
final_action and exclusion_reason per the controlled vocab.
coverage_po_ids = sorted list of PO IDs that cover the timely portion.
- Sort
component_plan by sku ascending.
- Sort
transfer_requests by sku asc, quantity desc, from_warehouse_id asc.
- Sort
purchase_requisitions by sku ascending.
- Build
summary with exact keys from template.
6.3 Supplier Incident Scorecard (train_003 style)
- Read the scorecard request JSON for
incident_date_filter, analysis_date, recommendation_policy, etc.
- Fetch incidents via
/incidents?start=...&end=... using the filter window.
- Fetch all suppliers via
/suppliers.
- For each supplier with at least one filtered incident:
incident_count = count of filtered incidents for that supplier.
incident_percentage = (incident_count / total filtered incidents) × 100, rounded to 1 decimal.
total_resolution_cost = sum of resolution_cost for filtered incidents, rounded to 2 decimals.
avg_duration_days:
- Closed:
close_date - open_date (calendar days)
- Open:
analysis_date - open_date (calendar days)
- Average across all filtered incidents, rounded to 2 decimals.
rma_count = count where incident_type == "RMA".
work_order_count = count where incident_type == "WORK_ORDER".
open_incident_count = count where status == "open".
severe_incident_count = count where severity in (high, critical).
- Apply recommendation policy in strict precedence order (
ESCALATE_SUPPLIER > PROCESS_REVIEW > WATCHLIST > MONITOR). Check each rule exactly as defined in the request JSON.
- Sort scorecard rows by
supplier_id ascending.
top_escalation_suppliers = supplier_ids with recommendation_code == "ESCALATE_SUPPLIER", sorted by incident_count desc, then total_resolution_cost desc, then supplier_id asc.
highest_cost_supplier_id = supplier with max total_resolution_cost (tie-break not specified; use first or supplier_id ascending for stability).
highest_share_supplier_id = supplier with max incident_percentage.
6.4 Mixed-Warehouse Allocation (train_004 style)
- Fetch all orders for the wave via
/orders?wave=....
- For each order, fetch the customer record.
- For each line:
- Fetch product (
/products/<sku>) and inventory at the requested warehouse (/inventory?warehouse_id=...&sku=...).
requested_effective_available = on_hand - reserved - quarantined at requested warehouse.
- Account-level block first: If
account_status == "blocked", the entire order is blocked. All lines get action = "manual_review", primary_reason = "account_blocked".
- If
account_status == "review_required" → manual_review / account_review_required.
- If
risk_flag == "fraud_watch" → manual_review / fraud_watch.
- If
risk_flag == "credit_watch" → manual_review / credit_watch.
- If product
active == false → manual_review / inactive_product.
- If
requested_effective_available >= quantity → ship with ship_quantity = quantity.
- If
requested_effective_available < quantity:
- Check other warehouses for effective available (without dipping below their safety stock). If found,
transfer with ship_quantity = requested_effective_available, transfer_quantity = quantity - ship_quantity.
- If no other warehouse can cover,
backorder with backorder_quantity = quantity - requested_effective_available.
transfer_requests list: one entry per transfer line, sorted by order_id asc, line_id asc.
blocked_orders: list of order_id strings where account_status == "blocked", sorted ascending.
order_rollup: for each order, determine outcome:
ready_to_ship if all lines are ship
needs_transfer if any line is transfer and none are manual_review/backorder
has_backorder if any line is backorder
manual_review if any line is manual_review
mixed_actions if multiple different actions apply
summary must include all required integer keys from the template.
6.5 Quality Hold Review / Supplier Replenishment Control (train_005 style)
- Read the memo for
analysis_window (start, end) and target_supplier_ids.
- For each target supplier:
- Fetch supplier via
/suppliers/<supplier_id>.
- Fetch incidents via
/incidents?supplier_id=...&start=...&end=....
- Fetch POs via
/purchase_orders?supplier_id=...&status=open and status=confirmed.
- Compute:
recent_incident_count = count of incidents in window.
recent_rma_count = count of RMA incidents in window.
severe_or_critical_count = count with severity high or critical.
open_incident_count = count with status == "open".
affected_skus = sorted unique list of SKUs from incidents.
sample_incident_ids = sorted list of incident IDs, capped at 5.
held_po_ids = sorted list of open/confirmed PO IDs for this supplier.
- Determine
decision based on policy:
freeze_new_replenishment if quality_status == "quality_hold" AND significant incident/PO risk.
buyer_review_required if quality_status == "watch" or moderate incident load.
monitor_only if low risk.
- The exact thresholds come from the task memo; use the memo's policy text.
held_po_ids (top-level) = sorted unique union of all per-supplier held_po_ids.
release_supplier_ids = sorted list of supplier_ids with decision == "monitor_only".
- Build
summary with exact keys from template.
7. Common Pitfalls
- Do not use localhost/127.0.0.1 unless
environment_access.md explicitly points there. Always use the declared remote base URL.
- Do not read env files or task evaluation internals.
- Effective inventory is
on_hand - reserved - quarantined. Never use raw on_hand for availability decisions.
- Shipping weight = sum of
quantity * product.weight_lb across all lines in the order. Pass the total to /shipping/quote.
- Shipping speed must be exactly
ground, two_day, or overnight (matching the order's shipping_speed field).
- Date filters on incidents are inclusive of both
start_date and end_date.
- PO status filtering: only
open and confirmed count as "eligible" or "timely" for coverage. cancelled and received do not.
- Safety stock is a product-level field. Do not treat it as unavailable unless the task memo explicitly says so; it is a threshold for
low_stock classification, not a reserve quantity.
- Overstock threshold is used in kit replenishment to decide
overstock_excluded.
- Nulls:
transfer_from and similar fields can be null; include them literally, not as empty strings.
- JSON output: Return exactly one JSON object. Do not wrap in markdown code fences in the final answer if the judge expects raw JSON.
- Currency precision: Always round to exactly 2 decimals. Use
round(value, 2); do not truncate.
- Percentage precision: Round to exactly 1 decimal place.
- Controlled vocabularies: Use the exact strings listed in §3. Any deviation causes validation failure.
- Sort stability: When ties exist, fall back to
supplier_id or order_id ascending to ensure deterministic output.
- Capped lists:
sample_incident_ids is capped at 5. Take the first 5 after sorting ascending.
- Account vs. line blocking: In allocation tasks,
blocked_orders is for account-level blocks only (account_status == "blocked"). Do not include orders here just because individual lines have product issues.
1---2name: self-attempt-02-363description: Northwind Components ERP Task Group Skill4---5# Northwind Components ERP Task Group Skill67## 1. Environment & API Access89- **Read `environment_access.md` first.** It overrides any localhost/127.0.0.1 references in task prompts. Use only the remote base URL declared there (e.g. `http://34.46.77.124:8007`).10- **Do not** read, list, or inspect `env/` source directories. Do not run `setup.sh` or `server.py`.11- **Base URL:** Use the URL from `environment_access.md`. All endpoints are read-only GET.12- **Do not invent endpoints.** The canonical list is:13 - `GET /`, `GET /health`14 - `GET /products`, `GET /products/<sku>`15 - `GET /customers`, `GET /customers/<customer_id>`16 - `GET /warehouses`17 - `GET /inventory?warehouse_id=&sku=` (both params optional; returns list)18 - `GET /purchase_orders?supplier_id=&sku=&status=` (returns list)19 - `GET /orders?wave=&required_date=&customer_id=` (returns list), `GET /orders/<order_id>`20 - `GET /shipping/quote?warehouse_id=&destination_zip=&weight_lb=&speed=`21 - `GET /incidents?start=&end=&supplier_id=&sku=&incident_type=&status=` (returns list)22 - `GET /suppliers`23 - `GET /boms`, `GET /boms/<bom_id>`2425## 2. Core Data Models2627### Order28```json29{30 "order_id": "SO-XXXXX",31 "customer_id": "CUST-XXXX",32 "destination_zip": "XXXXX",33 "lines": [{"line_id": 1, "quantity": 10, "sku": "NW-XXXX", "unit_price": 123.45}],34 "priority": "normal|high|critical|low",35 "required_date": "YYYY-MM-DD",36 "shipping_speed": "ground|two_day|overnight",37 "warehouse_id": "WH_NORTH|WH_CENTRAL|WH_WEST",38 "wave": "STRING"39}40```4142### Product43```json44{45 "sku": "NW-XXXX",46 "name": "...",47 "category": "...",48 "active": true|false,49 "supplier_id": "SUP-XXX",50 "unit_cost": 123.45,51 "weight_lb": 12.34,52 "safety_stock": 10,53 "overstock_threshold": 10054}55```5657### Customer58```json59{60 "customer_id": "CUST-XXXX",61 "name": "...",62 "account_status": "active|blocked|review_required",63 "risk_flag": "none|fraud_watch|credit_watch",64 "tier": "strategic|standard|economy",65 "margin_band": "high|medium|low"66}67```6869### Inventory Record70```json71{72 "sku": "NW-XXXX",73 "warehouse_id": "WH_...",74 "on_hand": 100,75 "reserved": 20,76 "quarantined": 5,77 "last_count_date": "YYYY-MM-DD"78}79```80- **Effective available** = `on_hand - reserved - quarantined`. This is the only quantity usable for wave release, transfer sourcing, or stock checks.8182### Supplier83```json84{85 "supplier_id": "SUP-XXX",86 "name": "...",87 "quality_status": "approved|watch|quality_hold",88 "region": "..."89}90```9192### Incident93```json94{95 "incident_id": "INC-XXXXX",96 "supplier_id": "SUP-XXX",97 "sku": "NW-XXXX",98 "warehouse_id": "WH_...",99 "incident_type": "RMA|WORK_ORDER",100 "severity": "low|medium|high|critical",101 "status": "open|closed",102 "open_date": "YYYY-MM-DD",103 "close_date": "YYYY-MM-DD|null",104 "resolution_cost": 1234.56,105 "root_cause": "..."106}107```108109### Purchase Order110```json111{112 "po_id": "PO-XXXXX",113 "supplier_id": "SUP-XXX",114 "sku": "NW-XXXX",115 "warehouse_id": "WH_...",116 "quantity": 100,117 "status": "open|confirmed|cancelled|received",118 "eta": "YYYY-MM-DD"119}120```121- For coverage calculations, only `open` and `confirmed` POs count as "timely."122123### BOM124```json125{126 "bom_id": "BOM-XXX",127 "name": "...",128 "warehouse_id": "WH_...",129 "target_date": "YYYY-MM-DD",130 "components": [{"sku": "NW-XXXX", "quantity_per_kit": 4}]131}132```133134### Shipping Quote135```json136{137 "zone_distance": 3,138 "service_days": 1,139 "total_cost": 225.67,140 "base_rate": 77.95,141 "fuel_surcharge_rate": 0.0925,142 "carrier": "Northwind Parcel"143}144```145- `speed` must be exactly `ground`, `two_day`, or `overnight`.146- `weight_lb` is the total order weight (sum of `line.quantity * product.weight_lb`).147148## 3. Controlled Vocabularies (Exact Strings)149150### Inventory Status151- `ready`, `low_stock`, `shortage`, `inactive_sku`, `inactive_and_shortage`152153### Customer Exception154- `none`, `review_required`, `account_blocked`, `fraud_watch`, `credit_watch`155- **Mapping rule:**156 - `account_status == "blocked"` → `account_blocked`157 - `risk_flag == "fraud_watch"` → `fraud_watch`158 - `risk_flag == "credit_watch"` → `credit_watch`159 - `account_status == "review_required"` → `review_required`160 - otherwise → `none`161162### Final Decision (Expedite)163- `ship_now`, `delayed_release`, `manual_review`, `backorder`, `reject_hold`164165### Next Action (Expedite)166- `release_to_pick`, `delay_and_monitor`, `send_account_review`, `create_backorder`, `hold_credit_or_fraud`, `escalate_product_master`167168### Line Action (Allocation)169- `ship`, `transfer`, `backorder`, `manual_review`170171### Primary Reason (Allocation)172- `none`, `account_blocked`, `account_review_required`, `fraud_watch`, `inactive_product`, `insufficient_effective_stock`173174### Final Action (Kit Replenishment)175- `no_action_stocked`, `transfer_only`, `purchase_required`, `timely_po_covered`, `overstock_excluded`176177### Exclusion Reason (Kit Replenishment)178- `none`, `target_overstock`, `timely_po_covers_gap`, `stocked_no_gap`179180### Recommendation Code (Supplier Scorecard)181- `ESCALATE_SUPPLIER`, `PROCESS_REVIEW`, `WATCHLIST`, `MONITOR`182183### Supplier Decision (Quality Hold Review)184- `freeze_new_replenishment`, `buyer_review_required`, `monitor_only`185186## 4. Sorting Rules (Mandatory)187188- **Records by order:** ascending by `order_id`.189- **Lines within order:** ascending by `line_id`.190- **SKU lists:** ascending alphabetical.191- **Supplier lists / scorecard rows:** ascending by `supplier_id`.192- **Transfer requests:** ascending by `sku`, then descending by `quantity`, then ascending by `from_warehouse_id`.193- **Component plan / excluded components:** ascending by `sku`.194- **Kit targets:** ascending by `bom_id`.195- **PO ID lists:** ascending.196- **Incident ID lists:** ascending.197- **Order ID lists (summary blocks):** ascending.198199## 5. Rounding Rules200201- **Currency (USD):** always round to exactly 2 decimal places in output.202- **Percentages:** round to 1 decimal place.203- **Durations (days):** round to 2 decimal places.204- **Integers:** do not round; use exact integer arithmetic.205206## 6. Workflow Patterns by Task Type207208### 6.1 Expedite Queue Decision (train_001 style)2091. Read the queue memo to get the `wave_id` and the list of `order_ids` to evaluate.2102. Fetch the wave's orders via `/orders?wave=...` or individual `/orders/<id>` calls.2113. For each order:212 - Fetch customer via `/customers/<customer_id>`.213 - For each line SKU, fetch product via `/products/<sku>` and inventory via `/inventory?warehouse_id=...&sku=...`.214 - Determine `inventory_status`:215 - If any SKU `active == false` → includes `inactive_sku`.216 - If effective available < requested quantity → includes `shortage`.217 - If effective available >= quantity but < safety_stock → `low_stock`.218 - Otherwise `ready`.219 - Combine `inactive_sku` + `shortage` → `inactive_and_shortage`.220 - Determine `customer_exception` using the mapping in §3.221 - Determine `final_decision` and `next_action` based on exception + inventory:222 - `account_blocked` → `reject_hold` / `send_account_review` (or `hold_credit_or_fraud` if credit_watch)223 - `fraud_watch` / `credit_watch` → `reject_hold` / `hold_credit_or_fraud`224 - `review_required` → `manual_review` / `send_account_review`225 - `inactive_sku` → `backorder` or `manual_review` / `escalate_product_master`226 - `shortage` → `backorder` / `create_backorder`227 - `low_stock` → `delayed_release` / `delay_and_monitor`228 - All clear → `ship_now` / `release_to_pick`229 - Populate `shortage_skus`, `inactive_skus`, `low_stock_skus` (sorted ascending).230 - Call `/shipping/quote?warehouse_id=...&destination_zip=...&weight_lb=...&speed=...` for the shipping object.2314. Build `summary`:232 - `order_count`233 - `decision_counts` with exact keys: `ship_now`, `delayed_release`, `manual_review`, `backorder`, `reject_hold`234 - `total_shipping_cost_usd` (sum of all record shipping quotes, 2 decimals)235 - `blocked_order_ids`, `manual_review_order_ids`, `backorder_order_ids`, `inactive_sku_order_ids` (sorted ascending)236237### 6.2 Kit Replenishment / Production Planning (train_002 style)2381. Read the production memo to get `planning_site` (e.g. `WH_WEST`) and target builds (`bom_id`, `build_quantity`, `build_date`).2392. Fetch each BOM via `/boms/<bom_id>`.2403. For each component SKU:241 - `total_required` = Σ(`build_quantity` × `quantity_per_kit`) across all target BOMs.242 - Fetch inventory at `planning_site` and all other warehouses.243 - `target_effective_available` = `on_hand - reserved - quarantined` at `planning_site`.244 - Fetch POs via `/purchase_orders?sku=...&status=open` and `status=confirmed`. Sum `timely_po_qty` for POs at the planning site.245 - Determine `overstock_excluded` if effective stock + incoming POs would push total above `overstock_threshold`.246 - Compute gap = `total_required - target_effective_available - timely_po_qty`.247 - If gap > 0 and another warehouse has effective available without dropping below its own safety stock, create a `transfer_request` with `transfer_qty = min(gap, other_effective_available)`.248 - If gap still > 0 after transfers, create a `purchase_requisition` with:249 - `quantity` = remaining gap250 - `unit_cost` from `/products/<sku>` `unit_cost`251 - `extended_cost` = `quantity * unit_cost` (rounded to 2 decimals)252 - `needed_by` = earliest `build_date`253 - `supplier_id` from product254 - `warehouse_id` = planning site255 - Set `final_action` and `exclusion_reason` per the controlled vocab.256 - `coverage_po_ids` = sorted list of PO IDs that cover the timely portion.2574. Sort `component_plan` by `sku` ascending.2585. Sort `transfer_requests` by `sku` asc, `quantity` desc, `from_warehouse_id` asc.2596. Sort `purchase_requisitions` by `sku` ascending.2607. Build `summary` with exact keys from template.261262### 6.3 Supplier Incident Scorecard (train_003 style)2631. Read the scorecard request JSON for `incident_date_filter`, `analysis_date`, `recommendation_policy`, etc.2642. Fetch incidents via `/incidents?start=...&end=...` using the filter window.2653. Fetch all suppliers via `/suppliers`.2664. For each supplier with at least one filtered incident:267 - `incident_count` = count of filtered incidents for that supplier.268 - `incident_percentage` = (`incident_count` / total filtered incidents) × 100, rounded to 1 decimal.269 - `total_resolution_cost` = sum of `resolution_cost` for filtered incidents, rounded to 2 decimals.270 - `avg_duration_days`:271 - Closed: `close_date - open_date` (calendar days)272 - Open: `analysis_date - open_date` (calendar days)273 - Average across all filtered incidents, rounded to 2 decimals.274 - `rma_count` = count where `incident_type == "RMA"`.275 - `work_order_count` = count where `incident_type == "WORK_ORDER"`.276 - `open_incident_count` = count where `status == "open"`.277 - `severe_incident_count` = count where `severity` in (`high`, `critical`).278 - Apply recommendation policy in **strict precedence order** (`ESCALATE_SUPPLIER` > `PROCESS_REVIEW` > `WATCHLIST` > `MONITOR`). Check each rule exactly as defined in the request JSON.2795. Sort scorecard rows by `supplier_id` ascending.2806. `top_escalation_suppliers` = supplier_ids with `recommendation_code == "ESCALATE_SUPPLIER"`, sorted by `incident_count` desc, then `total_resolution_cost` desc, then `supplier_id` asc.2817. `highest_cost_supplier_id` = supplier with max `total_resolution_cost` (tie-break not specified; use first or supplier_id ascending for stability).2828. `highest_share_supplier_id` = supplier with max `incident_percentage`.283284### 6.4 Mixed-Warehouse Allocation (train_004 style)2851. Fetch all orders for the wave via `/orders?wave=...`.2862. For each order, fetch the customer record.2873. For each line:288 - Fetch product (`/products/<sku>`) and inventory at the requested warehouse (`/inventory?warehouse_id=...&sku=...`).289 - `requested_effective_available` = `on_hand - reserved - quarantined` at requested warehouse.290 - **Account-level block first:** If `account_status == "blocked"`, the entire order is blocked. All lines get `action = "manual_review"`, `primary_reason = "account_blocked"`.291 - If `account_status == "review_required"` → `manual_review` / `account_review_required`.292 - If `risk_flag == "fraud_watch"` → `manual_review` / `fraud_watch`.293 - If `risk_flag == "credit_watch"` → `manual_review` / `credit_watch`.294 - If product `active == false` → `manual_review` / `inactive_product`.295 - If `requested_effective_available >= quantity` → `ship` with `ship_quantity = quantity`.296 - If `requested_effective_available < quantity`:297 - Check other warehouses for effective available (without dipping below their safety stock). If found, `transfer` with `ship_quantity = requested_effective_available`, `transfer_quantity = quantity - ship_quantity`.298 - If no other warehouse can cover, `backorder` with `backorder_quantity = quantity - requested_effective_available`.2994. `transfer_requests` list: one entry per transfer line, sorted by `order_id` asc, `line_id` asc.3005. `blocked_orders`: list of `order_id` strings where `account_status == "blocked"`, sorted ascending.3016. `order_rollup`: for each order, determine `outcome`:302 - `ready_to_ship` if all lines are `ship`303 - `needs_transfer` if any line is `transfer` and none are `manual_review`/`backorder`304 - `has_backorder` if any line is `backorder`305 - `manual_review` if any line is `manual_review`306 - `mixed_actions` if multiple different actions apply3077. `summary` must include all required integer keys from the template.308309### 6.5 Quality Hold Review / Supplier Replenishment Control (train_005 style)3101. Read the memo for `analysis_window` (`start`, `end`) and `target_supplier_ids`.3112. For each target supplier:312 - Fetch supplier via `/suppliers/<supplier_id>`.313 - Fetch incidents via `/incidents?supplier_id=...&start=...&end=...`.314 - Fetch POs via `/purchase_orders?supplier_id=...&status=open` and `status=confirmed`.315 - Compute:316 - `recent_incident_count` = count of incidents in window.317 - `recent_rma_count` = count of RMA incidents in window.318 - `severe_or_critical_count` = count with severity `high` or `critical`.319 - `open_incident_count` = count with `status == "open"`.320 - `affected_skus` = sorted unique list of SKUs from incidents.321 - `sample_incident_ids` = sorted list of incident IDs, capped at 5.322 - `held_po_ids` = sorted list of open/confirmed PO IDs for this supplier.323 - Determine `decision` based on policy:324 - `freeze_new_replenishment` if `quality_status == "quality_hold"` AND significant incident/PO risk.325 - `buyer_review_required` if `quality_status == "watch"` or moderate incident load.326 - `monitor_only` if low risk.327 - The exact thresholds come from the task memo; use the memo's policy text.3283. `held_po_ids` (top-level) = sorted unique union of all per-supplier `held_po_ids`.3294. `release_supplier_ids` = sorted list of supplier_ids with `decision == "monitor_only"`.3305. Build `summary` with exact keys from template.331332## 7. Common Pitfalls333334- **Do not use localhost/127.0.0.1** unless `environment_access.md` explicitly points there. Always use the declared remote base URL.335- **Do not read env files** or task evaluation internals.336- **Effective inventory** is `on_hand - reserved - quarantined`. Never use raw `on_hand` for availability decisions.337- **Shipping weight** = sum of `quantity * product.weight_lb` across all lines in the order. Pass the total to `/shipping/quote`.338- **Shipping speed** must be exactly `ground`, `two_day`, or `overnight` (matching the order's `shipping_speed` field).339- **Date filters on incidents** are inclusive of both `start_date` and `end_date`.340- **PO status filtering:** only `open` and `confirmed` count as "eligible" or "timely" for coverage. `cancelled` and `received` do not.341- **Safety stock** is a product-level field. Do not treat it as unavailable unless the task memo explicitly says so; it is a threshold for `low_stock` classification, not a reserve quantity.342- **Overstock threshold** is used in kit replenishment to decide `overstock_excluded`.343- **Nulls:** `transfer_from` and similar fields can be `null`; include them literally, not as empty strings.344- **JSON output:** Return exactly one JSON object. Do not wrap in markdown code fences in the final answer if the judge expects raw JSON.345- **Currency precision:** Always round to exactly 2 decimals. Use `round(value, 2)`; do not truncate.346- **Percentage precision:** Round to exactly 1 decimal place.347- **Controlled vocabularies:** Use the exact strings listed in §3. Any deviation causes validation failure.348- **Sort stability:** When ties exist, fall back to `supplier_id` or `order_id` ascending to ensure deterministic output.349- **Capped lists:** `sample_incident_ids` is capped at 5. Take the first 5 after sorting ascending.350- **Account vs. line blocking:** In allocation tasks, `blocked_orders` is for **account-level** blocks only (`account_status == "blocked"`). Do not include orders here just because individual lines have product issues.