The Most Honest Answer My Tool Gives Is “Unknown”

I was building SessionRx, a local tool for reading the session logs that AI coding CLIs already write. It reads Claude Code, Codex, and Cursor, then runs six health checks against each recent session.
The useful part is not a clever dashboard. It is the refusal to make a missing measurement look healthy. Every check returns one of three states: observed, not-observed, or unknown.
The most honest answer my tool gives is “unknown”.
The incident had three denominator traps
During the build, a live context-fullness check reported a session reading 4.995 times its context window. That was not a slightly noisy percentage. It was evidence that the denominator was not what the product thought it was.
Trap one: the table was smaller than the sessions. F-008 assumed a fixed 200,000-token window table while real sessions were running on 1,000,000-token windows. The largest live session therefore read 4.995× its window. The scale mismatch was visible in the real-day comparison: on 2026-09-16, 360 turns averaged 237,666 tokens per turn. Against the old 200,000-token table, that day looked like 119% and fired the alarm; against a promoted 1,000,000-token window, it was 24%.
Trap two: a known tier crossed vendors. The first fix followed the rule “smallest known tier at least as large as the observed floor.” That lent gpt-5’s 400,000-token tier to an Anthropic session. A real session peaked at 368,963 tokens and consequently read 0.922 of its window: a false alarm. The correction is not a larger global ladder. Tiers are vendor-scoped. That same Anthropic session now resolves to 0.369 against the vendor’s 1,000,000-token tier.
Trap three: a floor became its own denominator. When no vendor tier is known, the only available denominator is the observed floor: the amount the session demonstrably reached. Floor divided by floor is 1.0 by construction. That would warn on every such session, even a trivial 5,000-token one. The rule is now explicit: the context fraction is unknown. A lower bound may be shown as “at least N,” because that is supported by the records, but it must never be turned into a percentage.

The fix was to stop guessing
The result is narrower, not more optimistic. When the window source is an observed floor, the context fraction is unknown. There is no percentage and no threshold verdict.
The lower bound can still be displayed as a lower bound. “At least N” is a fact about the records. “This is a percentage of the window” is a claim the records cannot support. Those are different statements, and the product now keeps them separate.
On the 20 largest real sessions, fractions above 1.0 went from 20/20 to 0/20. The fix did not hide real warnings: seven sessions still correctly warn at 0.96–0.999 of a 1,000,000-token window, and a test pins that behavior. The maximum published fraction fell from 4.995 to 0.417, while 0 of 264 observed-floor turns publish a fraction.

Unknown is not a pass
observed means a problem was found, with evidence. not-observed means the check ran and found nothing wrong. unknown means the log did not record what the check needed. It is not a green substitute for zero, and it is not silently counted as passed.
This rule applies beyond context pressure. A cache rate cannot be formed without cache counters. A repeated-tool check cannot establish repeated work if results are absent. A concurrency check cannot invent child intervals from a log format that does not record them. In each case, the honest result is unknown.

The other failures mattered too
The context incident was not the only useful failure. The build caught two real redaction bugs. A line shaped like authorization: Bearer … could have left the token exposed because the first keyed-credential pattern stopped at the space after Bearer. The fix made that redaction order-independent.
A second pattern was too broad: a naive base64 rule could eat ordinary deep filesystem paths. That would have removed the primary evidence references from the report. The redactor now protects those paths while still handling the credential shapes it is meant to hide.
The privacy boundary is equally deliberate. SessionRx never writes your files, reads session logs read-only, sends no data to a remote service, makes no AI API calls, and uses no remote network requests. Suggestions are previews of exact text plus a request you can copy into your own coding tool; that tool makes any change, and you approve it there.
The report still includes file paths and project names so findings can be traced, so it should be read before it is shared. The build also caught two redaction bugs: a Bearer token could have escaped when a keyed pattern stopped at the space after the word, and a broad base64 pattern could have consumed deep filesystem paths. Both were fixed and tested: credential-shaped values are redacted while paths and session UUIDs survive as evidence.
The operating rule
A health check is not allowed to be more certain than its evidence. If the log contains enough information to decide, SessionRx decides. If it contains evidence of a problem, it reports observed. If it ran and found no problem, it reports not-observed. If the required evidence is absent, it says unknown and leaves the verdict unresolved.
That is a small rule, but it changes the character of the tool. It makes the blank space visible. It keeps a lower bound from becoming a percentage. And it makes a clean result something the logs earned rather than something the UI assumed.
SessionRx v0.4.2 is published as session-rx. To try it locally, with Node 22.13 or newer:
npx session-rx
