One identifier. Five services. Fifteen steps. This is the complete thread of a single broker submission — from a prospect being found, through a refusal, through document assembly, to a queue item landing on an underwriter's desk. Nothing omitted, including the part where the agent was told no.
The submission reference is VS-2027-0832950. That string is also the correlation id,
which is the single most useful decision in the whole design.
The shape of the run
sequenceDiagram
autonumber
participant BR as Broker agent
participant PU as Data service
participant DS as Document store
participant UW as Underwriting
participant LN as InsightLense
BR->>PU: find_prospects(class, state, size band)
PU-->>BR: 12 candidates with filings data
BR->>UW: check_appetite(candidate A)
UW-->>BR: refused — class outside appetite
Note over BR,UW: Refusal recorded, run continues
BR->>UW: check_appetite(candidate B)
UW-->>BR: in appetite
BR->>UW: open_account(candidate B)
UW-->>BR: account opened, ref VS-2027-0832950
BR->>BR: assemble_package() — 6 documents
BR->>DS: store pack
DS-->>BR: 6 object keys
BR->>UW: send_to_underwriter(ref, attachments)
UW->>UW: intake, persist attachments
UW-->>BR: queue item assigned
BR->>LN: run finished — 15 spans, 7 actions, 3 events
What lands in each of the three records
The same run produces three different views. Each is useful to a different person, as covered in the data model post.
The run — 15 spans
The engineer's view. Every step in order, with what went in, what came out, tokens, latency and cost. Total for this run: $0.31.
step name tokens cost ms
1 plan 1,240 $0.019 980
2 find_prospects 890 $0.011 340 → tool
3 evaluate_candidates 3,110 $0.047 2,140
4 check_appetite(A) 420 $0.006 210 → refused
5 reconsider 1,880 $0.028 1,320
6 check_appetite(B) 420 $0.006 190 → allowed
7 open_account 510 $0.008 420
8 draft_acord125 2,940 $0.044 2,880
9 draft_sov 2,110 $0.032 2,010
10 draft_loss_runs 1,760 $0.026 1,650
11 draft_narrative 1,540 $0.023 1,480
12 assemble_package 680 $0.010 1,120 → 6 files
13 store_pack 210 $0.003 890 → tool
14 send_to_underwriter 390 $0.006 640 → tool
15 finish 420 $0.006 380
------
$0.31Step 5 is worth noticing. After the refusal the agent spent 1,880 tokens reconsidering before picking another candidate — that is the reasoning step that a refusal-as-exception design would have thrown away along with the refusal itself.
The authority record — 7 agent actions
The supervisor's view. Every capability the agent invoked, what it was permitted to do, and the outcome.
| Capability | Level required | Level held | Outcome |
|---|---|---|---|
| find_prospects | L1 | L1 | allowed |
| check_appetite (A) | L1 | L1 | refused — outside appetite |
| check_appetite (B) | L1 | L1 | allowed |
| open_account | L2 | L2 | allowed |
| assemble_package | L1 | L1 | allowed |
| store_pack | L2 | L2 | allowed |
| send_to_underwriter | L2 | L2 | allowed |
Note that the refusal here is not an authority refusal — the agent had the right to ask. It was a business refusal: the account did not fit appetite. Both kinds are recorded the same way, which is deliberate. A supervisor reviewing this wants to see everything the agent was told no about, regardless of which layer said it.
The business events — 3 records
The auditor's view. What actually changed.
14:22:07 account_opened VS-2027-0832950 agent BR-LOCKTON-02
14:31:44 documents_stored 6 objects agent BR-LOCKTON-02
14:32:19 submission_received VS-2027-0832950 system → queue UW-CASUALTYThree events, eighteen months from now, still readable by someone who has never heard of a span.
The documents
The pack is six documents, generated to be internally consistent rather than to look plausible individually — which is a harder problem and the one that matters.
| Document | Contains | Consistent with |
|---|---|---|
| ACORD 125 | Applicant, class code, coverage requested | The prospect's real filing data |
| Statement of values | Locations, building and contents values | Total insured value on the application |
| Loss runs | Five years of claims history | Exposure size and class hazard |
| Exposure schedule | Payroll, headcount by class | Filed employee count |
| Narrative | Operations description, risk controls | The class code and the loss history |
| Broker cover letter | Submission summary, target terms | Everything above |
Six documents that disagree with each other teach you nothing. The consistency is the test.
If the loss runs show a $2M claim against a $400k total insured value, an underwriting agent will reason about an impossible risk and you learn nothing about your appetite logic. Making the pack cohere is what makes the downstream behaviour meaningful.
Following it yourself
What this looks like in practice for the three people who care:
The underwriter searches VS-2027-0832950 in their own system and
finds the queue item, the six documents, and — because the correlation id is the submission
reference — the agent work that produced it, without needing a different tool or a different
identifier.
The engineer opens the run and sees fifteen steps. When a submission stalls, the step list shows where: a tool that timed out, a document generator that produced an empty file, an intake call that returned 422.
The auditor queries business events for the reference and gets three rows with actors and timestamps. They do not need to know that steps 4 and 5 existed.
What this looks like in InsightLense
Everything above is one screen. Searching the submission reference opens the thread, and the three record types are interleaved in time with the run steps collapsible underneath.
That is the case for the thread view in a single screenshot. The information needed to spot the defect was split across two services, and neither of them was wrong on its own terms — the document store really did write six objects, and intake really did receive none.
The bug this walkthrough found
Worth ending on, because it is the reason to build the walkthrough at all.
The first time we ran this, step 14 succeeded and the attachment table stayed empty. The intake route accepted attachments, constructed its request object with an empty list, and the request schema had no attachments field anyway — two independent breaks in one path. Submissions arrived with documents referenced in the body and nothing stored.
No test caught it. The route returned 200, the queue item was created, and the run looked clean. What caught it was a business event that said "6 objects stored" sitting next to an attachment count of zero — two records that should have agreed, in one thread, where a person could see both at once.
That is the argument for the whole model, in one incident.
Where do your agents already act on real records?
Tell us that, and what you would need to prove about those actions to an auditor. We will set up a hands-on walkthrough within two weeks.
Request a demo →