The factory floor in nine beats
The NS work order lifecycle is what happens every time GFS produces an assembly — a Right Start Foods burrito kit, a Melt Mates meal kit, a USDA brown-box pancake run. It starts with a work order opening (either manually or because quantityavailable tripped a reorder point) and ends with finished goods showing up as allocatable inventory.
It exists because manufacturing is the one place where NS is genuinely the system of record — we don't second-guess the build transaction, we mirror it. But the cost rollup, the variance audit, and the BOM-update HITL gate live on our side. So nine phases: NS does six of them, we do three (component reservation mirror, variance audit, FG availability mirror).
The diagram lives at ns-work-order-lifecycle.html. Two phases are still STUB — labor capture autoflow and NS-native component reservation. Those gaps are honest; the recovery path is in Failure modes below.
Trigger conditions
- An assembly's
quantityavailabledrops below its reorder point — auto-WO opens. - A sales order requires assembled stock that isn't on the shelf — production lead opens WO manually.
- USDA entitlement drawdown commits a build run — e.g. barrel cheddar processing.
- Operations forecasts a bid award and pre-builds inventory ahead of the QBL.
- R&D wants to validate a new BOM by running it once at small qty — pilot run.
Any WO with |actual cost − estimated cost| > 5% at close lands a row in proposed_actions for Mike. Below that, NS posts the build silently and the BOM stays untouched.
WO #4821 — build 500 Right Start breakfast burritos
Tuesday morning. Inventory shows RS-BURR-10472 at 38 cases — below the 50-case reorder point. NS auto-opens WO-4821 for 500 units. The BOM resolves to 8 components (tortilla, egg patty, cheese, sausage crumble, salsa pack, wrap film, case box, label). Components pull cleanly; the WO releases to the floor at 09:14.
By 14:30, production posts the build. NS rolls actual cost: components $1,842, labor $312 (entered by floor lead Susan via NS UI — STUB autoflow, no scanner kiosk yet), overhead $98. Total $2,252 vs estimated $2,180 — variance of +3.3%, under threshold. NS quietly closes the WO. Inventory shows 538 cases. The cost surface tile on the admin dashboard ticks by half a cent. No HITL was needed.
Contrast: WO-4822 the same week ran +7.1% over — a tortilla vendor cost moved and the BOM was stale. Variance audit fired, proposed_actions queued, Mike approved the BOM update on his phone at lunch. Cost surface re-anchored within 12 minutes.
The nine phases
-
01
WO intake — manual or auto
Either a production lead opens the work order in NS, or the reorder-point watcher fires when
inventory_balance.quantityavailabledrops below the assembly'sreorder_point. The auto path emits aworkorder.createdevent for downstream listeners. -
02
Component pull — BOM resolution + reservation
The runner reads
assembly_bomfor the assembly, walks each line, and checksinventory_balanceat the production location. Required qty is logged. STUB: NS-native component reservation is not wired — we read availability but don't lock the rows, so a parallel SO could theoretically grab the components first. In practice this rarely bites because production starts within minutes. -
03
Production start — status flips to 'In Progress'
The floor lead releases the WO. NS transitions
workorder.status='In Progress'and stampsstart_timestamp. The D1transactionsrow mirrors on the next 2-min hot sync. -
04
Labor capture — hours × rate against the WO
Time entries are booked against the work order. Hours roll up into
actual_labor_costat close. STUB: there is no scanner/kiosk autoflow — floor leads (Susan, Marcus) enter time manually through the NS UI on a laptop in the office. This is the single largest data-quality risk in the lifecycle; it works because we have one shift and two leads, but it won't scale. -
05
Component issue — debit inventory
NS posts a
workorderissuetransaction.inventory_balancedecrements per BOM line for the build qty. D1 mirrors with negative-qty rows intransaction_lineson the next hot sync. -
06
Build complete — credit finished goods
Production posts the build. NS records a
buildtransaction;inventory_balanceincrements at the production location for the assembly item. The credit and the matching debits from step 5 are linked by the NS build transaction id. -
07
WO close — status='Built', actual cost rollup
NS flips
workorder.status='Built'and rolls the actual cost: components from step 5, labor from step 4, allocated overhead. The rollup writes to the workorder header. -
08
Variance audit — HITL if >5% drift
The platform compares
actual_costvsestimated_costfrom the BOM. Ifabs(diff) / estimated > 0.05, a row is inserted intoproposed_actionswithaction_type='bom_variance_review', risk_level 3. Mike sees the diff at/proposed-actions.htmland decides: update the BOM (most common) or flag a production exception (e.g. a one-off scrap). -
09
Finished goods — allocatable inventory
inventory_balance.quantityavailablereflects the new build. Sales orders can now allocate against the SKU. The cost surface tile on the admin dashboard re-anchors with the new actual-cost data point. If Mike approved a BOM update in step 8, the new estimated cost is in effect for the next WO.
What's different after the WO closes
- NS and D1 agree on FG quantity, component balances, and actual cost.
- If variance > 5%, a HITL card is in Mike's queue.
- If Mike updated the BOM, downstream cost rollups use the new value immediately.
- The build transaction is permanent — reversals require an
assemblyunbuild.
What can go wrong
Floor leads forget to enter time, or enter wrong hours. Rollup uses estimated labor when actual is missing. Detection: variance audit flags WOs with labor_hours=0 AND build_qty>0. Manual recovery: backfill via NS UI; re-run cost rollup.
A parallel SO could allocate a component before the WO consumes it. Detection: workorderissue failure with "insufficient inventory". Recovery: short-pick the SO or short-pack the WO; reorder ASAP.
Variance ≤ 5% repeated over many WOs can mask sustained cost creep. Detection: cost surface tile shows monotonic drift over 30 days. Recovery: manually trigger bom_variance_review at quarterly cost review.
If NS posts an assemblyunbuild after the variance audit fired, the HITL card may reference a vanished build. The decide endpoint catches this and returns "stale_action".
Adjacent flows + diagrams
Code paths + invariants
| Concern | Where |
|---|---|
| WO mirror table | transactions WHERE recordtype='workorder' |
| BOM source | assembly_bom (D1 mirror of NS BOM) |
| Variance threshold | guardrails.workorder_variance_threshold (default 0.05) |
| HITL stage | proposed_actions.action_type='bom_variance_review' |
| Cost rollup | assembly_cost_rollup (Pillar 4) |
| Sync tier | hot (2 min) for transactions; warm (5 min) for inventory_balance |
| NS push (BOM update) | NS_PUSH_QUEUE, record_type='inventoryitem' |
| STUB — labor capture | no scanner; NS UI manual entry only |
| STUB — component reservation | read-only availability check; no NS row lock |