Three minutes
Summary
- The problem. An owner who lives far from a rental property hears about a broken hot tub or air conditioner as one sentence from a guest, and the technician's first visit often goes to finding out which part is needed (Part 1). The first version of this tool (v1) turned a photo of the equipment's data plate, the label with its make, model and serial number, into a brief cited to the maker's documents, and refused when the documents did not support an answer. But v1 remembered nothing: every brief paid for 7 to 8 fresh web searches, even for a unit it had researched before, and it knew nothing about the property (Part 3, Part 4).
- The thesis. A tool that remembers what it has already verified, and knows each property's records, can answer a repeat question with fewer searches and for less money without giving up any of v1's guarantees, as long as those guarantees stay in code rather than in the instructions given to the model. That needed a program that can branch, loop, pause for a person and save its progress, which is what LangGraph (a library that runs an AI workflow as a graph of steps) provides; LangChain (a library of building blocks for AI apps) runs the research step inside it (Part 5). It also needed each step to go to the cheapest tool that can do it: Anthropic's Claude for reading the plate, choosing what to search and writing the brief, and Tavily, a web search service built for AI tools, on its free tier for search (Part 6).
- The method. The bars were written into the product requirements on 17 September 2026, before any test ran: a repeat question about the same unit uses 2 searches or fewer, compared with the same unit's first v2 lookup; an invented model is refused 3 times out of 3 on the cheaper model; no cheap mode brief spends more than $0.15 and the whole build no more than $5; speed is reported, with no target. Replay (running the whole pipeline on recorded model replies and recorded search results, at no cost) tests the rules, the routing and the spending caps. Live batches on Claude Haiku 5.5 and Tavily, run on 13 and 14 October 2026, test how the model behaves; before ten new first lookups ran, a further bar was set: at least 9 of 10 must answer. A differential test sends 180 test briefs through both v1's validator (the code that checks each brief against the rules) and the rewrite's, and compares the verdicts (Part 8). Safety step flagging was tested on 29 and 30 September against 345 steps labeled by three model readers before any scoring, with the rule for choosing what ships written before any result. On 15 October 2026 I labeled the 175 held out steps myself, blind, with my answers sealed before any score, and Claude Haiku 5.5 was asked the same question as Jev, a judgment model from TypeSafe that flags safety steps, in a comparison whose settings were fixed before it ran (Part 9). Asking from inside an AI assistant was tested replay first: offline tests and a first connection in replay, then one live brief that I approved in advance, run by a test program through the official client software rather than by an assistant, afterward a free replay session in which Claude Code called the advisor's tools, and last one live brief in Claude Desktop, where I read the cost estimate and typed "proceed" myself (Part 7).
- The results. On Claude Haiku 5.5 (build d24ed7c475dcd813), a repeat of the hot tub's code question was answered from memory with 0 searches, against 2 on its first lookup. The other two repeats ended with no reliable answer: a vague hot tub question found the stored code but no documented causes, so it ran a short top up (a capped extra search pass when memory holds something but not enough) of 2 searches whose limit blocked the owner's manual it needed, and a new air conditioner question ran 4 searches because that unit's first lookup had also ended with no reliable answer and saved nothing: a miss on the bar of 2 or fewer. v1 ran 7 to 8 on every brief. The invented model was refused 3 of 3 times, each refusal made by the model. Of the ten new first lookups, 7 answered, against the bar of 9; Haiku 4.5 had answered all 10 (Part 8). A first lookup cost $0.0075 and answers from memory $0.0015 and $0.0013, against the $0.15 cap and an estimated $0.35 to $0.71 for a v1 brief; they took 40.1, 9.8 and 7.7 seconds, against 57 to 117 seconds for v1. A live run with synthetic property records cited the unit's earlier service record and its age, and a line written by code, not the model, said none of its warranty coverage was active. A replacement sweep, which checks each unit for a newer model its maker names, verified no successor for any of the three real units, and the product recall check found no product recall naming any of their exact models (Part 7). Through a new MCP server (MCP, the Model Context Protocol, is an open standard that lets an AI assistant call outside tools), Claude Code called the advisor's tools in a free replay session, reported the recorded brief's safety flag word for word with each step's source, and added a reading of its own. A live brief run by a test program and held at each paid step for "proceed" answered the hot tub's code question from memory for $0.0014, about the same as the $0.0015 it cost from the command line on 14 October. In Claude Desktop, a live brief I confirmed myself researched a water heater for $0.0061 and ended with no reliable answer, since the only manuals found were for sibling models with different model suffixes, so no live brief through an assistant has yet carried steps or safety flags; Desktop reported the refusal correctly, then filled the gap with general advice it labeled as its own (Part 7). Offline, v1's and v2's validators agreed on all 180 test briefs. Jev flagged 30 of the 31 safety steps the model readers marked in the half of the labeled set kept aside for the final score, against 20 for a rule matching the words breaker, power and heat. By my own blind labels it flagged 22 of 26, against 18 for either word rule and 19 for Claude Haiku 5.5 asked the same question, and about half of its 41 flags were steps I would not call safety steps. On the ten new lookups every safety step in a brief was flagged, 11 of 11 (Part 9).
- What it means. Remembering pays where it was designed to: an answer from memory cost about a fifth of a first lookup and took about a quarter of the time. But memory holds only what a first lookup verified: it keeps a code's meaning, not the steps, so both answers from memory listed no steps to try first where the first brief listed 4, and a first lookup that ends with no reliable answer saves nothing for the next question. The move to Claude Haiku 5.5 cut the cost per run to about a sixth of Haiku 4.5's, made runs slower and answered fewer first lookups. Haiku 4.5's 10 of 10 included answers built on the maker's general troubleshooting pages, which the tool's own rule does not allow; Haiku 5.5 more often declined on such pages, though not always, and no code enforces that rule. None of these changes loosens a rule that runs in code, and the tests cannot show that a cheaper brief is as good. On the ten new lookups the writing model flagged 10 of the 11 safety steps by itself, and the code check by Jev added the eleventh. Jev still catches the most safety steps by a person's reading, but with 26 safety steps its lead over the word lists and over Claude sits inside overlapping 95% intervals (the range each true rate probably falls in), so whether it beats a word list is not settled (Part 9).
- Cautions, and how to check. Replay proves the rules, the routing, the spending caps and the page layout; it cannot prove how the model behaves. The live samples are small: three runs for the refusal test, three repeat questions and ten first lookups, and three refusals out of three is consistent with a true refusal rate as low as about 37%. The property records and warranty rows are synthetic, and no technician has used a brief yet. Every live v2 number here comes from a named run on build d24ed7c475dcd813 (a build is a single frozen version of the code, identified by a fingerprint stored in every run record), run on 13 and 14 October 2026, US Eastern time (all on 14 October in UTC, the clock the run records use), with these exceptions: the product recall check ran on the evening of 13 October, before the ten first lookups, on build ad11e6e15a55d30a, which differs only in a research setting the check never reads; Haiku 4.5's figures, given for comparison, come from builds da738a1559ced359 and 9a64835e86a5a6c8; the labeled set scores trace to a locked settings file and the Jev model version (jev-1.13.0), not to a build; the Claude comparison ran on 15 October 2026 on build 179b4295c98a3143, which differs from d24ed7c475dcd813 only in a command that prints memory statistics; the first live MCP brief ran on 16 October 2026 on build 17427277685ed433, which adds only the MCP server to build 179b4295c98a3143, and the Claude Desktop brief the same day on build 841df66ad9669ef8, which changes only what that server says; v1's come from its own live run of 18 August 2026; and the whole build spend also counts runs on other builds. The safety step labels came first from three model readers, which were Claude models and may favor Claude in the comparison. The check against a person's labels has now been run, but the person is me, one labeler and not a technician, and 26 safety steps is a small sample. On 17 October 2026, all 3,696 offline tests passed on the code of build 841df66ad9669ef8, with the network blocked, no key and no cost (Appendix A).
Part 1
The problem
The property is an eight bedroom lake rental with a hot tub, two heating and air conditioning (HVAC) systems, a septic system, and a dock. The owner lives ninety miles away. When something breaks, the report arrives as a sentence from a guest or a cleaner: the hot tub is not heating, the upstairs is warm. That sentence is everything the technician gets. It does not carry the model, the age of the unit, the code on the panel, or what was tried the last time this happened. So the first visit is often diagnostic rather than corrective, and the part comes on the second one.
The job: when equipment fails at a property I am not at, help me tell whoever is going to fix it what this thing is and what the documentation says about this symptom, so they arrive with the right part instead of finding out what they need.
Note the shape of that job. It is not "diagnose the fault." Nobody standing ninety miles away, and no tool, should be doing that. It is "carry the documentation to the person who can."
Part 2
What I actually know
Verified.
- The failure this addresses is an information failure. Aberdeen Group research, cited widely across field service writing, puts about 51 percent of repeat visits down to a missing or wrong part, against 25 percent for technician experience and 13 percent for a job scheduled too short. I am citing secondary sources quoting Aberdeen rather than the original report, which I could not reach. Source, second source.
- The operations tools in this category track the schedule, not the house. One of the leading products stores make, model, and serial as fields and does nothing further with them.
- Manufacturer error code tables for this equipment exist publicly and are findable. The Sundance 880 series documentation the tool retrieves is real.
Inferred, and worth saying so.
- That a cited brief reduces second visits. This is the thesis, and it is not measured.
- That owners will photograph a data plate. It takes ten seconds, but nobody has been asked to do it yet.
Not known.
- Whether a technician changes what they load in the van because a brief told them to. One tradesperson answering that converts this from a build into a finding. Version two does not answer it either.
The demand signal I found pointed somewhere slightly different: local forums are full of owners asking who to call, not what is wrong. I noted it, kept building the narrower thing, and left the larger question open rather than quietly redefining the product to match the evidence I happened to find.
Part 3
What v1 proved
Every decision in both versions follows from one: the tool is allowed to say it does not know, and that is a success state, not an error. A maintenance tool that returns a confident, wrong, plausible looking repair instruction sends someone to open an equipment bay on live electrical, or to order a part that was never the problem. So the product has a NO RELIABLE ANSWER state, with its own layout showing what was searched, what was found, and why that was not enough.
A tool that is right most of the time and silent about which times is not a tool a technician can use.
v1 worked like this: photograph the plate, confirm what was read, get a brief. It made two calls to Claude Opus 5, the highest priced of the three Claude models priced in the build, using Anthropic's own built in web search capped at 8 searches, and kept no database. Five decisions shaped it, and all carry into v2.
The refusal lives in code, not in the prompt
Risk addressed: trust
Instead of writing "refuse when sources are insufficient" into the instructions and trusting it, validation code clears any candidates and suggested steps when the state is NO RELIABLE ANSWER, whatever the model returned.
- CostMore code, and a schema (the exact shape the answer must have) that the model must satisfy exactly.
- BoughtThe promise holds on a bad day, when the model is having one.
Label every source honestly, including when the honest label is weak
Risk addressed: trust, and usefulness
Sources are tiered manufacturer, dealer, or forum. A dealer page stays labeled dealer even when it is the best source found, and a brief built only on forum content says so at the top.
- CostSome briefs look thinner than a tool that quietly promoted its sources.
- BoughtThe label means something, so a technician can weigh it.
An observed code stops the search from widening
Risk addressed: usefulness
If the symptom includes a code visible on the panel, the code overrides symptom matching. On the same hot tub, the vague symptom returned six documented possibilities and the observed code returned one. A list of six is research. One is a part number.
- CostA misread code produces a confident single answer, so the brief tells the reader to confirm it on the unit.
- BoughtThe difference between a technician researching and a technician packing.
Search at the moment of the question, instead of building a corpus first
Risk addressed: feasibility
An earlier design parsed manuals into a knowledge pack in advance, and acquiring primary sources at scale was its open problem. Searching live at request time inverted that: the corpus would become a byproduct of questions people actually asked.
- CostEach brief costs money and time, and quality depends on what is public.
- BoughtA working, testable product instead of a data acquisition project with no end date.
Never diagnose. Carry documentation instead.
Risk addressed: safety, and liability
The brief never states a cause. It lists documented candidates, each with the documented meaning, the documented action, who should do it, and why it surfaced. First steps must be documented, safe for an untrained person, and actionable. Anything electrical or heat related is flagged and sorted to the top.
- CostReads as less impressive than a tool that names the fault.
- BoughtIt stays inside what the sources support, which is the only place it has any authority.
What the v1 run showed
Six acceptance cases were defined in the spec before the build. All six passed on content; the speed criterion did not. The four v1 briefs remain published as the evidence for this table: hot tub, code on panel, hot tub, vague symptom, air conditioner and the invented model.
| Case | Expected | Result |
|---|---|---|
| Legible plate | Read all four fields | All four, high confidence |
| Illegible plate | Return empty, not guesses | Model, serial and date all empty |
| Hot tub, vague symptom | Cited candidates, filter and water level checks | Six candidates, seven sources |
| Hot tub, code on panel | One confirmed candidate, not a list | Exactly one |
| HVAC, different category | Grounded, or a clean partial | Grounded, and invented no error codes for a category that does not display them |
| A model that does not exist | NO RELIABLE ANSWER | Refused, with its search trail, although generic advice for the brand was available |
| Any brief, under sixty seconds | Under 60 seconds | Missed: 57 to 117 seconds, over the target on three of four |
On the criterion v1 missed. Reducing how much reasoning each brief gets would have made the sixty seconds. I did not make that change, because the same setting buys the refusal behavior. v1 had not earned the right to say whether the criterion was wrong or the product too slow.
Part 4
Where v1 stopped
Running v1 showed three limits that no prompt could fix, because each is about what the tool remembers and knows, not about how well the model writes.
- It forgot everything. Every brief ran 7 to 8 live searches and read 42,000 to 91,000 tokens of input (a token is a word fragment, the unit models are billed in). A second question about the same hot tub paid the full price again. v1 logged every lookup but never stored what it verified.
- It knew nothing about the property. The brief has a "this has happened before" field. It was empty in all 4 recorded v1 briefs, because v1 had no service history to fill it from.
- It had no path for aging equipment. When a part is discontinued, the useful answer is a documented successor model, and v1 had nowhere to put one.
Cost made the first limit sharper. v1 never computed its own cost; its logged usage, priced at current list prices, puts a v1 brief at an estimated $0.35 to $0.71 (Part 6). Version two sets out to remember what it has verified, to know each property, and to spend less per brief, without moving any of the five decisions above out of code. Two items from v1's cut list come back for that reason: several properties, and warranty tracking.
Part 5
Why LangGraph and LangChain
LangGraph is a library that runs an AI workflow as a graph of steps. Each step reads and writes a shared record of the run, and arrows between the steps, called edges, decide what runs next. LangChain is a library of building blocks for AI apps: connectors to model providers, tools, and a ready made agent loop in which the model calls a tool, reads the result, and decides what to do next.
v1 was a fixed sequence of steps, and plain code was the right tool for it. v2 adds four things a fixed sequence cannot express cleanly: routing (answer from memory, top up with a few searches, or research in full), a bounded retry loop, a pause for a person to confirm the unit, and saved state for each property. Those four are a real reason to use a graph runtime, not a way to show off a framework.
The split: LangGraph runs the flow, LangChain runs one step
LangChain's ready made agent, create_agent, was
considered for the whole flow and rejected: it cannot hold a
confirmation pause that survives the program being closed and started
again, the validation retry loop, or state kept per property. So
LangGraph runs the whole flow, and create_agent runs only
the research step inside it, where a model and tool loop is exactly
what is needed.
| Capability | What it means | What the user gets |
|---|---|---|
| Interrupt and checkpoint (LangGraph) | An interrupt is a deliberate pause that waits for a person's answer. A checkpoint is a saved snapshot of the run, written after each step to a small database file. | The owner checks the unit and the code before anything is spent on research, and can finish later, even after a restart, without paying for the plate reading twice. |
| Conditional edges (LangGraph) | Arrows whose destination is chosen by a small function. | The tool answers what it already knows and searches only when it has to. A failed check gets one smaller second pass, only if the budget allows. |
| Parallel branches and typed state (LangGraph) | Several steps run at once, and the run's record has a fixed shape with a merge rule for each value they write. | Service history, stored facts and live research are gathered together, and the cost and the "what was searched" list on each brief include every call. |
create_agent and middleware (LangChain) |
The ready made loop of model and tools, and code that wraps every call in it and can stop a call before it happens. | A known worst case for each lookup: at most 5 searches and 3 page fetches on the first pass, and 2 more searches on the one smaller retry (v1 allowed 8 searches), and no model call once the money is gone. |
| Structured output (LangChain) | The model answers in a fixed, typed form, like filling in a form, not in free text. | Every citation in a brief points to a page the tool actually retrieved, because the model can refer to a source only by its number and code builds the list. |
| Provider connectors (LangChain) | Ready made connections to Claude and to Tavily's search and fetch. | Search runs on a free tier while Claude does only the judgment, so the owner pays for one model at its cheapest adequate setting, and the recorded demo shows exactly the calls that were made live. |
The tradeoffs actually paid
- The names move fast. Many functions were renamed or moved after the 1.0 releases, and the documentation and the source code disagree in three places. Every name was checked against the current release, the source was taken as correct, and v2 relies on none of the three disputed behaviors.
- No stock fake model could drive the agent. A fake model returns scripted replies so tests cost nothing. None of LangChain's supports tool calling (the model asking the code to run a search or fetch), and one silently loops back to the start of its script. v2 wrote its own, which fails loudly. Because it never checks the form the way the real API does, one paid check covered that gap.
- The structured output ceiling. Anthropic limits a form to 24 optional and 16 either or fields, and LangChain passes the form through unchanged. A draft modeled on v1's lenient form would have failed on the first paid call, so the form is now flat, with every field required.
- Defaults that had to be overridden. The agent's loop limit defaults to 9,999 steps, so the middleware caps are the only real guard; LangChain's own search limit leaves no reason in the run's record, so v2 wrote two small middleware pieces of its own. The Claude connector defaults to the model's maximum output, which on Haiku 4.5 would have reserved $0.32 against a $0.15 cap, so every call sets its own output limit, and neither connector has a timeout until one is set.
- A rewrite in a second language. v1 is TypeScript and v2 is Python, because Python has the more complete LangGraph ecosystem (an inference, not a measurement). The price was porting v1's validator; the differential test pays it back (Part 8).
- Model lifetime. Anthropic listed Haiku 4.5 as retiring no sooner than 15 October 2026, and the live command refuses a model's runs from that date. So cheap mode moved to Claude Haiku 5.5, listed as retiring no sooner than 7 October 2027, and every live Claude result the page reports as current was measured again on it, with Haiku 4.5's figures kept only for comparison (Part 8).
Alternatives rejected
- A vector store beside the graph. It finds text by similarity of meaning. In my earlier project on documentation gaps, vector search scored 24 correct against 23 for graph retrieval, a gap too small to justify a third way to look things up.
- A hosted graph database. At the size this build was planned for (about 50 nodes, an estimate), a Python library that holds the graph in memory and saves it as a plain file does the same job, with no account and nothing to pay.
- Building the corpus up front. v1 already rejected it. v2 grows memory only from lookups that really happened, so early questions pay for full research.
Part 6
Two APIs, each for its job
An API is a service the code calls over the internet and pays for by use. v1 used one API for everything: Claude Opus 5 read the plate, ran Anthropic's own web search, and wrote the brief. v2 splits the work by what each step actually needs. Since 30 September a third service, TypeSafe's Jev, also checks each step to try first in a brief for safety (Part 9), and the product recall check asks a free government service, with no key and no cost (Part 7).
Claude, for judgment
- Reads the plate photo.
- Decides what to search and which pages to fetch.
- Classifies a vague symptom, only when the routing rules cannot decide.
- Writes the brief.
- Cheap mode, the one run live, uses Claude Haiku 5.5, the lowest priced of the three models priced in the build, for every step, with research effort (a setting for how much the model thinks and how long it keeps researching) set to high. Full mode hands only the writing to Sonnet 5; it is tested in replay only.
Tavily, for finding pages
- Runs the web searches and fetches page text.
- Free tier: 1,000 credits a month. A basic search costs 1 credit; the 2 credit advanced search is switched off.
- A page fetch costs 1 credit per 5 successful pages; failed fetches are free.
- Paid overage is switched off, so a search costs $0.
Why the split is cheaper
Per million tokens, Claude Haiku 5.5 costs $0.10 in and $0.50 out on prompts up to 100,000 tokens ($0.50 and $2.50 above that), Sonnet 5 costs $2 and $10, and Opus 5 costs $5 and $25 (Anthropic's pricing page, checked 13 October 2026); Anthropic's server search adds $0.01 per search. Haiku 4.5, which the earlier live runs used, cost $1 and $5. So on shorter prompts the model price alone is a fiftieth of Opus 5's, and the search line, an estimated $0.07 to $0.08 per v1 brief (7 to 8 searches at $0.01), falls to $0 on Tavily's free tier. The $0 holds only on the free tier: at Tavily's pay as you go rate of $0.008 a credit, a worst case first pass of 8 credits would cost about $0.064 (arithmetic, not measured). So at volume most of the saving comes from the model and from memory skipping search.
| Brief | Haiku 4.5 | Haiku 5.5 |
|---|---|---|
| v1, any case (Opus 5, 7 to 8 paid searches) | Estimated $0.35 to $0.71; v1 never logged its cost | |
| Research route, answered (read plate, research, write) | $0.0435 hot tub, $0.0431 air conditioner (no plate photo) | $0.0075 hot tub |
| Ten first lookups, median per run (the five on the air conditioner had no plate photo) | $0.0476 (build 9a64835e86a5a6c8) | $0.0076 |
| Research route ending in a refusal (no plate photo) | $0.0270 to $0.0451 (invented model, 3 runs) | $0.0045 to $0.0068 (invented model, 3 runs); $0.0086 and $0.0089 (air conditioner) |
| Top up of 2 searches after a memory check | $0.0207 air conditioner (no plate photo), $0.0226 hot tub | $0.0040 hot tub, ending with no reliable answer |
| Answered from memory, no search | $0.0067 with property records (no plate photo), $0.0082 hot tub | $0.0013 with property records (no plate photo), $0.0015 hot tub |
| Plate reading alone | $0.0028 and $0.0029 | $0.0005 and $0.0006 |
| Full mode (Sonnet writes the brief) | Replay only; not run live | |
Runs marked "no plate photo" were given the model directly, so their cost includes no plate reading; the other hot tub runs include it. On shorter prompts Haiku 5.5 costs a tenth of Haiku 4.5's price per token, but per run it cost about a sixth.
The hard caps are $0.15 per cheap mode brief and $5 for the whole build. Every live run on build d24ed7c475dcd813 stayed under its cap: the highest, one of the ten first lookups, cost $0.0098. The runs on that build cost $0.1301 and 71 Tavily credits in total. The whole build has spent $1.5532 of its $5 and 249 of its 300 Tavily credits, a total that counts every live run on every build, the safety step work of 29 and 30 September, the Claude comparison of 15 October (Part 9) and the two MCP briefs of 16 October (Part 7) included. On credits, a first pass uses at most 8 (5 searches and 3 fetches) and the one smaller retry up to 2 more, so a brief uses at most 10, and 1,000 free credits cover about 100 research briefs a month at the worst case (arithmetic, not measured).
The second payoff: the rules stay in code
In v1, Anthropic's built in search returned its citations in a way that did not work together with structured output, so v1 could not have code build the source list; it relied on an instruction to the model not to pad the bibliography. In v2, the search and fetch wrappers hand code the raw results. Code builds the source list only from searches and fetches that actually succeeded, the model can point to a source only by its number, and because code holds the raw page text it can check that every quote appears word for word on its page and that a cited error code appears there as a whole word. The instruction became a rule enforced in code.
How LangChain and LangGraph carry the split
- LangChain puts both providers in one loop. The agent runs Claude's tool calling over Tavily's search and fetch, and one configuration file names the model for each step.
- Middleware counts both bills in one place. It counts Tavily searches and fetches against their limits and reserves each Claude call in a spending ledger before the call is made.
- LangGraph decides whether either API is called at all. Routing skips search when memory holds enough verified facts and sends a top up of 2 searches when it holds some. The confirmation pause sits before any research spend, so the only paid call before the owner confirms is the plate reading, which cost $0.0005 and $0.0006 live on build d24ed7c475dcd813.
The tradeoffs. Citation mapping, the page evidence checks and the credit count all became v2's own code, which is more to maintain than one provider, and it is the part that keeps the source list honest. The second tradeoff is quality: Haiku was picked because it is cheapest, and a cheaper model can write a less complete brief while every rule passes. So "cheaper" and "as good" are separate claims, and this page supports only the first (Part 9).
Part 7
What v2 lets owners and technicians do
Each feature is described by what the person gets and why it matters on the day something breaks. Where a live run shows it working, the demo case that replays it is named. The recorded v2 demo replays eight live runs of 14 October 2026 on build d24ed7c475dcd813. Four of the eight (cases 3, 4, 5 and 6) end with no reliable answer, and the demo shows them as refusals, the success state when the documents do not support an answer, though for the three real unit cases (3, 4 and 5) each also counts as a miss in Part 8. It shows warranty status on case 8, but not the replacement sweep, the product recall check or the MCP server.
Remember equipment it has already researched
For: the owner paying for the lookup, and the technician waiting on it
v2 keeps a knowledge graph: facts stored as things and the links between them, such as "this model shows this code", "this model has this documented cause", "this model replaced that one". Every fact carries its page address, the date it was retrieved, and the exact sentence from the page that supports it, and is stored only from a validated brief on a live run.
Live on build d24ed7c475dcd813, a repeat of the hot tub's FLO code question (FLO is the panel's flow switch code) was answered from memory with no search, for $0.0015 in 9.8 seconds, against $0.0075 and 40.1 seconds for its first lookup (demo cases 1 and 2). The repeat brief was thinner, though: memory keeps a code's documented meaning, not the steps around it, so the brief gave the code and its meaning but none of the 4 steps to try first that the first brief listed.
The air conditioner shows the other side. Its first lookup found Trane's general troubleshooting page and installer guides for other model numbers, but nothing documenting this model or its family, so the model declined and nothing was saved. A new question about the unit, a fan that would not spin, found nothing in memory, ran full research with 4 searches, and also ended with no reliable answer: $0.0089 in 43.5 seconds, against $0.0086 and 37.6 seconds for the first lookup (demo cases 4 and 5). On Haiku 4.5 (build da738a1559ced359) the same first lookup had answered, partly from Trane's general pages, and stored 6 documented causes.
- GetsA repeat question about a unit the tool has already answered skips or shortens search, so it is faster and cheaper, though an answer from memory alone can be thinner.
- WhyRental properties see the same equipment fail again, and v1 paid full price every time.
Know the property: history, age and warranty
For: the technician, before the visit
A matching earlier service record fills "this has happened before", cited to that record; a record for a different appliance is thrown out. Code computes the unit's age from the install date in the records, and the model is told not to. Warranty coverage is stored as one row per component, with its term and whether it starts at install or purchase, and code works out each end date and whether it is active on the run's date. The model never writes a warranty date, and the validator rejects one if it tries. The brief lists active coverage and tells the owner to check with the maker before paying for a repair; it never says which coverage applies, and with no rows it says "No warranty on file," never "out of warranty."
Shown live, on synthetic records. A live run on the hot tub with seeded synthetic property records attached (the model and the documentation were real; the records were made up for testing and are labeled so) cited the earlier synthetic service record, stated the unit was installed on 10 June 2021 and about 5 years old, and printed a coverage line written by code from three synthetic rows, all ended: "No warranty coverage on file is active as of 2026-10-14 (UTC)." It used 0 searches and cost $0.0013 in 7.7 seconds (run t-044cd20f9678498e on build d24ed7c475dcd813, demo case 8; its brief is briefs/v2/t-044cd20f9678498e.html). Like the repeat, it listed no steps to try first. Because every seeded term has ended, one synthetic water softener with active coverage was added; it shows on the offline property page, not in a live brief.
- GetsWhat was tried last time, how old the unit is, and whether it is under warranty, on one page.
- WhyThat is the context the one sentence report from a guest never carries.
A confirmation pause before any money is spent
For: the owner
After the plate is read, the run pauses. The owner confirms or corrects the model and the code. If the model number is unreadable, the run stays paused until someone types it, so a guess is never treated as confirmed. Live on build d24ed7c475dcd813, the clear plate was read exactly, every field at high confidence, and the blurry plate came back with its model, serial and date marked unreadable rather than guessed, and only the maker read, at low confidence (demo case 7).
- GetsA check on what was read, before the lookup is paid for.
- WhyA wrong model or a misread code wastes the whole lookup and can point to the wrong part.
Spending capped in code, and reported honestly
For: the owner paying the bill
Every paid call is reserved in a ledger (a running record of spend) before it is made, so a cheap mode brief stops at its $0.15 cap, give or take one call's estimate error. The ledger is never deleted, so a reset cannot grant a fresh budget. Running out of money is its own "budget stopped" status and never counts as NO RELIABLE ANSWER, because an empty wallet is not a finding about the documentation.
- GetsA known worst case per brief.
- WhyA tool that can run up an open bill is not one an owner leaves running.
The refusal and the honest labels, kept
For: the technician deciding what to trust
NO RELIABLE ANSWER is still enforced in validation code, and code can lower a source's tier label but never raise one. The badge now names the website that hosted the document beside it, so a maker's manual found on a third party archive is not a surprise. Live on build d24ed7c475dcd813, the invented model was refused on all 3 runs, each time by the model itself after it had reached the brand's real documentation (demo case 6).
- GetsThe same guarantees as v1, plus the host behind every badge.
- WhyCheaper is only useful if the brief is still safe to act on.
Upgrade options, replacement planning and maintenance, cited or absent
For: the owner deciding whether to repair, and planning prevention
A successor model appears only when a fetched page names it as a whole word ("Optima 880" is not taken from "Optima 880X"), and a price only when the cited page states that exact amount. A maintenance interval is kept only from the manufacturer, and code computes the due date from the property's maintenance log. Upgrade options and maintenance intervals are tested in replay only: in the re-recorded live runs, no brief needed an upgrade option or quoted a maintenance interval.
A replacement sweep now plans ahead of a failure. For each appliance at a property it shows the unit's age from its install date and any successor model a verified quote names; with nothing verified it says "No discontinuation documented in what this tool has verified," never "not discontinued." It reads stored facts at no cost, and an optional lookup asks only whether a model is discontinued and what replaced it, under one $0.15 cap for the whole sweep. Live on build d24ed7c475dcd813, lookups for the three real units (the hot tub, the air conditioner and the water heater) verified no successor for any of them, and one candidate for the air conditioner was dropped because its quote did not name the unit's model. The three lookups cost $0.0044 and 8 credits; the four units with invented makers were refused before any call.
- GetsA cited path to a replacement when parts run out, and a due date from the maker's own interval.
- WhyA guessed successor sends someone shopping for the wrong unit.
A brief a technician opens with no app
For: the technician
The brief is a single self contained page. Nothing loads from anywhere else, and all model text is escaped so it cannot run as code.
- GetsA file to text or email, with no login.
- WhyThe person who needs the brief is not the person who has the tool.
A product recall check that never says the unit is affected
For: the owner, before anyone opens the equipment
The tool asks the free recall service of the U.S. Consumer Product Safety Commission (CPSC) for every product recall listed under the maker's name, and code keeps only one that prints the unit's exact model. A match shows the product recall's number, title, hazard, remedy and link, and tells the owner to check whether their serial number is in the affected range; it never says the unit itself is affected. With no match it says no product recall names this exact model, with the date checked, never "no recalls." Invented makers are never queried. Run once on the evening of 13 October 2026, on build ad11e6e15a55d30a, 9 free requests returned 12 distinct product recalls for Trane, 6 for Rheem and 1 for Sundance Spas, and none named any of the three models exactly.
- GetsA safety notice that names this model, with no alarm raised by a similar one.
- WhyA false match on a safety notice either frightens an owner for nothing or teaches them to ignore the next one.
The advisor inside an AI assistant (MCP)
For: the owner who already asks an AI assistant for help
The advisor turns a photo of an equipment data plate, the label with its make, model and serial number, and a symptom into a service brief that cites every claim to a documented source, or says plainly that it does not know. It now also runs as an MCP server. MCP, the Model Context Protocol, is an open standard that lets an AI assistant call outside tools. It is built so that an owner can ask an assistant, such as Claude Desktop or Claude Code, for a brief in plain words, and the assistant receives the advisor's own cited brief: every step to try first with its source, every safety flag word for word, the documented candidates for what is wrong, the warranty coverage line, the cost, the run ID, and the location of the brief's page on the owner's computer, the file to send the technician. So far, Claude Code has called the tools in a free session in replay mode, which answers from recorded model replies; one live, paid brief has run through the official MCP library's own client, driven by a test program; and one live, paid brief has run in Claude Desktop, with me reading the preflight, the cost estimate shown before any money is spent, and typing "proceed". That brief ended with no reliable answer, the tool's refusal when its sources do not support one, so no live brief through an assistant has yet carried steps to try first or safety flags.
The server runs on the owner's own computer. The app starts it
and talks to it over standard input and output, a direct
connection between two programs on one computer, so there is no
hosted service to sign up for and no network port; a live brief
still uses the owner's own keys for the paid services, as the
command line does. Anyone can connect a copy of their own, on
their own computer, by the steps in the project's
README,
the page GitHub shows at the front of the repository. Out of
the box a copy replays a recorded case, with no keys and no
cost; a live brief runs only on that person's own keys and
accounts, and the repository holds no keys, with a test that
fails if one is in any file git would commit. The server is
built on the official MCP library for Python, version 2.2.0,
and offers four tools.
get_service_brief and resume_brief run
the same pipeline as asking and resuming from the command line.
property_status gives a property's warranty
coverage, each unit's age and any successor model the tool has
verified, and its stored product recall checks, free and
offline. check_product_recalls runs the product
recall check against the free recall service of the U.S.
Consumer Product Safety Commission (CPSC), which costs nothing
but asks first, because it sends requests to an outside service.
The server also offers two pages for the assistant to open: the
brief and the property page.
What the build keeps. The tools run the same graph of steps through the same pieces as the command line, so its rules apply unchanged: the citations, the refusals, the warranty dates written by code, the safety check by Jev, a second model that flags safety steps, and the spending ledger, which reserves every paid call against a $0.15 cap per brief and $5 for the whole build before the call is made. The server is part of the build fingerprint, the fingerprint of the code that every run record carries, so a run it starts names a build that covers the code that confirmed its spend. Every call that costs money or goes to an outside service first shows its preflight: the planned calls and, for a paid one, their typical and worst case cost against the $0.15 cap. It goes ahead only on the answer "proceed". A confirmation is used once, bound to the tool, its exact arguments and the exact preflight lines, and expires after ten minutes; a preflight that changed before it was confirmed is shown again, and nothing is sent.
Tested offline, then connected in replay. The
server's 32 test cases run with the network blocked, and 28 of
them go through the official library's own client (a client is
the part of an app that calls a server's tools; in these tests a
test program plays the app): 27 inside one
process and 1 over real standard input and output. They use the
protocol's 2026-07-28 version, and the earlier 2025-11-25 version
in the 4 cases on how the server asks the person. They show that
the same recorded case through the command line and through the
tools writes the same run record; that, in offline tests against
fake paid services, a live call refuses every missing, wrong,
reused, foreign or changed confirmation, with nothing sent and no
ledger row; and that every citation and safety flag reaches the
tool's response on nine recorded cases. MCP forms (elicitation,
in which the server asks the app to show the person a form to
fill in) have been answered only in these tests. Claude
Desktop's log does not record which protocol version it used,
so whether the 2025-11-25 version has run outside these tests
is not known. The strictest test setting
fails any run that leaves out or skips one of the server's tests,
and all 53 planted bugs that the server's tests and that setting
must catch (deliberate small breaks, used to check that the
tests notice them) were caught. Then, on 16 October 2026 and before any money
was spent, a test program made the first real connection through
the official client, in replay mode and at no cost. On the
recorded hot tub case it listed
all four tools, the brief paused, resumed and came back with 2
steps to try first, both cited, and 1 safety flag, and
property_status returned the property's 3
appliances.
One live brief, with a test program as the owner. Then, in run t-bc31dd881bff44c4 on build 17427277685ed433, the same test program started the server with live spending allowed and talked to it through the official client over standard input and output, the way Claude Desktop and Claude Code connect to a local server, on the protocol's 2026-07-28 version and without forms. No person was in the run. The test program played the owner, under my approval given in advance at about $0.01: it answered "proceed" only to a preflight whose typical cost was at most $0.02 and whose worst case was at most the $0.15 cap, and it confirmed the unit the plate shows. Asked for a brief from the hot tub's clear plate photo and "panel shows FLO", the server returned its preflight (typical $0.0109, worst case $0.15) and sent nothing. On "proceed", it read the plate exactly (Sundance Spas, Optima 880, serial 100915742, dated 06/2014) and paused for the owner to confirm the unit and the code FLO, which came from the owner's words, not from the plate. Resuming with the confirmed unit returned its own preflight (typical $0.0105, worst case $0.1497), and on a second "proceed" the brief finished. The four tool calls took 15.95 seconds (0.35, 5.37, 0.20 and 10.03); the whole session, from starting the server to closing it, took 17.82 seconds.
The brief was answered from memory, that is from facts an earlier lookup had verified, with no web search, and held one confirmed candidate: FLO, "Flow Switch Error: Water flow is restricted or the switch is stuck.", cited to a dealer page. It cost $0.0014 by the ledger, inside the $0.15 cap, about the same as the $0.0015 the same question cost from memory through the command line on 14 October. The difference is the length of what the model wrote in the brief writing call, 1,080 output tokens against 1,274 (a token is a word fragment, the unit models are billed by), not the server's: both runs sent the model the same input. The run record gives 12.97 seconds of processing, against 9.8 seconds on 14 October, 12.96 of them in the two model calls. The run made no search and no Jev call.
Then an AI assistant, in replay. Later that day,
Claude Code 2.1.299, running Claude Opus 5.5, was given the
server for one session only, in replay on the same build, so no
money was spent. Nothing was added to Claude Code's settings. The
session was non-interactive, with no person to answer questions,
and only the three advisor tools it needed were allowed, set in
advance, so no approval prompt was shown. The request was written
as an owner would write it: a guest says the hot tub's panel
shows FLO; here is the plate photo; if asked to confirm the unit,
confirm what the plate shows; check the property; report what to
try first with each step's source, any safety flags word for
word, the cost and the run ID. Claude Code connected, found the
four tools, and on its own asked for the brief and for the
property's status. The brief paused for the owner to confirm the
unit. The server asked by a form, which Claude Code canceled
automatically because the session was non-interactive, so the
run stayed paused. Claude then sent the confirmed unit itself,
taken from the owner's request, through
resume_brief, the path for apps without forms. The
brief came back with 2 steps to try first, both cited to dealer
pages, and 1 safety flag, raised by the brief's writer, the model
that wrote it; Jev's check shows as not recorded, because this
older recording holds no Jev answers. Claude's answer gave both
steps with their sources, the safety flag word for word and that
the writer raised it, that Jev's check was not recorded, the cost
labeled as replay with no real money spent, the run ID
t-7ecdeb193c584be8, and the property's warranty, product recall
and replacement status. It also added its own reading: it noted
that the plate's serial differs from the property's synthetic
record, and it called two lines in the brief contradictory and
said which to trust. That contradiction is a replay artifact,
since the recorded model text predates the unit details given in
this session, and it is the retelling the tool does not control.
The session took 34.5 seconds and cost the project nothing.
One live brief in Claude Desktop, with me as the
owner. First I made two fixes to what the server says
(decision 105 in the project's decision log): result messages now
count in the singular at 1, and a paused brief and the server's
standing instructions now tell the assistant to show the owner
what was read, ask them to confirm or correct it, and never fill
in or change a field itself. Then, in run t-7f23f74a338140bd on
build 841df66ad9669ef8, which carries those fixes, Claude Desktop
2.42304.0 on macOS started the server from its own settings file,
with live spending allowed, in cheap mode, the lower cost setting
with the $0.15 cap. I chose this trial and approved the money in
advance. My request, in my own words: "The water heater at my
rental isn't making hot water. Use the property-advisor tools to
get me a service brief for appliance appl-waterheater at property
prop-b." There was no plate photo: the unit came from the
property's synthetic record, a Rheem PRO+E50 M2 RH92 CL electric
water heater, so there was no plate reading and no pause to
confirm the unit, and decision 105's instruction was not put to
Desktop. Desktop called get_service_brief, and the
server returned its preflight and sent nothing, in 0.41 seconds:
typical $0.0105 and worst case $0.15 against the $0.15 cap, with
7 model calls typical and 17 at most, and the whole build at
$1.5471 of its $5. The server sent no form: it took the path for
apps without forms, returning the preflight with a confirmation
code, and Desktop's log shows only results from the server, no
request to the app. The log does not record which protocol
version Desktop used, and this trial does not show whether
Desktop can show a form. Desktop showed the preflight as text in
the chat and asked me to type proceed; I typed it there, and the
assistant called the tool again with "proceed" and that
confirmation code. That call reached the server 25.7 seconds
after the preflight left it, a gap that includes the assistant
writing its message and my reading and typing.
The call took 47.50 seconds in Desktop's log; the run record gives
43.45 seconds of processing, 26.06 of them in research and 17.30
in writing the brief. Memory held nothing verified for this unit
or its family, so the brief researched: 5 web searches, 3 page
fetches and 7 search credits (the unit the web search service
bills by). It also added the unit's history, because the
property's registry holds 1 record for it. The brief cost
$0.0061 by the ledger, against the preflight's typical $0.0105
and inside the $0.15 cap. It ended with no reliable answer,
declined by the model. Its reason, from the run
record: the only manuals found belong to sibling models with
different suffixes (RH95 EC1), the retailer and marketing pages
describe no procedure, and matching the symptom would need
general knowledge about electric water heaters, which the brief
does not use. With no steps, Jev's check was skipped, and there
were no safety flags. Desktop then called
property_status on its own, offline and free (0.09
seconds), and searched the web itself. Its answer reported the
refusal and its reason correctly, the cost ($0.0061 and 7 credits,
51 of 300 left) and where the brief's page was, and said the
property's record is synthetic. Then it added its own content,
outside the tool: warranty terms of closely related models from
the maker's product pages, with an inference that parts are
probably still covered; troubleshooting steps it labeled as
general electric water heater knowledge, "not from the advisor";
and its own pick of what to do. Before the run it had also added
a safety caution of its own. None of it went through Jev's check
or the tool's citation rules. So the tool refused to fill the gap
from general knowledge, and the assistant filled it, labeled as
its own. The whole build has now spent $1.5532 of its $5 and 249
of its 300 search credits; Claude Desktop's own usage on my
Claude plan was not measured and is outside the project's ledger.
After the trial, Desktop was set back to replay.
- GetsThe advisor's cited brief, its refusals and its spending checks, from inside an AI assistant.
- WhyAn owner who turns to an assistant first should get the documented answer there, not a guess, and should still confirm every paid call.
What it cannot show yet. Claude Desktop has run one live, paid brief, but no live brief through an assistant has yet carried steps to try first or safety flags; the setup guide, docs/mcp.md, shows how to connect both apps. It is still unverified which apps show MCP forms to the person, and without them both the owner's confirmation of the unit and the "proceed" pass through the assistant: the server cannot tell who supplied them, and the assistant could send either without asking, even a model number the plate did not show. No form has yet reached a person outside the tests: Claude Code's non-interactive session canceled the one it was sent, and the server sent Claude Desktop none, so whether Desktop shows forms was not tested; Desktop showed the preflight in the chat as text. In the Claude Code session, the assistant did send the unit details itself, taken from the owner's request. In Claude Desktop I typed "proceed" myself, and it still reached the server through the assistant. Decision 105 now tells the assistant never to fill in a field itself, but the pause to confirm the unit has not been put to an assistant since: the Desktop brief had no plate photo, so there was no unit to confirm. Without forms, the app's own approval prompt before each tool call is the owner's only check: keep it on, and never set these tools to always allow. How each app shows that prompt, Claude Desktop included, has not been verified. The assistant retells the brief in its own words, and that retelling is outside the tool's control: the tool's response carries every citation and safety flag word for word, but the assistant may leave some out, or add a reading of its own, as Claude Code did. Claude Desktop gave a live example: where the tool refused to fill the gap from general knowledge, the assistant filled it, with warranty terms of related models and troubleshooting steps it labeled as general knowledge, not the advisor's, none of them checked by Jev. Neither live brief had steps to try first or safety flags, so that safety flags reach the response is shown on the recorded cases, not on a live run.
Where each number comes from. The first live brief's cost, route and processing time come from its run record, data/runs/t-bc31dd881bff44c4.json, and the spending ledger. That brief's per call times, both of its preflights and what the replay connection showed come only from the test program's own logs, kept with its script in data/runs/t-bc31dd881bff44c4.client/; the replay log ends with the test script's own crash on its final summary line, after every call had printed, and the script was fixed before the live part. The Claude Code session is kept in data/evidence/claude_code_replay_20261016/: every event of the session, its one session settings, and two earlier attempts that stopped before Claude Code was signed in. Its run record and brief are data/runs/t-7ecdeb193c584be8.json and data/briefs/t-7ecdeb193c584be8.html. The Claude Desktop brief's cost, route, searches and processing time come from its run record, data/runs/t-7f23f74a338140bd.json, and the ledger's readout of the run; each call's times come from Claude Desktop's own log of the server's messages. The preflight's figures come from the chat, as Desktop showed them; its typical and worst case cost match the ledger's readout, and its build spend of $1.5471 is the ledger's $1.5532 less this run's $0.0061. That log, the same lines from Desktop's MCP log, the chat as I pasted it from Desktop, the server entry Desktop ran and the ledger readout are kept in data/evidence/claude_desktop_live_20261016/, and the brief's page is data/briefs/t-7f23f74a338140bd.html. These folders are kept out of the public repository.
Part 8
How v2 was tested
Replay runs the whole pipeline on recorded model replies and recorded search results, at no cost and with the network blocked. It proves the rules, the routing, the ledger and the page renderer, but not how the model behaves. Small live batches on Claude Haiku 5.5 and Tavily, run on 13 and 14 October 2026 on build d24ed7c475dcd813, test the model; Claude Haiku 4.5's results of 30 September appear only where the comparison is the point. The bars were written into the requirements on 17 September 2026, before any test ran, and the bar for first lookups before the ten new runs.
The rules stayed in code
- 14 of v1's 17 guardrail behaviors are ported. The other 3 tested parsing a block of text the model returned, which structured output removed, and are marked obsolete.
- v1's and v2's validators agree on the decision, the reason and the cleaned brief for all 180 differential test briefs: 16 from v1's guardrail tests and 164 new edge cases. The test needs v1's private source, so it skips on a fresh copy of the repository.
- A refusal or a budget stop clears candidates, steps, upgrade options and maintenance items; tier labels can be lowered by code, never raised; an observed code still narrows the answer.
- A stored fact needs a word for word evidence sentence from its page; a fact that fails is dropped, not downgraded.
- The MCP server keeps them too: the same recorded case through the command line and through its tools writes the same run record, and in offline tests against fake paid services a live call refuses every missing, wrong, reused, foreign or changed confirmation, with nothing sent and no ledger row (Part 7).
- On 17 October 2026, on the code of build 841df66ad9669ef8, all 3,696 offline tests passed with the network blocked. A full run the same day caught all 1,692 planted bugs. A planted bug is a deliberate small break in the code, used to check that the tests notice it.
Criteria, bars and results
| Criterion | Bar | Result | How measured |
|---|---|---|---|
| Rewrite agrees with v1's validator (SC1b) | All test briefs agree | 180 of 180 | Replay |
| Refusal clears the brief (SC3a) | Candidates and steps empty on refusal or budget stop | Pass | Replay |
| Pause survives a restart (SC5) | Resume without repeating the plate reading | Pass | Replay |
| Sources come from what search returned (SC6) | Source list built only from successful results | Pass | Replay |
| "This has happened before" (SC8) | Filled from a matching record, cited | Pass | Replay |
| Upgrade options (SC9) | Only when a fetched page names the successor | Pass | Replay |
| Self contained brief (SC10) | Nothing loads from outside; model text escaped | Pass | Replay |
| Warranty status in code (SC13) | Code computes every end date and status; no model written date; never "out of warranty" | Pass; live, none of the 3 synthetic rows active on 14 October 2026 | Replay, and live |
| Replacement sweep (SC14) | No successor shown without a verified quote naming it | Pass; live, no successor verified for the 3 real units, for $0.0044 | Replay, and live |
| Product recall check (SC15) | A match only on the exact model; never says the unit is affected; $0 | Pass; live, 9 free requests, no product recall names any of the 3 models | Replay, and live (build ad11e6e15a55d30a) |
| Invented model refused (SC3b) | 3 of 3 on Haiku | Pass: 3 of 3, every refusal by the model | Live |
| Repeat question searches less (SC7b) | 2 searches or fewer on every repeat | Miss: 0 (answered from memory) and 2 (a short top up), against 2 on the first lookup; 4 on the air conditioner's new question, against 4, because its first lookup saved nothing. The last two ended with no reliable answer | Live |
| First lookups answer (SC12b) | At least 9 of 10, set before the runs | Miss: 7 of 10 (4 of 5 hot tub, 3 of 5 air conditioner); every refusal by the model | Live |
| Safety steps flagged on live lookups (SC12b) | Every safety step flagged | Pass: 11 of 11, with 3 false flags | Live |
| Safety labels checked against a person's (SC12c) | One person labels the held out steps blind, sealed before scoring; nothing retuned; reported either way | Done: 162 of 175 agree with the model readers (Cohen's kappa 0.728; kappa is agreement corrected for chance, where 1 is perfect and 0 is no better than chance); by the person's labels Jev caught 22 of 26, inside overlapping intervals with both word lists and Claude (Part 9) | Offline from recorded answers; the Claude comparison live on 15 October 2026 (build 179b4295c98a3143) |
| Plate reading | Clear plate read; blurry plate left empty, not guessed | Pass: clear plate read exactly; blurry plate's model, serial and date marked unreadable | Live |
| Every run within its cap (SC11) | $0.15 or less per cheap mode run | Pass on every live run; highest $0.0098 | Live, from the ledger |
| Whole build spend | $5 or less | $1.5532, counting every live run on every build and the safety step work, the Claude comparison (Part 9) and the MCP briefs (Part 7) included; the runs on build d24ed7c475dcd813 cost $0.1301 | Live, from the ledger |
| Time for a research brief | No target; reported | 40.1 s; ten first lookups, median 41.3 s; refusals on the invented model 21.6 s to 27.2 s. Haiku 4.5 (build da738a1559ced359): 28.7 s and 25.8 s | Live, measured |
| Time for a brief from memory, and for a top up | No target; reported | 9.8 s and 7.7 s from memory alone; 26.5 s for the short top up. Haiku 4.5 (build da738a1559ced359): 4.3 s and 5.5 s; 15.6 s and 15.7 s | Live, measured |
Times are each run record's processing time; the repeat's evaluation record, timed from start to finish, gives 9.9 s.
What the newer model changed
Cheap mode moved from Claude Haiku 4.5 to Claude Haiku 5.5 because the older model could retire from 15 October 2026 (Part 5), and research effort was set to high. The same ten first lookups, five on the hot tub's code and five on the air conditioner's fan, compare the two.
| Measure | Haiku 4.5 | Haiku 5.5 |
|---|---|---|
| Answered | 10 of 10 | 7 of 10 |
| Cost of the ten runs | $0.4662 | $0.0750 |
| Cost per run, median | $0.0476 | $0.0076 |
| Seconds per run, median | 24.9 | 41.3 |
| Search credits, ten runs | 47 | 35 |
Every refusal came from the model at the writing step, where Haiku 5.5 declined when its only sources were the maker's general pages or a dealer's code table cut off before the action. The tool's own instructions to the writer (rule 6) ask for documentation of this exact model or its documented family and forbid general knowledge of the equipment category. Haiku 4.5's air conditioner answers, all five here and both in its demo, cited Trane's general troubleshooting pages, written for any unit, which that rule does not allow, so its 10 of 10 includes answers the rule forbids. Haiku 5.5 is not consistent either: its three air conditioner answers cite the same kind of page, and two of its refusals came on similar sources. No code check enforces the rule; only the model applies it. I shipped Haiku 5.5 at 7 of 10 and kept the rule as written, and both results are reported as measured. Haiku 5.5 was slower than Haiku 4.5 in every set of timed runs.
What the live numbers can and cannot say. Three refusals out of three is consistent with a true refusal rate as low as about 37% (one sided, 95% confidence), and three repeat questions and ten first lookups are small samples. Only the hot tub code repeat shows memory replacing search; the other two repeats ended with no reliable answer, one held to 2 searches by the top up limit and one with nothing in memory to use. The speed and cost figures sit beside v1's (57 to 117 seconds, and an estimated $0.35 to $0.71), but v2 changed the model, the search provider, the search cap and the pipeline at once, and the move to Haiku 5.5 changed the model and its research effort together, so they do not say which change made the difference.
Part 9
Design decisions, and the safety check
Four design choices shape how memory and replay behave. Each is there for a reason an owner or a technician would recognize. How they came about is recorded in the project's decision log (DECISION-LOG.md in the source).
Store documented causes as well as codes
For: owners of equipment that shows no codes
An air conditioner rarely displays an error code; what its documentation lists is causes, such as a blocked outdoor coil or low refrigerant. So memory keeps a documented cause, with its documented action, under the same word for word evidence rule as a code, and a cause label must share at least 2 content words with its quote. On Haiku 4.5 (build da738a1559ced359), the air conditioner's first lookup stored 6 documented causes and dropped 3 that failed these checks. On build d24ed7c475dcd813 that lookup ended with no reliable answer, so no cause was stored: after the batch, memory holds one fact, the FLO code's meaning on the hot tub, taken from a dealer page.
Never answer a question with no confirmed code from stored codes alone
For: the technician, who needs the full list when there is no code
"Not heating" can have several documented causes. Answering it from the one code memory happens to hold would narrow the list to a single part the symptom never pointed to. Answering from memory alone needs at least 3 distinct verified causes and a match from the symptom classifier; anything less gets a top up of 2 searches. Live on build d24ed7c475dcd813, the vague hot tub question found the FLO code but no stored causes, so the symptom classifier was not called and a short top up ran: 2 searches and 1 fetch. Its limit blocked a second fetch, an 880 Series owner's manual, and the model then declined, naming that manual's troubleshooting section as what was missing: no reliable answer, for $0.0040 (demo case 3). v1 listed six documented possibilities for the same symptom.
Whole word excerpts
For: anyone reading a quote in a brief
Excerpts of a page start and end on word boundaries. A quote cut in the middle of a word can change its meaning, as "$12" cut from "$129" would, and cannot be checked word for word.
Live recordings are replayable offline
For: checking the results
Replay reads the real page text saved from a live run, and marks grounding "unverifiable" when that text was not saved. On the build machine, every live run can be rerun offline for free, and the recorded demo replays the live runs verbatim. The live recordings stay on that machine, out of the public repository, so a reader can check each run ID and build fingerprint in the demo's data file but cannot yet rerun them.
The safety check, by a person's reading
Jev still catches the most safety steps by a person's reading, but with 26 safety steps its lead over the word lists, and over Claude asked the same question, sits inside overlapping 95% intervals, and about half of its flags are steps that person would not call safety steps. The person is me: on 15 October 2026 I labeled the 175 held out steps blind, and the comparison with Claude was registered before it ran. Every other safety result on this page, the live check included, is scored against the labels of three model readers, and by their labels Jev's lead over the published word list is clear. Both sets of results follow: the check and its test against the readers first, then my labels, the Claude comparison and a paired test, which compares two checks step by step on the same steps, counting only the steps where they disagree.
Why safety steps needed a check in code
The instructions ask the writing model to flag each safety step, and code sorts flagged steps to the top. Code can reorder flagged steps but cannot judge which steps need a flag: deciding what counts as a safety step means either trusting a judgment or writing a rule that judges the step's wording. Nor can code add a step, because every step must cite a source. So a step the model leaves unflagged stays unflagged unless something checks it, and testing such a check was the first item in Part 10.
A safety check in code, tested before it shipped
On 29 and 30 September I tested three ways to catch a safety step the writing model leaves unflagged, each able to add a safety flag but never remove one or add a step: a word rule that flags any step naming certain words (the published list was breaker, power and heat; a tuned list, chosen on the tune half described below, drops the bare word heat but keeps heater and heating, and adds wire, panel, door, disconnect, electrical, jumper and box); Jev, a judgment model from TypeSafe that reads each step and answers how likely it is to be a safety step, as a probability from 0 to 1; and Jev together with the tuned word rule. The test set was 345 steps, taken from maker and dealer documentation and from the tool's own earlier briefs, and labeled before anything was scored by three model readers working blind, who agreed on 338 of them. The set was split into a tune half, where each check's settings were chosen, and a held out half of 175 steps, 31 of them safety steps, which no setting ever saw. The settings were locked in a file before the held out half was scored, once, and the rule for choosing what ships was written before any result: of the tuned word rule, Jev, and Jev together with the tuned word rule, drop any whose precision (the share of its flags that were real safety steps) is below 0.60, then take the highest recall (the share of real safety steps it flagged), then the higher precision. Separately, on 29 September, before the live check, the instruction to the writing model was revised to spell out which steps count as safety steps: power or gas switched off, on or reset; working near anything that can be live, hot or carrying gas; and running or testing a heater.
| Check | Recall: safety steps flagged | Precision: flags that were safety steps |
|---|---|---|
| Word rule, as published (breaker, power, heat) | 20 of 31 (0.645) | 20 of 28 (0.714) |
| Word rule, tuned (the backup for a failed Jev call) | 22 of 31 (0.710) | 22 of 34 (0.647) |
| Jev, flagging at 0.51 or higher (shipped) | 30 of 31 (0.968) | 30 of 41 (0.732) |
| Tuned word rule plus Jev | 30 of 31 (0.968) | 30 of 50 (0.600) |
The held out half has no steps the tool wrote, so the writing model's own flags are not in this table; the ten live lookups below measure the writing model. With 31 safety steps the sample is modest. A 95% interval is the range the true rate probably falls in, given how few steps were tested. By the readers' labels, Jev's recall (0.838 to 0.994) sits clear of the published word rule's (0.469 to 0.789) and barely overlaps the top of the tuned rule's (0.534 to 0.839), and the precision intervals of all four checks overlap. The tuned word rule plus Jev flags every step Jev flags; its extra flags caught no safety step Jev missed, which is why its precision is lower.
What shipped, and the live check. Jev and the tuned word rule plus Jev tied on recall, and Jev alone had the higher precision, so Jev ships, flagging a step when it answers 0.51 or higher. Then the ten new first lookups ran live on Claude Haiku 5.5 (build d24ed7c475dcd813), five with the hot tub's FLO question and five with the air conditioner's fan question. The 7 that answered held 18 steps, 11 of them safety steps by the same three readers, and all 11 were flagged, with 3 false flags (11 of 14). The writing model, under a revised instruction that spells out which steps count, flagged 10 of the 11 by itself; Jev flagged 10 of the 11 with 1 false flag, and the one flag Jev raised that the writer left off was the safety step the writer missed. The tuned word rule, which ships only as the backup for a failed Jev call, would also have flagged all 11 (11 of 14). There is no clean figure for the writer before the revised instruction, so no before and after comparison is reported. The ten lookups cost $0.0750 and 35 credits.
What these numbers cannot say. The labels in the table above came from three model readers, not from people; a person's labels, below, give a less certain result. The tuned word list did not hold up: it scored precision 0.955 on the half it was tuned on and 0.647 on the held out half, below the published list, because words such as "door" and "box" found harmless steps in pages it had not seen. The live check is small, 11 safety steps from two questions, 10 of them on the hot tub and mostly at a breaker, so the held out half is the stronger evidence for the check itself. With Jev alone shipped, the tuned word rule now backs up any step whose Jev call fails: it can add a flag to that step, never remove one, and the brief still carries the line telling the reader to treat any step at a breaker, a panel, a heater or a gas valve as a safety step. The backup is weaker than the check it stands in for: held out, the tuned word rule caught 22 of 31 safety steps (recall 0.710) at precision 0.647, against 30 of 31 (0.968) at 0.732 for Jev. It was picked over the published list, 20 of 31 at 0.714, on 1 October, after the held out scores were known. The published list was not one of the choice rule's candidates, but the pick follows the rule's order: both lists have precision 0.60 or higher, and the tuned list has the higher recall. Build d24ed7c475dcd813 includes the backup, but every Jev call on it answered, so the backup raised no flag live and is shown working only by the offline tests. The demo shows Jev's check at work on case 1: the writing model flagged 3 of the brief's 4 steps, including turning the power off at the breaker and back on, and Jev agreed with all three (0.98, 0.77 and 0.96) and added no flag of its own.
Checked against a person's labels
On 15 October 2026 I labeled all 175 held out steps myself, on a local labeling page that showed each step with the instructions, worked examples and hazard choices the model readers had, and no reader's vote or check's flag. My answers were sealed before anything was scored (Appendix A). I agreed with the readers' majority on 162 of the 175 steps (92.6%), a Cohen's kappa of 0.728 (agreement corrected for the agreement chance alone would give, where 1 is perfect and 0 is no better than chance). I called 26 steps safety steps; the readers called 31. The same checks, with nothing retuned, scored as follows against my labels.
| Check | Recall: safety steps flagged (95% interval) | Precision: flags that were safety steps (95% interval) |
|---|---|---|
| Word rule, as published (breaker, power, heat) | 18 of 26 (0.692; 0.500 to 0.835) | 18 of 28 (0.643; 0.458 to 0.793) |
| Word rule, tuned (the backup for a failed Jev call) | 18 of 26 (0.692; 0.500 to 0.835) | 18 of 34 (0.529; 0.367 to 0.685) |
| Jev, flagging at 0.51 or higher (shipped) | 22 of 26 (0.846; 0.665 to 0.938) | 22 of 41 (0.537; 0.387 to 0.679) |
| Claude Haiku 5.5, asked Jev's question | 19 of 26 (0.731; 0.539 to 0.863) | 19 of 33 (0.576; 0.408 to 0.728) |
The rows match the readers' table above, in the same order, with two differences: the tuned word rule plus Jev, which did not ship, was not scored against my labels, and Claude, which ran on 15 October, is new; its figures by the readers' labels are in the next section.
Jev flags the most safety steps, 22 of 26, but its interval overlaps those of both word lists and of Claude, and its precision fell from 0.732 by the readers' labels to 0.537 by mine: about half of its 41 flags are steps I would not call safety steps. The 4 safety steps Jev missed by my labels are the ones I called safety steps and all three readers did not, so Jev missed only where the readers and I parted. By my labels the tuned word list, which backs up a failed Jev call, caught no more than the published list and flagged more steps that were not safety steps; it was chosen on the readers' labels, and nothing here changed it. After seeing the 13 steps where the readers and I disagreed, I changed my mind on 3, and 2 of those now match the readers; the changes are kept apart, and every number above uses the sealed blind labels.
Claude, asked the same question
The second comparison asks whether a general model does Jev's job as well. Before it ran, its settings were fixed in code: Claude Haiku 5.5, the model cheap mode already uses, asked Jev's exact question about each of the same 175 steps, one call per step, with the settings cheap mode uses to classify a vague symptom, including effort (how much the model reasons before answering) set to low. A "true" answer is a flag, with no threshold to tune. It ran once, on 15 October 2026 on build 179b4295c98a3143 (ledger run claude-judge-152437a0a5ed): all 175 steps were answered, none declined, for $0.0182.
By my labels Claude caught 19 of 26 at precision 0.576 (table above), inside the same overlapping intervals as Jev. Every safety step Jev missed by my labels, Claude missed too, along with 3 more. By the readers' labels Claude caught 28 of 31 (recall 0.903) at precision 0.848, against 30 of 31 at 0.732 for Jev. Claude and Jev agreed on 163 of the 175 steps (93.1%), a kappa of 0.795. By the ledger, Claude cost $0.000104 a step against $0.000028 for Jev, about 3.7 times as much, and took a median 1.08 seconds a step (90th percentile 1.67 seconds).
A paired test on the same steps
Overlapping intervals judge each check by its own total. A paired test is sharper: it compares two checks step by step on the same steps, counting only the steps where they disagree, here the safety steps one caught and the other missed, and the false flags (flags on steps that were not safety steps) one raised and the other did not. Its p value is the chance of a split at least this lopsided if the two checks were equally good, so the smaller it is, the harder the split is to put down to chance. A common bar is a p value under 0.05. I chose this test after the results above were known; unlike the Claude comparison, it was not set before the run. It reads only the recorded answers and cost nothing.
By my labels, Jev caught 3 safety steps that Claude missed, and Claude none that Jev missed (p value 0.250). Among the 149 steps I did not call safety steps, Jev raised 7 false flags that Claude did not, and Claude 2 that Jev did not (p value 0.180). Against each word list, Jev caught 4 safety steps the list missed and the list none that Jev missed (p value 0.125 for each list). On false flags the lists do better: Jev raised 17 that the published list did not, against 8 the other way (p value 0.108), and 12 that the tuned list did not, against 9 (p value 0.664). By the readers' labels, Jev caught 3 that Claude missed and Claude 1 that Jev missed (p value 0.625), and Jev raised 7 false flags that Claude did not against 1 the other way (p value 0.070). Jev caught 11 safety steps the published word list missed, against 1 the other way (p value 0.006), and 8 that the tuned list missed, against none (p value 0.008).
So by my labels the paired test agrees with the intervals: every split on catches that involves Jev leans toward Jev, but with 26 safety steps none is under that bar, nor are Jev's extra false flags against Claude or the word lists. By the readers' labels, Claude's edge on false flags, 7 to 1, comes close to that bar but does not clear it. The splits under that bar are all by the readers' labels: Jev's leads over the two word lists, and Claude's over the published list, 9 safety steps to 1 (p value 0.021). They need care: the scorer reports 24 such comparisons (every pair of the four checks, by both sets of labels, for catches and for false flags), with no correction for their number, and with that many tries chance alone can produce a lopsided split; a common correction, dividing the 0.05 bar by the 24 comparisons, leaves none of them under it. How the test was run is in Appendix A.
What these comparisons cannot say. One person labeled the steps, and I designed the tool; I am not a technician, and a technician might draw the line elsewhere. With 26 safety steps every interval is wide, and by my labels the paired test, chosen after the results were known, shows no check beating another on safety steps caught or on false flags. The readers' labels came from Claude models, which may favor Claude: by their labels Claude's precision is above Jev's (0.848 against 0.732), and by mine the two are close (0.576 against 0.537), the pattern such a bias would produce, though it does not prove one. Claude ran at the cheap classifier setting, effort low, so a higher effort or a larger Claude model might score differently; neither was tried. Nothing was retuned, and Jev still ships, flagging at 0.51.
Rules that stand
- Speed is reported, not scored.
- A budget stop never counts as a refusal.
- The retry is one smaller second pass, taken only if affordable.
- Misses are published as misses, and each live result is reported only from the build it ran on.
Part 10
What I would do next
- Decide how safety steps get flagged.Done Jev now checks every step to try first: by the model readers' labels it flagged 30 of 31 held out safety steps against 20 for the published word rule and 22 for the tuned one, and all 11 safety steps in ten new live lookups were flagged, the writer catching 10 and Jev the eleventh (Part 9).
- Put one brief in front of one technician and ask a single question: did this change what you would bring. Neither version has answered it, and it is the only question that turns process quality into evidence.
- Check the safety labels against a person's.Done I labeled the 175 held out steps blind on 15 October 2026 and agreed with the readers on 162. By my labels Jev caught 22 of 26 safety steps, but its lead over both word lists and over Claude asked the same question is inside overlapping intervals, and about half its flags were steps I would not call safety steps (Part 9). Two checks would settle more: a technician's labels, since I am not one, and a larger labeled set, since with 26 safety steps even a paired test, which compares two checks only on the steps where they disagree, cannot separate them: Jev's widest lead by my labels, 4 safety steps to none over each word list, has a p value of 0.125, and the published list's lead on false flags, 8 to Jev's 17, one of 0.108.
- Enforce the source rule in code. Both models answered from the maker's general pages, which the writer's rule does not allow, and only the model applies that rule. A code check that a cited page names this model or its family would make it hold on a bad day.
- Keep the steps, not just the meaning. Memory keeps a code's meaning, so both answers from memory listed no steps to try first. Storing each documented step with its quote would let a repeat answer carry them.
- Match product recalls to serial ranges. The check matches model names and tells the owner to check their serial number; reading serial ranges from free text is error prone, so it waits.
- Run v2 on a real property. The seed data is 2 properties and 7 appliances, all labeled synthetic. Three use real equipment models (the hot tub, the air conditioner and the water heater), and four have invented makers and model names.
- Measure speed and quality with one thing changed at a time, rather than inferring either from a comparison that changed four.
Part 11
What I cut
v1's spec named these as out of scope before its build started, which is the only time a cut list is honest. Two came back in v2, for the reason given in Part 4.
- Accounts, and anything resembling a funnel. Still cut. This is a validation instrument, and email capture would say nothing about the question.
- Several properties.Back in v2 Memory and service history only pay off per property.
- Warranty tracking and prevention scheduling.Back in v2 Coverage status is now computed in code from each component's term, and maintenance due from the maker's intervals.
- Integration with existing operations tools. Still cut. That is the business, not the test.
- The cleaner capture workflow. Still cut. The right long term entry point, and a second unproven assumption stacked on the first.
- A name and any branding. Still cut, so nothing rides on presentation.
Out of v2's scope from the start:
- Paid databases, a hosted graph database, vector stores and hosted servers. None buys anything at this size (Part 5).
- Repair versus replace dollar amounts. The tool never estimates a price a source does not give.
- A live demo. The recorded v2 demo replays live runs of 14 October 2026 verbatim and makes no API call, so it is free to visit and free to host.
- A mobile capture flow, and full mode live.
- ENERGY STAR efficiency ratings (the U.S. government's efficiency label) and links to technician feedback. Deferred by the second set of requirements.
Appendix A
Method made visible
v1: reviewing my own build adversarially
Before shipping v1 I reviewed the build against its own spec across three lenses: does it match the specification, does it use the platform correctly, and what breaks. A separate pass tried to refute every finding. Thirty five claims, thirty one confirmed. The ones that mattered were an intermittent failure on exactly the search heavy cases the product exists for, output budgets that would have cut a brief off mid sentence, a bug that corrupted citations when reassembling the response, and a script injection hole in the shared brief, the file handed to a third party.
v2: gates, replay first, and a typed "proceed"
- The build ran in phases. Replay phases came first, at no cost; live phases ran only after a typed "proceed", with the planned calls and spend printed first.
- The ledger reserves each call before it is made, against a $5 cap for the whole build.
- Every library name was checked against the current release before use.
- Planted bugs test the tests: a full run on 17 October 2026, on the code of build 841df66ad9669ef8, caught all 1,692.
- Every run record carries a fingerprint of the code that produced it, so each live v2 result on this page traces to its build: the live evaluation and the demo to build d24ed7c475dcd813, the product recall check to build ad11e6e15a55d30a, Haiku 4.5's comparison figures to builds da738a1559ced359 and 9a64835e86a5a6c8, the labeled set scores to Jev calls on 30 September under the locked settings and model jev-1.13.0, the Claude comparison to build 179b4295c98a3143, the live MCP brief run by a test program to build 17427277685ed433, and the live Claude Desktop brief to build 841df66ad9669ef8. The whole build spend is the one total that also counts runs on other builds.
- The MCP server was built and tested offline first, in replay and against fake versions of the paid services. Its first real connection ran in replay, at no cost. Only then did one live brief run, which I approved in advance at about $0.01. No person was in that run: a test program played the owner, answering "proceed" to each of its two preflights only because each was within limits set beforehand (a typical cost of at most $0.02 and a worst case of at most the $0.15 cap), and confirming the unit the plate shows. Later the same day, Claude Code called the tools in a free replay session. Last, one live brief ran in Claude Desktop, which I approved in advance and confirmed myself, typing "proceed" after reading its preflight; it ended with no reliable answer.
- The safety check was scored on a labeled set built before any scoring, with its settings locked and its choice rule written before the held out half was scored once.
- The check of those labels against a person's ran blind on 15 October 2026. A local labeling page showed me each held out step with the instructions, worked examples and hazard choices the model readers had, and no reader's vote or check's flag; an answer could be changed until sealing, and the latest one stands. The answers were then sealed by a hash (a fingerprint of a file's contents that changes if one byte does) before any score existed. Once they were sealed, the labeling page would not start again, and the scorers check that the labels still match the seal. The 3 answers I changed after seeing the disagreements are kept in a separate file and scored nowhere. The locked settings file and Jev's settings were not touched, and nothing was retuned. Eleven of my yes answers named only "other" as the hazard, which the protocol counts as no, exactly as it counts the readers' votes.
- The Claude comparison was registered before it ran: its settings were written down and fixed in code (settings fingerprint 658f072743accb13), with Claude Haiku 5.5 asked Jev's exact question and criteria, one call per step, effort low, a single true or false answer, and no thinking, sampling or fallback setting; a true answer is a flag, with no threshold and no tuning; a decline would count as not flagged and be reported apart; one run only, retried only on a lost connection; scored against my sealed labels and the readers' majority, beside Jev and both word lists. It was planned at about $0.02 and capped at $0.15, and cost $0.0182. Its run record names build 179b4295c98a3143, and its spend is ledger run claude-judge-152437a0a5ed, both of 15 October 2026.
- The paired test was added on 16 October 2026, after every result above was known, and was not registered before any run. It is McNemar's exact test, the standard paired test for two checks' yes or no answers on the same steps, run by the Claude comparison's scorer on the recorded answers only, with no call and no cost. The scorer reports all 24 comparisons in its scores file, with the steps behind every split, and makes no correction for their number. Nothing in the shipped check changed.
What I got wrong
- v1: I pinned a dependency version from memory instead of checking, and the build failed on the first compile.
- v1: one of my own tests was wrong. I checked the actual behavior in a browser before changing the assertion.
- v2: the price check once accepted "$12" from a page that said "$129", caught before any live run.
Honest limits of this write up
- No technician has used either version.
- The recorded v2 demo replays live runs of 14 October 2026 with no API call; four of its eight cases end with no reliable answer, as recorded. The four v1 briefs linked in Part 3 remain the record of v1.
- The v2 property records and warranty rows are synthetic. The property, the owner and the commercial detail are genericized; the equipment and the retrieved documentation are real.
- The product recall check matches model names, not serial ranges, and has run live once.
- Cost comparisons with v1 are estimates computed from v1's logged usage, not measurements of v1's bill.
- The safety step labels came from three model readers and one person, me; no technician has labeled them, and the readers were Claude models, which may favor Claude in the comparison.
- The MCP server has run two live briefs: one through the official library's own client driven by a test program, with no person in it and no search or Jev call, and one in Claude Desktop, which researched and ended with no reliable answer, so no live brief through an assistant has yet carried steps or safety flags. Claude Code has called its tools only in replay, no form has yet reached a person outside the tests, and an assistant's retelling of a brief is outside the tool's control.
Appendix B
Terms used on this page
- API: a service the code calls over the internet, paid for by use.
- LangGraph: a library that runs an AI workflow as a graph of steps; each step reads and writes a shared record of the run, and edges decide what runs next.
- LangChain: a library of building blocks for AI apps: model connectors, tools, and a ready made agent loop.
- Checkpoint: a saved snapshot of the run, so a run can stop and continue later.
- Interrupt: a deliberate pause that waits for a person's answer.
- Middleware: code that wraps every model call or tool call and can check or stop it before it happens.
- Schema: the exact shape an answer must have: which fields, of which types.
- Validator: the code that checks each brief against the rules and clears or rejects what fails.
- Tool calling: the model asking the code to run a tool, here a search or a page fetch, and reading the result.
- Structured output: the model answers in a fixed, typed form instead of free text.
- Knowledge graph: facts stored as things and the links between them, each here carrying the exact sentence that supports it.
- Replay: running the whole pipeline on recorded model replies and search results, at no cost.
- Ledger: the running record of spend, checked before every paid call.
- Planted bug: a deliberate small break in the code, used to check that the tests notice it.
- Token: a word fragment; models are billed per million tokens.
- Build: a single frozen version of the code, identified by a fingerprint stored in every run record. The live evaluation and the demo ran on build d24ed7c475dcd813, the product recall check on build ad11e6e15a55d30a, the Claude comparison on build 179b4295c98a3143, the first MCP brief on build 17427277685ed433 and the Claude Desktop brief on build 841df66ad9669ef8; Haiku 4.5's comparison figures come from builds da738a1559ced359 and 9a64835e86a5a6c8; "the whole build" spend is the project's total.
- Research effort: a setting for how much the model thinks and how long it keeps researching; high for the research step here.
- Warranty status: whether each warranty component is active on the run's date, worked out by code from its term and the install or purchase date.
- Successor model: the model a maker names as replacing a discontinued one.
- CPSC: the U.S. Consumer Product Safety Commission, which runs a free public service listing product recalls.
- Product recall match: a product recall that prints the unit's exact model number; a similar model never counts.
- HVAC: heating, ventilation and air conditioning equipment.
- Jev: a judgment model from TypeSafe that answers a yes or no question as a probability from 0 to 1; here, whether a step is a safety step.
- Recall: the share of real safety steps a check flagged.
- Precision: the share of a check's flags that were real safety steps.
- Held out half: the half of a labeled set kept aside from every setting choice, so its score is a fair test.
- Blind labels: labels given without seeing anyone else's labels or any check's flags.
- Cohen's kappa: agreement between two labelers corrected for the agreement chance alone would give; 1 is perfect agreement and 0 is no better than chance.
- 95% interval: the range a true rate probably falls in, given how few cases were tested; when two checks' intervals overlap, the intervals alone have not shown which is better.
- Paired test: a test that compares two checks step by step on the same steps, counting only the steps where they disagree; here, McNemar's exact test.
- p value: the chance of a split at least as lopsided as the one seen, if the two checks were equally good; the smaller it is, the harder the split is to put down to chance, and when many comparisons are run, a small one can still turn up by chance.
- Hash: a short fingerprint of a file's contents that changes if one byte changes; sealing the labels by hash shows they were not edited after scoring began.
- MCP: the Model Context Protocol, an open standard that lets an AI assistant, such as Claude Desktop or Claude Code, call outside tools; here, the advisor's four tools, served from the owner's own computer.
- Preflight: what a command or tool shows before a call that costs money or goes to an outside service: the planned calls and, for a paid call, their typical and worst case cost, the run cap and the spend so far. Nothing goes out until the answer is exactly "proceed".