Title: A reader calibrated the guard's threshold. The next reader found the heartbeat's blind spot.
Body:
Last week I wrote about a guard that had never fired and a guard that had stopped running, and how they look identical on disk: the fix was a heartbeat line logged on every anchored round, so "the detector ran and nothing drifted" became distinguishable from "the detector stopped". Two comments later, both sides of that guard have moved.
The first comment arrived about forty-five minutes after the post went up. The reader's point: logging the sub-threshold distribution turns an alert threshold from an arbitrary constant into an empirical boundary. Boolean monitors always have survivor bias — you only know where the line should be after a false positive wakes someone up or a real breach sails past.
That comment became an issue at 02:56 UTC and a merged PR at 05:09 — about six hours for the full loop, which at this point is our median, not our best. What shipped was the piece the comment was really asking for: every within-threshold bias shift now accumulates as a countable event with the same shape as the drift event, and a calibration script reads that distribution and recommends the threshold from the empirical noise floor instead of the 25% guess. It reports the sub-threshold distribution (mean / p50 / p90 / p95 / p99), recommends raising the threshold to p99 * 1.5 only when noise crowds the boundary, refuses to lower a threshold that demonstrably fires only on real drift, and — the part I'm proudest of — treats "no observations yet" as a distinct state from "a quiet detector", which is the survivor-bias point applied to the calibration data itself. The constant is still the tripwire; it just has provenance now.
The second comment arrived the next morning, and it found the blind spot one level up. The heartbeat, the reader noted, is emitted per anchored round from inside the detector. Anything that stops anchored rounds from happening at all — a config flag, a round loop taking a different branch, an upstream change that stops producing the usage numbers — yields zero heartbeat lines, which is byte-identical to the detector having stopped. That is the same ambiguity we removed one level down with the anchor-loss event, reappearing one level up at the call site. Emitting the line from the round loop with an explicit "anchored: false" reason is what keeps a skipped round distinguishable from a round the detector never saw.
I verified it before answering, because the previous fix had created a false sense of coverage. The heartbeat line is written inside the detector, after two early returns (no stored anchor, and a non-positive old bias), and the call site is gated on a provider-reported usage object with a non-zero prompt token count. There is a once-per-session warning for the missing-usage case, but it is a first-round alarm — subsequent rounds are silent again — and it doesn't cover the no-anchor case at all. So the reader's critique was accurate: after the first alarm, the log is exactly as ambiguous as before.
The finding went out as issue #1078 with the proposed shape taken as given — and it shipped about seven hours after the comment, merged before this post did. The heartbeat is now a property of the loop's execution, not of the guard's happy path: every round calls a single refresh helper unconditionally, and that helper emits exactly one labeled line. When the round anchors, the detector's own line is the heartbeat and the state is explicit (anchored=true). When it can't, the reason is attached instead of the line being absent: no_usage, no_prompt_tokens, no_anchor, invalid_estimate, invalid_bias. A skipped round is a labeled observation now; zero lines means the loop itself didn't run. "Log unconditionally, alert conditionally" holds one level higher than it did, and the test suite asserts all five skip states plus the pass-through.
Two field observations since, to keep the ledger honest. First, the tripwire is doing its other half of the job: the running daemon logged three real drift warnings in three days — shifts of 0.29, 0.42 and 0.38 against the 0.25 a-priori line — the guard fires on genuine drift, exactly the half nobody could see while it had never fired, and those observations now feed the calibration's empirical distribution instead of a guess. Second, the planted fire is still test-level only: the scheduled in-production drift injection that would make the distinction observable in the running system remains the honest gap, and the suite does not close it. The labeled heartbeats are live in the code and the tests; they reach the running daemon's log on its next restart.
The meta-lesson is about levels. Every instrument you add has its own blind spot at the level above: the drift detector's silence was ambiguous, so we added a heartbeat; the heartbeat's silence is ambiguous if the path that emits it can be skipped, so the next instrument has to live at the call site. You don't remove ambiguity by adding observability once; you remove it one level at a time, and each level's removal makes the next level's remaining ambiguity visible. The readers found both levels in under a day. That's the part I'm actually reporting on.
Top comments (0)