Item record review + push-back
Item record review is the items-side counterpart to assembly_build_review. It's the workhorse Mike uses on the data-cleanup loop — open an item, see its full live state, propose specific field updates, and push the cascade.
The cascade is deliberately wide because items touch a lot: NS fields, spec sheets, pricing_master rows, vendor_costs, assembly memberships, open bid lines, recent transactions. Changes ripple to all of them; the workflow makes the ripple deterministic.
Risk level 3 (medium). Contract at workflow_definitions WHERE workflow_type='item_record_review'.
Trigger conditions
- Mike opens
/item/<code>and notices a stale or wrong field. - Data-quality watchdog fires
data_quality.item_flaggedafter detecting drift. - Vendor response contains a corrected spec (pack size, allergens, etc).
- Customer complaint cites a label discrepancy that traces to an item field.
- Spec audit finds a kosher cert that's missing or expired.
The not_in_active_bid precondition warns (not blocks) — items in open bid lines can still be updated, but the workflow drafts a notification to the bid owner so the customer hears about the change first. That's the standing rule: never let a customer find a spec change in the bid PDF before we tell them.
The 7 beats
-
01
Stage NS field update
A
proposed_actionsrow stages withaction_type=item_field_update, entity_ref=item_code, fields frominputs.proposed_changes. Allowed fields are whitelisted (displayname, salesdescription, custitem_brand, etc) — anything else is rejected at precondition. -
02
Invalidate item cache
Keys
item:{item_code},item_full:{item_code},ns:item:{item_code}are deleted so the live /item/<code> render is fresh. -
03
Invalidate pricing cache (pattern)
Pattern delete on
pricing:{item_code}:*via KV list scan. Busts every customer-pricing cache keyed off this item. -
04
Regenerate spec sheet (conditional)
If proposed_changes touched spec-relevant fields (claims, pack_size, allergens), the spec sheet PDF regenerates via the
regenerate_spec_sheetchat tool. -
05
Recompute assembly cost rollups
For each assembly that has this item in its BOM,
assembly_cost_rolluprecomputes. Keeps margin math current across the assembly catalog. -
06
Flag dependent pricing for review
If item-level changes could affect customer pricing (pack_size ripples to case_price), pricing_master rows touching this item flag for the next pricing review cycle.
-
07
Notify sales if active bid (conditional)
If
open_bid_linesis non-empty, a notification email per bid owner drafts inoutbound_email_logwith status=pending_review.
What's different after the workflow runs
- NS item record reflects the new field values within the NS push drain window.
- Item caches (3 keys) and pricing pattern caches are busted.
- Spec sheet PDF is regenerated if user-facing fields changed.
- Assembly cost rollups are current.
- Bid owners have a notification email waiting if the item is in their open bid.
- reflexion_log carries an
item_review,data_cleanuptagged row.
What can go wrong and how to recover
Precondition item_exists blocks. Mike checks the item_code (case-insensitive lookup) and either fixes the code or runs new_assembly_item if it's genuinely new.
Precondition item_active warns. Mike can still proceed — sometimes reactivating an item is part of the cleanup.
Precondition rejects with severity=block. Adding a new allowed field requires updating the contract's precondition list (and ideally an ADR).
Retry policy is 2 attempts with [300s, 1800s] backoff. Drainer cron picks up persistent failures within 30 minutes.
Adjacent workflows + diagrams
Code paths + invariants
| Concern | Where |
|---|---|
| Workflow contract | workflow_definitions WHERE workflow_type='item_record_review' |
| Allowed field list | precondition: displayname, salesdescription, custitem_brand, custitem_pack_size, custitem_case_count, custitem_buyamerican, custitem_kosher, custitem_allergens, custitem_country_of_origin, custitem_storage_temp, reorderpoint, taxschedule |
| Data-quality trigger | data_quality.item_flagged event |
| Spec regen tool | regenerate_spec_sheet |
| Reflexion tag | item_review,data_cleanup |
| Risk level | 3 |
| Expected duration | ~variable (data-driven) |
| Trigger | manual_or_event · event_type_glob=data_quality.item_flagged |
Dated trail · spot stale claims
Dated trail of when this doc was last touched, what changed, and what to look at if it feels stale.
| Date | Round | Change | Touched by |
|---|---|---|---|
2026-05-26 | R586 | Added CHANGELOG · SCHEMA · RUNBOOK · BACKLOG sections — wiki became best-in-class operating documentation. | Mike + Claude |
2026-05-25 | R584/R585 | Wiki originally shipped — 8-section structure (hero / what / when / steps / outcomes / failure-modes / related / for-developers). | Mike + Claude |
workflow_definitions WHERE workflow_type='item_record_review' before acting on these claims.The machine-readable spec
Canonical fields, table names, endpoint signatures. What code should match, what tests should assert. workflow_type · item_record_review · risk_level · 3.
Inputs (required + optional)
| Field | Type | Description |
|---|---|---|
item_id | integer | NS item ID. Required. |
review_reason | string | Why this item is being reviewed. |
review_scope | string | 'pricing' | 'spec' | 'metadata' | 'all' |
D1 tables written
| Table | Operation | Trigger |
|---|---|---|
proposed_actions | INSERT | Each finding becomes a proposal |
item_review_runs | INSERT | Run record |
items | UPDATE (post-HITL) | Apply approved fixes |
events | INSERT (item.reviewed) | audit |
Endpoints called
| Method | Path | Purpose |
|---|---|---|
POST | /api/workflow/execute | Runner entrypoint |
GET | /api/item/:id/review-history | Past reviews |
Events fired
| event_type | When | Subscribers |
|---|---|---|
item.reviewed | Post-run | audit |
item.metadata_changed | If metadata fields updated | kb_rebuild trigger candidate |
It broke at 2am — what now
Different from "how do I use this." This is the page Mike pulls up when something is wrong: logs to check, recovery steps, who to escalate to.
Scenario · Review flagged a spec mismatch but spec_items wasn't updated
spec_items writes are gated on Mike's approval; the flag stays open until then.
- Check:
SELECT * FROM proposed_actions WHERE entity_ref='item:<id>' AND action_type='spec_update' - Approve in queue: Mike taps approve in /proposed-actions.html
Scenario · Item review shows no findings but Mike knows fields are wrong
Review scope may have excluded the field.
- Re-run with scope=all:
POST /api/workflow/executeworkflow_type=item_record_review scope=all - Manual fix: Use propose_item_update chat tool.
Scenario · Item review committed wrong value (typo in NS)
Item review wrote bad data back to NS.
- Revert: Find prior value in items_history; manually set in NS.
- Investigate: Why did Mike approve? Review the proposed_action diff before approving.
Logs to check
workflow_run_log· top-level run auditworkflow_step_log· per-step traceworkflow_verify_results· post-window verify outcomescron_locks· stuck cron lock detectionevents· workflow.completed / workflow.failed event trailreflexion_log· per-run narrative (if reflexion_enabled)npx wrangler tail· live Worker logs
Kill switch · emergency stop
If this workflow is misbehaving in a high-impact way (creating bad proposed_actions in volume, pushing wrong things to NS), flip a kill switch:
kill:ns_writes· stops every NS push platform-widekill:proposed_apply· stops HITL approvals from executing fan-outkill:high_risk_ops· stops risk_level >= 4 fan-out
See kill-switches-state-machine.html for the full state machine + recovery procedure.
Escalation
Primary: Mike Levine (single-admin) · mikelevine@globalfoodsolutions.co. For prolonged outage during business hours, notify warehouse lead + accounting lead so they can defer dependent work.
What's not done · what's uncertain
What's not done, what's uncertain, what we punted. Captured so it survives context switches and doesn't die in someone's head.
-
STUB
Auto-review on stale items
Today review is on-demand. Could cron-review items not touched in 90 days.
-
OPEN
Review covers what fields exactly?
Scope='all' is vague. Need a documented field-by-field checklist.
-
DEFER
Bulk item review (re-baseline 1000+ items)
Today one at a time. Bulk needs a queue + cumulative cap.