Context ring gives no usable warning before auto-compact

Status Open
Reported on v2.1.138
Maintainer reply None cached
Activity 0 comments · opened Sep 1, 2026

Environment

  • Claude Desktop app: 1.40609.0 (macOS 26.5.1, Apple Silicon)
  • Claude Code engine (CLI): 2.1.138
  • Model: Opus 5, 1M context window
  • Date observed: 2026-09-01

What changed for me

In an earlier build the context ring in the composer chin started turning yellow at
roughly 60%
and went red well before the end, which was enough lead time to wrap up
or compact deliberately.

Now there is effectively no warning left: the ring stays in its neutral colour, and the
first thing I notice is that the session is full and auto-compacts. From a handling
point of view that is a real regression — compaction is disruptive, and the whole point
of the ring is to see it coming.

What I found in the shipped bundle

Three things combine into "no warning":

1. The thresholds sit late. In
Contents/Resources/ion-dist/assets/v1/shared-10-3-tqq7pk.js:

function Wx(e) { return e >= 90 ? "critical" : e >= 75 ? "warning" : "normal" }

So the ring is neutral all the way to 75%, and red only from 90%. On a 1M window that
means the entire warning band is the last 250k tokens, and the red band is the last
100k — which a single large tool result can cross in one turn. The percentage
thresholds are constant, but the token cost per turn is not, so the bigger the window,
the less lead time the same percentages actually buy.

2. The ring measures against the wrong number. It is drawn from
rawMaxTokens (the full window), while compaction fires at auto_compact_window,
which arrives separately in the model-selector config
(autoCompactWindow: e?.auto_compact_window). Nothing reconciles the two. If that
window is below 90% of the context window, the session compacts before the ring can
ever turn red — the user sees neutral, then compaction.

3. The secondary warning is gated. The one remaining pre-compact hint is the stale
session compact band (c11959232-DM8o5ho4.js):

XT = { minAgeMinutes: 70, minContextPct: 75 }

behind the feature gate epitaxy_stale_session_compact_band, so it is not guaranteed
to be on for a given user, and it is also keyed to session age, not to how close the
compaction actually is.

Expected

The ring should be a usable early-warning indicator again:

  • Colour the ring against the threshold that actually matters — the auto-compact

window — not against the raw context window.

  • Start the warning band earlier (the previous behaviour, warning from ~60%, gave far

more usable lead time on a large window).

  • Make the "compaction is close" signal independent of the gated, age-based band.

Secondary bug found while investigating

Once the counted context exceeds the window, the ring does not stay full — it snaps
to completely empty in the neutral colour, i.e. it reads as a fresh session. The
percentage also disappears from the popover, leaving only a bare token count.

tI() in shared-10-3-tqq7pk.js returns contextPct: null on overflow instead of
clamping:

function tI(e, t, n = !1) {
  if (null === t || (e > t && !n))
    return { summary: Vx(e), contextPct: null };   // <-- overflow bails out
  ...
}

and the ring trigger in ca80fca8d-DkeN2GSR.js substitutes 0 with no clamp to 100:

const V = H ? (F ?? 0) : (h.peak ?? 0);

contextPct: nullpct: 0 → full strokeDashoffset → nothing drawn, and Wx(0)
classifies it as normal. Clamping to 100 (and forcing critical) would fix it. The
ring's aria-label is built from the same summary, so screen-reader users lose the
percentage in the same situation.

View original on GitHub ↗