• contact@verticalserve.com
Home / Engineering / Post 12
Engineering Blog · Post #12

Workflow Status Machine: Validated Transitions, Bot API Contracts, and the extraction_pending → quality_check → in_review Pipeline

How InsightUW enforces a Marine Hull submission through exactly the right workflow states — rejecting invalid transitions, enabling bot automation, and ensuring no submission skips quality check on the way to an underwriter's desk.


The Problem

Submission workflow in most underwriting platforms is a lie. There is a status field on the record — "New," "In Review," "Quoted," "Bound" — but the transitions between those statuses are unenforced. Anyone can change a submission from "New" to "Bound" with a single database update. Bots push submissions into states that the UI does not expect. A quality check gets skipped because someone updated the status directly.

The consequences are serious:

  • Submissions reach underwriters without passing extraction or quality check
  • Bot integrations set invalid statuses, causing downstream errors
  • Reporting is unreliable because status history does not reflect the actual process
  • Compliance audits fail because there is no proof the required steps occurred
  • Two people change the status at the same time, and one change is silently lost

A proper workflow needs a state machine — a formal definition of which transitions are allowed, who can trigger them, and what conditions must be met.

The InsightUW Approach

InsightUW implements a validated state machine for submission workflow. Every status transition is:

  1. Defined in a transition table (from → to → conditions → actor types)
  2. Validated before execution (preconditions checked, actor authorized)
  3. Atomic (transition either fully completes or fully rolls back)
  4. Audited (every transition is logged with actor, timestamp, and reason)
  5. Evented (every transition fires a domain event for downstream consumers)
stateDiagram-v2 [*] --> received: Submission Created received --> extraction pending: Auto (on create) extraction pending --> extracted: Bot: Extraction Complete extraction pending --> extraction failed: Bot: Extraction Error extraction failed --> extraction pending: Bot: Retry Extraction extracted --> quality check: Auto (on extraction) quality check --> qc approved: QC Analyst: Approve quality check --> qc rejected: QC Analyst: Reject qc rejected --> extraction pending: Bot: Re-Extract qc rejected --> quality check: QC Analyst: Re-Submit qc approved --> in review: Auto (on QC pass) in review --> quoted: Underwriter: Issue Quote in review --> declined: Underwriter: Decline in review --> referred: Underwriter: Refer Up referred --> in review: Senior UW: Return referred --> declined: Senior UW: Decline quoted --> bound: Underwriter: Bind quoted --> not taken up: System: NTU Timeout quoted --> in review: Underwriter: Revise bound --> [*] declined --> [*] not taken up --> [*]

The Status Transition Table

The full transition table is stored as configuration, not code. This means new statuses and transitions can be added without a deployment.

Bot API Contract

Bots (extraction engines, RPA tools, external systems) interact with the workflow through a strict API contract. The bot must identify itself, specify the transition, and provide required payloads.

Invalid Transition Rejection

When a bot or user attempts an invalid transition, the state machine rejects it with a detailed error:

Quality Check: The Gate Between Extraction and Underwriting

The quality check status is the critical gate. It ensures that every submission's extracted data has been verified before an underwriter sees it.

graph LR subgraph Extraction["Extraction (Bot)"] A["extraction pending"] B["extracted"] C["extraction failed"] end subgraph QC["Quality Check (Human)"] D["quality check"] E["qc approved"] F["qc rejected"] end subgraph UW["Underwriting (UW)"] G["in review"] end A -->|"Bot: extraction complete"| B A -->|"Bot: extraction error"| C C -->|"Bot: retry (max 3)"| A B -->|"Auto: confidence >= 0.70"| D D -->|"QC: approve"| E D -->|"QC: reject"| F F -->|"Bot: re-extract"| A F -->|"QC: re-submit"| D E -->|"Auto: UW assigned"| G

The QC approve/reject API:

The Scenario

Marsh submits a Marine Hull application for the MV Pacific Voyager, an 82,000 GT bulk carrier trading worldwide. The submission arrives via email with 4 attachments: ACORD marine application, vessel specification sheet, 5-year loss history, and P&I club letter.

What Happens in InsightUW (Timeline)

Time Event Status System Action
9:00:00 AM Email received received Submission SUB-2026-04-2001 created
9:00:01 AM Documents attached received → extraction pending Auto-transition; 4 documents stored in S3
9:00:01 AM Extraction bot notified extraction pending Webhook fires to extraction-bot-v3
9:00:05 AM Bot completes extraction extraction pending → extracted Vessel details, tonnage, IMO, value extracted (confidence 0.92)
9:00:05 AM Auto-route to QC extracted → quality check Confidence 0.92 >= 0.70; enters QC queue
9:15 AM QC analyst Rachel Kim reviews quality check Verifies 6 checklist items; corrects tonnage from 82,000 to 81,950
9:18 AM QC approved quality check → qc approved Checklist complete; correction logged
9:18:01 AM Auto-assign to underwriter qc approved → in review Assigned to James Parker (marine hull specialist)
9:18:01 AM Notification sent in review Bell notification: "New Marine Hull submission assigned"
10:30 AM Underwriter reviews, runs AI analysis in review 8 intelligence checks complete in 6.2 seconds
11:15 AM Underwriter issues quote in review → quoted Quote letter generated; premium $142,000
Apr 25 Broker confirms quotedbound Binder generated; subjectivities cleared

What Could NOT Happen

The following transitions would all be rejected by the state machine:

  • Bot tries to move from extraction pending → in review (skipping QC): REJECTED
  • QC analyst tries to approve without completing checklist: REJECTED (precondition: qc checklist complete)
  • Junior underwriter tries to bind a $65M hull (authority $10M): REJECTED (precondition: authority check passed)
  • Anyone tries to move from declined back to in review: REJECTED (no reverse transition defined)

Audit Trail

Every transition is logged in an immutable audit table:

Metrics: Before and After InsightUW Workflow State Machine

Metric Before InsightUW After InsightUW Improvement
Submissions skipping QC 15–25% (no enforcement) 0% (state machine enforced) 100% compliance
Invalid status transitions per month 200+ (bots + manual) 0 (rejected at API) 100% eliminated
Status audit trail completeness 40–60% (manual logging) 100% (automatic) Full auditability
Bot integration failures (invalid state) 30/week 0/week (contract enforced) 100% eliminated
Time to diagnose workflow issues 2–4 hours (check logs, DB) 5 minutes (audit trail API) 95% faster
Compliance audit preparation 2 weeks (manual evidence) 1 hour (export audit trail) 99% faster
Concurrent status update conflicts 5–10/week (no locking) 0 (atomic transitions) 100% eliminated
Mean time through pipeline (received → in_review) 4–8 hours 18–25 minutes 93% faster

Key Takeaways

  1. A status field without a state machine is just a string. InsightUW enforces every transition with preconditions, actor authorization, and atomicity.

  2. The QC gate is non-negotiable. No submission reaches an underwriter without passing quality check. The state machine makes this architecturally impossible to bypass.

  3. Bot API contracts prevent integration chaos. Bots must identify themselves, specify valid transitions, and provide required payloads. Invalid attempts are rejected with helpful error messages.

  4. Every transition is audited. The immutable audit trail satisfies compliance requirements and makes workflow debugging trivial.

  5. Configuration, not code. The transition table is data, not hardcoded logic. Adding a new status or transition does not require a code deployment.


Ready to enforce your underwriting workflow? InsightUW's state machine ensures every submission follows the right path — no skipped steps, no invalid transitions, no compliance gaps.

Schedule a Workflow Architecture Review →

See InsightUW run on your data

A 45-minute working session with a real broker email and your LOBs.

Request a demo