Assembly build + BOM review · risk 3 (Part 2 of 2)

Manually invoked from /assembly/<code> review page OR fired by weekly assembly rollup cron when cost_drift_pct exceeds threshold (R533).

01 / Trigger 02 / Context + preconditions 03 / HITL gate (Mike approves) 04 / Fan-out (Part 2 of 2) 05 / Post actions (log_run + reflexion + events) 06 / Verify (SQL / R2 / HTTP checks) How this workflow gets kicked off. Could be a chat-tool invocation, a cron tick, an inbound event (e.g. price.changed), or Mike clicking 'execute' from an admin page. TRIGGER kind: ? glob: assembly.cost_drift_detected invoker: Mike (single-admin) risk_level: 3i Trigger manual_or_event risk 3 Before deciding anything, pull related data from D1 (the local mirror of NetSuite). Each query loads a slice of the entity's current state so the AI and Mike can review before any writes happen. LOAD CONTEXT (D1 queries before fan-out) current_assembly: SELECT id, item_code, description, custitem_brand, custitem_pack_size, custitem… current_bom: SELECT bom_line_id, line_key, line_description, quantity, unit, source_vendor, … current_cost_rollup: SELECT raw_cost, packaging_cost, labor_cost, overhead_cost, freight_cost, fob_d… customer_programs_using: SELECT ap.program_id, cp.customer_name, cp.program_name, cp.contract_price, cp.… active_pricing_rows: SELECT customer_name, case_price, cost_basis, school_year FROM pricing_master W… spec_sheet: SELECT spec_id, spec_status, spec_version, claims_json, last_updated FROM spec_… recent_builds: SELECT COUNT(*) AS build_count_90d FROM transactions WHERE type='Build' AND ent…i Load context 7 D1 queries Safety checks that must pass before any writes. 'block' severity halts the run; 'warn' surfaces a warning but continues. Without these, a bad input could cascade into NetSuite. PRECONDITIONS (checked before fan-out) [block] assembly_exists: current_assembly.id present [block] either_line_or_header_changes: line_changes present OR header_changes present [block] rationale_present: rationale present [warn] no_active_customer_program_locked: customer_programs_using is null [warn] cost_rollup_fresh: current_cost_rollup.last_computed >= date('now','-7 days')i Preconditions 5 checks The HITL (Human-In-The-Loop) gate. The workflow stages a proposed_action and waits for Mike to approve in /proposed-actions.html. Only fires when risk_level >= 3. This is the invariant: no NS write happens without Mike's go-ahead. HITL GATE (Mike approves before fan-out) action_type: workflow_assembly_build_review entity_ref: workflow:assembly_build_review:run_<run_id> approver: mike (single-admin) risk_gate: >= 3 (this workflow = 3) approval window: typical <= 60 min envelope: proposed_actions row staged by runneri Mike approves stage_proposed_action risk ≥ 3 gate Set a follow-up flag on a row (e.g., 'needs_review') so a downstream cron or human picks it up later. STUB today. FAN-OUT: flag kind: flag (not in contract — diagram-only annotation)i flag flag STUB Draft an email and stage it as a proposed_action for Mike's review. The email is NOT sent - only drafted + queued. STUB today. FAN-OUT: hitl_email_draft kind: hitl_email_draft (not in contract — diagram-only annotation)i hitl_email_draft hitl_email_draft STUB Spawn a Cloudflare Workflow durable-execution class (e.g., AnnualRollWorkflow) for long-running multi-step work. STUB today. FAN-OUT: workflow_class_invoke kind: workflow_class_invoke (not in contract — diagram-only annotation)i workflow_class_invoke workflow_class_invoke STUB Always-runs at the end of every workflow execution: writes a row to workflow_run_log with status, duration, step counts, and errors. Real implementation. POST ACTION: log_run -> D1: workflow_run_log fields: run_id, workflow_type, status, started_at, completed_at, summary_json source: runner automatic (always)i log_run workflow_run_log REAL Writes an entry to reflexion_log so the AI 'remembers' what happened. Only fires if the contract has reflexion_enabled=1. Future workflows can search this log for prior context. Real implementation. POST ACTION: reflexion -> D1: reflexion_log tags: assembly_build_review reflexion_enabled: True fields: run_id, narrative, tags source: runner automatic (when reflexion_enabled=1)i reflexion reflexion_log REAL Fires a workflow.completed / workflow.partial / workflow.failed event into the event ledger so downstream subscriptions can react. Uses an idempotency_key so producer retries collapse. Real implementation (R564). POST ACTION: event -> Event ledger (recordEvent) types: workflow.completed | workflow.partial | workflow.failed idempotency_key per run_id source: runner automatici event workflow.completed REAL A post-execution sanity check. The runner stages this with status='pending'; the verify-scheduler cron (every :08 and :38 hourly) wakes up after the configured window (e.g. +24h) and executes the sql_check, then flips status to pass/fail/timeout. Real implementation (R564). VERIFY: assembly_header_actua… scheduler: verify cron @ :08/:38 (R563)i assembly_header_actua… ≤60m A post-execution sanity check. The runner stages this with status='pending'; the verify-scheduler cron (every :08 and :38 hourly) wakes up after the configured window (e.g. +24h) and executes the sql_check, then flips status to pass/fail/timeout. Real implementation (R564). VERIFY: bom_line_count_change… scheduler: verify cron @ :08/:38 (R563)i bom_line_count_change… ≤60m A post-execution sanity check. The runner stages this with status='pending'; the verify-scheduler cron (every :08 and :38 hourly) wakes up after the configured window (e.g. +24h) and executes the sql_check, then flips status to pass/fail/timeout. Real implementation (R564). VERIFY: cost_rollup_recomputed scheduler: verify cron @ :08/:38 (R563) result row: workflow_verify_resultsi cost_rollup_recomputed ≤60m A post-execution sanity check. The runner stages this with status='pending'; the verify-scheduler cron (every :08 and :38 hourly) wakes up after the configured window (e.g. +24h) and executes the sql_check, then flips status to pass/fail/timeout. Real implementation (R564). VERIFY: no_orphaned_pricing scheduler: verify cron @ :08/:38 (R563) result row: workflow_verify_resultsi no_orphaned_pricing ≤60m Legend User UI Agent logic Policy Tool action Context / trace

Contract

  • • Type: assembly_build_review
  • • Risk: 3
  • • Trigger: manual_or_event
  • • Fan-out: 3 targets (Part 2 of 2)

HITL semantics

  • • risk ≥ 3 ⇒ stage_proposed_action
  • • Mike approves before fan-out
  • • REAL = solid green · STUB = dashed

Post actions

  • • log_run → workflow_run_log
  • • reflexion → reflexion_log
  • • event → workflow.completed
  • • verify × 4