Version two
The reviewed read
The reading is the substrate. The review is the product. When a person accepts, assigns, or settles what the reading could not, that decision is part of the record, and the record now shows what the claims already consumed. It runs live in the V2 demo.
Decisions and erosion built and running. Sample readings persist behind the storage interface. Accounts, roles, and the client context that would group readings by customer designed, not built.
The problem, in two halves
- A person’s answer disappears into the result. The value reaching the coverage tower is sometimes the machine’s and sometimes a person’s, and by the time it reaches the summary the two are indistinguishable. The build already refuses to let the reader assert a citation without code checking it. Provenance existed for the machine and not for the person.
- The printed limit is not the remaining cover. A two million dollar aggregate with claims paid against it is a smaller number, and reporting the printed figure is a confident wrong answer, which is the failure this whole build is organized against. “Is this coverage sufficient” is not answerable without what the loss runs know.
What was built
The scope was deliberately small: the engine already stopped, cited, and refused, so this slice applies the same discipline to the person operating it, and no more.
- Read decisions are first-class objects. A decision is a dated determination against a policy, not a log entry: who decided, when, what the reading said, what the person determined, why, tied to the citation the system produced, bounded by the policy period. It does not carry forward on renewal. It is not an attestation; nobody signs anything. It is a diff on the reading, captured as a side effect of doing the work.
- The loss run is a third document type. You read declarations. You read schedules of underlying insurance. You read loss runs. All three are inputs to one coverage picture. A loss run is read for what it prints, every figure cited, and its citations are verified against the page text like any policy reading.
- The join is by policy number, or by a person. The entity name on a loss run routinely differs from the named insured on the policy, so a name never decides the join. Where the printed number matches nothing in the program, the run stops, shows the printed words, explains why the join matters, and asks. The answer is recorded as a decision either way, including the answer “leave it unapplied”.
- Erosion is arithmetic, in code. The aggregate comes off the declarations, the losses come off the loss run, and the subtraction happens in TypeScript. The tower shows what remains beside what was printed, dated to the report’s own valuation date, because losses develop and the figure is a photograph. An incurred total includes what the carrier has reserved for a claim but not yet paid, so what remains rests partly on the carrier’s estimates, not on a settled balance.
- A person can settle what the reading could not. Whether defense costs erode the limits is policy language, and the reader’s verdict is discarded unless it cites the page. When it comes back unknown, the person who has read the form can determine it, with a required rationale. The extraction is never touched, so what the reader could prove and what the review concluded stay distinguishable forever, and the check row names the decider.
- Known claims can be entered where no loss run settles the aggregate. An aggregate nothing settles is not actually full; it is unknown. Where no loss run is in the file, or the one that is there was left unapplied, the operator can state the paid and pending claims against a policy. The arithmetic over them is the same code a loss run goes through, and the tower then reflects the point in time. The basis is never blurred: the figure is marked asserted everywhere it appears, the remaining-aggregate check reports it as asserted and not evidenced, and a loss run supersedes it the moment one arrives.
Hard problems, met and settled
- Loss runs are carrier-formatted and inconsistent. One prints a grand total, one prints five policy periods in one report, one prints asterisks where the reserves would be. The reading takes only what is printed: incurred where the report totals it, paid where paid is all it prints, labeled as whichever it was, and nothing invented either way.
- The join key is not always present or clean. Policy number is the join key and the demo corpus deliberately includes a loss run whose number matches nothing. A system that asks and explains is doing risk management; one that guesses quietly is doing what this build spent four commits refusing to do.
- Identity without accounts. There is no sign-in in this build, so the operator is recorded under the placeholder tag [user.name]: the field is real, the capture is designed, and an invented identity would be worse than saying so.
Not built, on purpose
- No claim lives here. Loss runs are an input, and entered claims are the operator’s stated facts inside one review, standing in for the loss run that would evidence them. Nothing has a lifecycle: no claim record is kept, managed, or edited, because the moment the product owns claim records it has become claims administration, which is a different product and somebody else’s.
- Communications capture. Routing counterparty communication through the tool was considered and cut. People route around forced channels, and a partial audit trail is worse than a stated gap because it looks complete.
- Accounts, roles, and permissions. Designed, not built. Documents belong to a client account rather than a browser session, and the person who reads is not always the person who accepts.
- Persistence. Partly built. A sample reading is written to Postgres behind the storage interface and survives a redeploy; an uploaded document’s reading is not written, because its text is a customer’s and the site’s own promise is that it lives only in memory for the session. What is missing is the account context above: readings persist, but nothing yet groups them by client so a renewal can be held against what was there before.
Done when
The operational parts are shown working live, and the parts that are designed rather than built are labeled as designed. The decisions and the erosion run live in the V2 demo, and sample readings persist live behind the storage interface; accounts, roles, and the client context that would group readings by customer are presented as design in this engagement.