Summary
thinking_desync_risk is computed from a hardcoded context-token threshold calibrated against ~200K-window sessions. On a 1M-context session it reports high from roughly a third of the way in and never recovers, so the field stops carrying information exactly where a long session would most want it.
What it actually measures
proxy/extensions/session-health.mjs:66:
export function computeRisk(contextTokens, { warnTokens, highTokens }) {
if (contextTokens >= highTokens) return "high";
if (contextTokens >= warnTokens) return "warn";
return "ok";
}
with (:19-20):
const DEFAULT_WARN_TOKENS = 250_000;
const DEFAULT_HIGH_TOKENS = 340_000; // just under the observed ~382K trip
Two things worth naming:
- Despite the name, it never inspects thinking blocks.
thinking_block_count, thinking_blocks_dropped, and thinking_block_max are all recorded in the same file and none feed the risk value. It is a context-size gauge wearing a desync label.
- The
~382K trip in that comment is an observation from the #63147 thinking-desync era. It was a reasonable proxy when window size and desync exposure correlated. On a 1M window they don't.
Observed
A live session on this host, running claude-opus-5[1m]:
context_tokens: 340344
thinking_desync_risk: "high"
/context for the same session reads 36% of 1M. The field says "high" because 340,344 ≥ 340,000 — it crossed by 344 tokens. Every 1M session will pin high for its entire second half and stay there.
Why it matters
An indicator that is always on is worse than absent: it trains readers to ignore it, and it will be ignored on the one occasion it is right. This is the same failure mode as #282 (upstream-change-detection alarming on routine conversation growth) — a detector whose predicate no longer matches the world it runs in.
Concretely, it cost a false alarm in a working session today: the field was read as a live signal about that session's health when it was reporting nothing but "context is over 340K."
Options
- Scale thresholds to the effective window. Derive from the model's context limit rather than constants —
warn and high as fractions. Keeps the field meaningful on both 200K and 1M sessions. Needs a reliable window size at request time; the context-1m-2025-08-07 beta header is already detected by auto-1m-guard, so the signal exists.
- Suppress the field when the 1M beta header is present. Cheaper and honest — absent beats wrong. Loses the signal on exactly the sessions most likely to be long.
- Rename to match what it measures (
context_size_tier or similar) and let it stay a size gauge. Doesn't fix the 1M calibration, but stops implying a causal link to desync that the code doesn't compute.
Options 1 and 3 are complementary. Recommend 1 + 3 together; 2 is the fallback if window size turns out not to be reliably knowable at that point in the pipeline.
Non-Functional Requirements
- Size/complexity budget — small. Option 1 is a threshold derivation plus its config plumbing; option 3 is a rename plus a back-compat window on the old key if anything consumes it. Expect well under 100 LOC either way.
- Threat model — n/a. Observational field, written to a local session status file; no wire effect, no new inputs.
- Maintainability — no new abstraction warranted. Whatever lands should record why the thresholds are what they are, since the current constants' rationale survived only as a trailing comment that outlived its context.
- Performance/reliability — n/a; one comparison per response.
- Load-bearing? No. The field is reported, never acted on —
computeRisk gates nothing but a log line and a status-file value. Changing it cannot affect request handling.
Note
Not urgent. This is a reporting defect, not a behavioral one — no session is at risk because of it. Filed so the calibration is fixed deliberately rather than rediscovered by someone trusting the field.
— Proxy Builder
Summary
thinking_desync_riskis computed from a hardcoded context-token threshold calibrated against ~200K-window sessions. On a 1M-context session it reportshighfrom roughly a third of the way in and never recovers, so the field stops carrying information exactly where a long session would most want it.What it actually measures
proxy/extensions/session-health.mjs:66:with (
:19-20):Two things worth naming:
thinking_block_count,thinking_blocks_dropped, andthinking_block_maxare all recorded in the same file and none feed the risk value. It is a context-size gauge wearing a desync label.~382K tripin that comment is an observation from the #63147 thinking-desync era. It was a reasonable proxy when window size and desync exposure correlated. On a 1M window they don't.Observed
A live session on this host, running
claude-opus-5[1m]:/contextfor the same session reads 36% of 1M. The field says "high" because 340,344 ≥ 340,000 — it crossed by 344 tokens. Every 1M session will pinhighfor its entire second half and stay there.Why it matters
An indicator that is always on is worse than absent: it trains readers to ignore it, and it will be ignored on the one occasion it is right. This is the same failure mode as #282 (
upstream-change-detectionalarming on routine conversation growth) — a detector whose predicate no longer matches the world it runs in.Concretely, it cost a false alarm in a working session today: the field was read as a live signal about that session's health when it was reporting nothing but "context is over 340K."
Options
warnandhighas fractions. Keeps the field meaningful on both 200K and 1M sessions. Needs a reliable window size at request time; thecontext-1m-2025-08-07beta header is already detected byauto-1m-guard, so the signal exists.context_size_tieror similar) and let it stay a size gauge. Doesn't fix the 1M calibration, but stops implying a causal link to desync that the code doesn't compute.Options 1 and 3 are complementary. Recommend 1 + 3 together; 2 is the fallback if window size turns out not to be reliably knowable at that point in the pipeline.
Non-Functional Requirements
computeRiskgates nothing but a log line and a status-file value. Changing it cannot affect request handling.Note
Not urgent. This is a reporting defect, not a behavioral one — no session is at risk because of it. Filed so the calibration is fixed deliberately rather than rediscovered by someone trusting the field.
— Proxy Builder