What only the UI can see
Hesitation before an approve, a field edited then reverted, a scroll that never reached the evidence, a run abandoned with the tab still open — none of it reaches the backend, and all of it is what separates the two readings of a trust metric.
Here is the complete backend record of a HouseWarm review session. An extraction request. An extraction response with eleven fields and their confidences. A submission with eleven values and an approval. Three rows.
From those three rows you can compute correction rate, because the submitted values can be compared to the proposed ones. You can compute acceptance rate, from the same comparison. That is the end of the list. Whether the reviewer looked at the source crop, how long they sat with the low-confidence field before approving, whether they typed a correction and thought better of it, whether the previous document was opened and abandoned — none of it happened, as far as the server is concerned. The reviewer is a function that returns eleven strings.
Every signal that separates the two readings of a trust metric lives on the client, and none of it reaches a backend unless the interface decides to send it. That is not a limitation of HouseWarm’s architecture. It is a property of review gates: the thing you want to measure is a human deciding, and deciding happens in a browser.
The four signals, and what each one settles
Take them in the order the interpretation lesson left them, each paired with the ambiguity it is there to break.
Hesitation before an approve
The time between the reviewer’s last interaction with a field and the approve, measured while the tab is actually in front of them. It separates read it and agreed from clicked through. A genuinely better agent does not make a reviewer decide faster than they can read; a disengaged reviewer does exactly that. This is the signal that a falling correction rate cannot produce on its own, and it is cheap.
Emit it as a bucketed duration, not a timestamp pair, and gate it on page visibility with an idle threshold you write into the schema. Two seconds and two hundred seconds should land in different buckets; two hundred seconds and a lunch break should not land in the same one.
A field edited, then reverted
The reviewer disagreed with the agent, changed the value, and put it back. By the definitions the metric-set module settled on, that document is accepted unchanged — correction rate compares submitted values to proposed ones, so the revert vanishes. That is the right call for the metric and a bad outcome for the record, because a revert is one of the few moments where a reviewer’s reasoning becomes visible.
It is ambiguous on its own, which is why it is useful. A revert can mean the reviewer checked the evidence and the agent was right after all — a caught near-miss, and the gate working. It can also mean the field is confusing enough that a competent person entered a value and could not defend it. Those are opposite findings, and they are distinguished by whether the crop was opened in between, which is why this event and the next one are worth nothing separately.
Evidence never reached
HouseWarm shows a source-image crop and the raw OCR text one disclosure away. Whether either was opened before the approve is a fact the interface can observe and the server cannot. It is the most direct test available of the disengagement reading: an agent that got more accurate does not reduce how often a reviewer inspects the evidence, and a reviewer who stopped reading does.
Decide precisely what counts, because “opened” hides a choice. Clicking the disclosure is one thing, the crop entering the viewport is another, and the crop being visible for long enough to have been looked at is a third. Any of the three is defensible. Only one of them is what your event means, and the schema row has to say which.
A review abandoned with the tab still open
Opened, interacted with, never decided. This one is not merely client-only, it is invisible: to a backend that hears about approvals, an abandoned review is not a zero, it is an absence, and it reads as if the session never happened. Abandonment is the metric most likely to be reported as excellent by a gate that has no way to detect it.
The browser gives you no dependable “the user left” moment, so do not design around one. Abandonment is inferred from the absence of a terminal decision within a stated window after the last interaction, which means the window is part of the definition and belongs in the metric row rather than in the implementation. A heartbeat while the tab is visible is what makes the inference possible at all.
What each one costs the component
None of these is an analytics change. Each is a requirement on a component, which is why the schema lesson insisted on naming the emitter in the row:
- Dwell needs a clock reading at the last field interaction and at submit, plus the page-visibility state in between, plus a bucketing function so the emitted value is a range rather than a duration.
- Revert needs the field to hold the agent’s proposed value alongside the current one for the life of the session — a change to the field’s state, not to its markup.
- Evidence opened needs the crop and the OCR disclosures to be observable, and needs the definition of “opened” the schema chose to be the one implemented, not whichever was easiest.
- Abandonment needs a session identity that survives a reload, a heartbeat, and an agreed window. It is the only one of the four that changes the shape of the session rather than a single component.
Cost them honestly when you take the spec to engineering. Three of the four are small. The fourth is not, and pretending otherwise is how abandonment ends up as the row that quietly never ships and then reads as zero forever.
Every one of these is also a surveillance surface
Dwell time per reviewer, reported per reviewer, is a productivity metric whether or not you intended one. So is abandonment. The moment these events exist, someone can ask which reviewer is slowest, and the answer will be available.
This course’s position, stated as a position rather than a finding: instrument the surface, report the surface, and put the per-reviewer breakdown behind a stated purpose. The metric-set module asked for per-reviewer reporting because time-to-trust is a property of one person’s relationship with a system and is meaningless pooled. That is a reason to compute it per reviewer. It is not a reason to publish a leaderboard, and the difference between those two is a decision you should make in the spec, in writing, before someone else makes it in a dashboard.
The ceiling on all of this
Instrumenting these four tells you when a reviewer disengaged. It does not repair the disengagement, and the same study is blunt about the limits of the interventions that try to. Participants given no AI assistance at all outperformed every AI condition, cognitive forcing functions included, on the cases where the model was wrong. On the sub-decision the authors analysed most closely, overreliance on incorrect predictions fell from 0.64 to 0.48 — a real reduction, and still short of removing the problem. The title says cognitive forcing functions can reduce overreliance, and the hedge is the honest part of the sentence.
There is a second constraint worth carrying into any intervention you propose off the back of these events. The forcing functions helped participants high in need for cognition considerably more than those low in it, and the authors raise this explicitly as a question of intervention-generated inequality. A change that works on the reviewers who were already engaged is not a fix for the reviewers the metric was worried about. So when your dwell distribution shows a bimodal split and somebody proposes adding friction, the events you built will also tell you whether the friction landed on the right half.
Check your recall
Answer from memory — no scrolling back.
Retrieval check
Why are “field reverted” and “evidence opened” close to worthless as separate events, and valuable together?
Check your answer
Because a revert on its own has two opposite meanings. If the reviewer opened the source crop between the edit and the revert, they checked and the agent was right: a near-miss caught, and evidence that the gate is doing its job. If they reverted without ever looking at the evidence, they entered a value they could not defend, which is a finding about the field’s clarity or about the reviewer’s confidence in their own judgement.
Same event, two conclusions, and the thing that separates them is the other event and its timestamp. This generalises: a client signal is usually ambiguous alone and disambiguating in a sequence, which is why section 1 of the spec asks what question each event answers rather than what it records. An event whose question can only be answered jointly with another should say so in the row.
Hands on
Add the four client-only rows
Done when: Section 1 of INSTRUMENTATION.md carries a row for each of the four client-only signals, each naming its emitting component, its precise trigger, and the metric ambiguity it resolves — and each row is marked with whether HouseWarm’s gate can emit it today or needs a component change.
- Write the four rows: hesitation before approve, field edited and reverted, evidence opened, review abandoned. Use the
object_verbnaming you committed to in the schema lesson. - For each, write the trigger precisely enough that two engineers implement the same thing. “Evidence opened” is the test case: pick click, viewport entry, or sustained visibility, and write the pick into the cell.
- In the question it answers cell, write the ambiguity it breaks rather than what it records. “Distinguishes a falling correction rate caused by a better agent from one caused by a reviewer who stopped checking” is a question. “Tracks crop opens” is not.
- Mark each row emits today or needs a component change, and for the second kind write the change and a rough cost. Be honest that abandonment is the expensive one.
- Add one line to section 4 naming who decides whether per-reviewer dwell is reported and to whom. That is not your call alone, and leaving it unwritten means it gets made by whoever builds the first dashboard.
- Bring the four rows into the chat. I will take each one and argue it is measuring the reviewer rather than the interface, and your job is to say what the row is for.
What this does not cover
These four rows now carry properties, and some of the obvious properties are the content of a mortgage document. The most informative version of the revert event would record the value the reviewer typed and the value they went back to, which would be genuinely useful and would move a borrower’s name out of the review gate and into an analytics warehouse.
The never-logged lesson is that constraint: what must not leave a review surface, the regulator’s principle behind the exclusion, and the derived shape that gets emitted in its place. After that, the routing lesson decides which of these events goes to product analytics, which goes to the trace, and which goes to both with two different payloads.
Read this next — primary source
To Trust or to Think: Cognitive Forcing Functions Can Reduce Overreliance on AI in AI-assisted Decision-makingZana Buçinca, Maja Barbara Malaya & Krzysztof Z. Gajos, Proc. ACM Hum.-Comput. Interact. 5, CSCW1, Article 188, 2021 — free author copy from the Harvard EECS site
The interpretation lesson took one correlation from this paper. This lesson takes the design consequence, so it is worth having the whole thing open. Read it for the method — a simulated AI pinned at 75% accuracy, three different ways of forcing the participant to think before seeing the suggestion — and for the two results that constrain what you are allowed to conclude: participants with no AI at all outperformed every AI condition on the cases where the model was wrong, and the interventions helped the already-engaged more than the disengaged. Note the “Can” in the title. It is doing work. Where it stops: the paper measures self-reported trust and decision accuracy. It does not measure dwell, reverts or scroll depth, and nothing here should be read as though it did.
Stuck, curious, or think this lesson is wrong? Ask your teaching agent. The lessons are the scaffold; the conversation is where the learning gets unstuck.