1---2name: reflect-3-attempt-03-463description: ProcureOps Task Solver SOP4---5# ProcureOps Task Solver SOP67## Environment89- Base URL: from `environment_access.md` (GDPEVO_ENV_BASE_URL); overrides any `localhost` or `127.0.0.1` in task text.10- All data comes from the remote ProcureOps API. Do not start a local env.11- Endpoints: `/programs`, `/suppliers`, `/items`, `/contracts`, `/purchase_requisitions`, `/purchase_orders`, `/receipts`, `/ap/invoices`, `/ap/payments`, `/approval_events`, `/budget_snapshots`, `/vendor_risk_events`.12- Every endpoint returns `{"count": N, "results": [...]}`. Always work from `results`.1314## Source Precedence15161. **Task-local payloads** (memos, packets, chargeback registers) — provide business context, target IDs, and local-only data like chargeback registers. Treat as authoritative for business rules and target scope.172. **API records** — source of truth for operational state (PO status, receipt quantities, invoice holds, supplier ratings, budget caps, approval events).183. **Answer template JSON** — defines required keys, allowed values, ordering, and precision. Match it exactly.1920## Field Conventions2122### Dates and As-Of Filtering23- All dates are `YYYY-MM-DD` strings.24- "As of `as_of_date`" means records with date **on or before** the as_of date. Records after are excluded.25- Invoice/receipt dates, risk event dates, and approval event dates all respect the as_of cutoff.26- PO `due_date` < as_of_date → the PO is **late**.2728### Sorting29- List fields marked "sorted ascending" must be sorted lexicographically (string sort).30- List fields marked "set; evaluator sorts values" can be in any order.31- Nomination lines are matched by `sku`; order within the array does not matter.3233### Currency and Precision34- All amounts in USD. Round to **2 decimal places** (cents) unless the template specifies otherwise.35- Ratios use the precision specified (e.g., `receipt_completion_ratio` → 4 decimal places).36- Percentages use the precision specified (e.g., `quantity_variance_pct` → 1 decimal place).37- Use standard rounding (half-up).3839### Null vs Missing40- `null` in JSON means the value is explicitly absent (e.g., no contract → `commercial_basis_id: null`).41- Empty arrays `[]` mean no records exist (e.g., no receipts, no risk events).42- `0.00` for financial fields when the value is zero.4344## Key Business Rules4546### Budget Headroom47- `budget_headroom = budget_cap - committed_amount` (from `/programs` or `/budget_snapshots`).48- Both endpoints agree; either is authoritative.4950### Contract Ceiling Usage51- Sum subtotals of all POs under the contract **excluding cancelled** POs.52- "Cancelled" means status `"cancelled"`. "Closed", "confirmed", "partial_receipt", "open" all count as non-cancelled.53- `headroom_before_change = ceiling_amount - noncancelled_subtotal`.54- `ceiling_ok = headroom_after_change >= 0`.5556### Approval Gates57- Only action `"approved"` satisfies approval requirements. `"submitted"`, `"returned"`, `"escalated"` do **not** count as approval.58- A requisition status of `"converted"` does not imply approval — check the actual approval events.59- Use the **latest** approval event (by date) for the source requisition.6061### Supplier Risk62- Risk events are **supplier-level**, not PO-level. Any open/monitoring event for the supplier counts.63- Filter vendor risk events: status `"open"` or `"monitoring"` as of the as_of date.64- `supplier_risk_ok = true` when there are **no severe** (severity `"high"`) open events.65- A supplier `risk_rating` of `"watch"` is context; it does not by itself block unless there is also a severe open event.6667### Invoice and Receipt Reconciliation68- `short_qty_vs_po = ordered_qty - received_qty`.69- `unreceived_billed_qty = billed_qty - received_qty`.70- `receipt_completion_ratio = received_qty / ordered_qty`.71- Invoice exception codes are additive: include all that apply.72- `SUPPLIER_WATCH_RISK` should be included in exception codes when the supplier has any open risk event.7374### AP Close Desk75- `opening_balance` is specified by the task memo (often `0.00` for a slice).76- Scheduled payments through the cutoff date reduce the close balance.77- `close_balance = opening_balance + invoice_total - scheduled_payments`.78- `net_balance_impact = invoice_total - scheduled_payment_amount`.79- `quantity_variance_pct = (quantity_variance / PO_quantity) * 100`, rounded to 1 decimal.80- `balance_status`: `"FULLY_SCHEDULED"` when close_balance = 0, `"OPEN_HELD"` when held, `"OPEN_APPROVED"` when approved but not fully scheduled.8182### Chargeback Handling83- Chargeback registers in task payloads are **authoritative sources** (not API data).84- `approved_chargeback_amount = basis_quantity × unit_cost` (from chargeback register).85- `pending_chargeback_amount` same formula for pending chargebacks.86- `net_release_amount = invoice_total - approved_chargeback_amount` for release decisions; `0.00` for holds.87- Approved chargebacks → `release_net_after_approved_chargeback`. Pending quality review → `hold_pending_quality_chargeback`.8889### Change-Control Budget Exposure90- `requested_subtotal = requested_quantity × contract_unit_price`.91- `requested_tax = requested_subtotal × (tax_rate_percent / 100)`, rounded to cents.92- `requested_total = requested_subtotal + requested_tax` (add freight only if the change memo provides it).93- `budget_after_change = remaining_budget - requested_total`.94- `budget_ok = budget_after_change >= 0`.9596## Arithmetic Checks9798- Always recompute totals independently; do not assume API subtotals are consistent.99- Tax verification: `tax / subtotal` should equal the stated tax rate (e.g., 0.0725 for 7.25%).100- `invoice_total = subtotal + freight + tax`.101- Budget headroom should be verified against both `/programs` and `/budget_snapshots`.102- When contract and PO unit prices differ, use the **contract** price for ceiling calculations and the **PO** price for PO-level math.103104## Output Schema Pitfalls105106- **List ordering**: Pay attention to whether lists must be sorted or are sets. Sorted lists use lexicographic string sort.107- **Enum values**: Use exact allowed values from the template. Do not invent or approximate.108- **Null handling**: Use JSON `null` (not `"null"`, not `"none"`, not `""`).109- **Empty arrays vs null**: `[]` for empty lists, `null` for absent single values.110- **Integer vs float**: Quantities are integers; financial amounts are floats with 2 decimal places.111- **Boolean**: Use JSON `true`/`false`, not strings.112- **Date format**: Always `YYYY-MM-DD` strings.113- **Blocker codes**: The list `["none"]` means no blockers. When blockers exist, `"none"` must be absent.114115## Exclusion Rules116117- **Cancelled POs**: Exclude from contract usage calculations. Check `status` field.118- **Cancelled requisitions**: Ignore for nomination/readiness purposes.119- **Closed/expired risk events**: Exclude from `open_event_ids` and risk checks. Only `"open"` and `"monitoring"` statuses count.120- **Future records**: Receipts, invoices, and events dated after the as_of date are excluded.121- **Out-of-scope invoices**: Only include the invoices explicitly named in the task memo/packet.122123## Workflow Pattern1241251. Read the task prompt, memo/packet payloads, and answer template.1262. Identify which API endpoints are needed.1273. Fetch all relevant endpoints in parallel.1284. Filter data by program, supplier, SKU, and as_of date.1295. Compute derived values (headroom, variance, ratios).1306. Build the answer JSON matching the template exactly.1317. Validate: check sorting, precision, allowed enum values, null vs empty.