Reports · Issue #4441

A later model-capacity update changes the context-ring scale

2026-09-30 · Bug · Low priority · Medium effort

PARTIALLY REPRODUCED · High confidence in the tested normalization, projection and display behavior.

Claim, expected result and observed result

The issue reports a 256K compact-window display changing to 1M during a Claude turn and back afterward. The requested behavior is to retain the applicable compact-window denominator while separately recording model capacity and updating usage.

A synthetic sequence calls the real Claude context-report normalizer and SDK usage extractor, creates context-usage events, and passes them to the real thread projection. An optimized browser fixture renders the actual context ring and card. The first three inputs keep used tokens at 128,000. Both clean runs change the projected denominator and actual displayed ratio from 256,000 / 50% to 1,000,000 / 13%, then back to 256,000 / 50%. The middle update also removes the snapshot from the projected output. The ring SVG offset, accessible label and card text all agree; this is a scale change, not increased token usage.

Synthetic transitionUsed tokensProjected denominatorDisplayed ratioSnapshot retained
Context snapshot, rawMaxTokens 256,000128,000256,00050%; 128k / 256kYes
SDK modelUsage contextWindow 1,000,000128,0001,000,00013%; 128k / 1mNo
Next 256,000 snapshot128,000256,00050%; 128k / 256kYes
Control: usage increases at same capacity160,000256,00063%; 160k / 256kNo
Control: new 512,000 context snapshot128,000512,00025%; 128k / 512kYes
Control: SDK model key changes to Claude Haiku; capacity 200,000128,000200,00064%; 128k / 200kNo

The last control changes synthetic SDK metadata only; it does not perform an actual model switch. Snapshot autoCompactThreshold is deliberately separate: 240,000 for the 256K snapshot and 496,000 for the 512K snapshot. The display uses rawMaxTokens/contextWindowTokens, not that threshold.

Root cause and proposed next change

The real normalizer copies rawMaxTokens to contextWindowTokens and stores autoCompactThreshold separately. The SDK extractor emits a modelContextWindow from model usage, without a snapshot. The projection scans newest events first and resolves both usedTokens and modelContextWindow from the later aggregate update, stopping before the older snapshot. Its snapshot guard cannot retain a snapshot that was never selected. The percentage helper divides usedTokens by modelContextWindow. The card and the ring display that same ratio.

Source inspection also shows post-turn snapshot publication sends snapshot.contextWindowTokens as the context-window size. That lifecycle call was inspected, not executed in this fixture. The test constructs domain events at the boundary; it does not run the bridge transport or server persistence path.

Proposed fix: represent model capacity separately from the applicable display/compact capacity, retain the latter across aggregate usage updates only while its model/session context remains valid, and invalidate or refresh it on model/context-setting changes. Do not retain stale category counts when usage changes. Add transition tests for compact mode enabled/disabled, model changes and fresh snapshots, then exercise a real Claude session to verify metadata origin and ordering. No production fix or PR was created.

Trusted base and environment

Fetched public origin/main: 4195cf56febd44853463cd9eec518a172dd7654a. Linux x86_64, Node 24.19.0, pinned pnpm 9.15.0, Vite 8.0.12 optimized fixture build, desktop headless Chromium 151.0.7922.173 at 1100×800. Two detached clean worktrees at that SHA used separate node_modules, local install caches, browser profiles and loopback ports. Dependency downloads were shared. Both frozen installs, upstream builds, synthetic generators and fixture builds succeeded. No added dependency.

Exact repeatable steps

Use Node 24.19.0, pnpm 9.15.0 and a locally installed Chromium. Save capture.mjs below outside the checkout. In each clean checkout save the four source files below under apps/app/issue4441/. Do not copy generated steps.json or dist between runs. Commands below preserve the executed flags with local scratch paths normalized. The source export condition is required for the repository SDK imports. Use separate terminals for the loopback server and browser, then run the capture command. Stop only those test processes afterward.

WORK=$(mktemp -d)
git clone https://github.com/get-bb/bb.git "$WORK/base"
git -C "$WORK/base" worktree add --detach "$WORK/first" 4195cf56febd44853463cd9eec518a172dd7654a
git -C "$WORK/base" worktree add --detach "$WORK/second" 4195cf56febd44853463cd9eec518a172dd7654a
# Save the four source files separately in first and second; capture.mjs in WORK.
cd "$WORK/first"
npm_config_cache="$WORK/npm-first" npm_config_devdir="$WORK/node-gyp-first" XDG_CACHE_HOME="$WORK/cache-first" pnpm install --frozen-lockfile --store-dir "$WORK/dependency-store"
pnpm exec turbo run build --filter=@bb/app
cd apps/app
NODE_OPTIONS=--conditions=source pnpm exec tsx issue4441/generate.ts
pnpm exec vite build --config issue4441/vite.config.ts
python -m http.server 49341 --bind 127.0.0.1 --directory "$WORK/first/apps/app/issue4441/dist"
chromium --headless --no-sandbox --disable-gpu --no-first-run --disable-dev-shm-usage --remote-debugging-address=127.0.0.1 --remote-debugging-port=49342 --user-data-dir="$WORK/browser-first" about:blank
node "$WORK/capture.mjs" 49342 49341 "$WORK/browser-first"
# Second clean reproduction, performed by the same agent:
cd "$WORK/second"
npm_config_cache="$WORK/npm-second" npm_config_devdir="$WORK/node-gyp-second" XDG_CACHE_HOME="$WORK/cache-second" pnpm install --frozen-lockfile --store-dir "$WORK/dependency-store"
pnpm exec turbo run build --filter=@bb/app
cd apps/app
NODE_OPTIONS=--conditions=source pnpm exec tsx issue4441/generate.ts
pnpm exec vite build --config issue4441/vite.config.ts
python -m http.server 49343 --bind 127.0.0.1 --directory "$WORK/second/apps/app/issue4441/dist"
chromium --headless --no-sandbox --disable-gpu --no-first-run --disable-dev-shm-usage --remote-debugging-address=127.0.0.1 --remote-debugging-port=49344 --user-data-dir="$WORK/browser-second" about:blank
node "$WORK/capture.mjs" 49344 49343 "$WORK/browser-second"

apps/app/issue4441/index.html

<html><head><title>Synthetic context transitions</title></head><body><div id="root"></div><script type="module" src="/main.tsx"></script></body></html>

apps/app/issue4441/generate.ts

import { writeFileSync } from "node:fs";
import assert from "node:assert/strict";
import { normalizeClaudeContextUsage } from "../../../plugins/provider-claude-code/src/bridge/context-usage";
import { extractClaudeContextWindowUsage } from "../../../plugins/provider-claude-code/src/sdk-extraction";
import { extractThreadContextWindowUsage } from "../../../packages/thread-view/src/thread-context-window-usage";
import { threadScope } from "@bb/domain";
const metadata = {capturedAt:"2026-09-30T00:00:00.000Z",providerSessionId:"synthetic-session",providerTurnId:null};
const snapshot = (capacity:number, used=128000) => normalizeClaudeContextUsage({categories:[{name:"Messages",tokens:used}],totalTokens:used,rawMaxTokens:capacity,model:"claude-sonnet-4-6",isAutoCompactEnabled:true,autoCompactThreshold:capacity-16000},metadata);
const streamed = (capacity:number,used=128000,model="claude-sonnet-4-6") => extractClaudeContextWindowUsage({fallbackModelContextWindow:256000,latestRequestContextTokens:used,message:{modelUsage:{[model]:{contextWindow:capacity}}} as never});
const fromSnapshot = (capacity:number,used=128000) => {const s=snapshot(capacity,used);return {snapshot:s,usedTokens:s.usedTokens,modelContextWindow:s.contextWindowTokens,estimated:true};};
const event = (seq:number,contextWindowUsage:any) => ({meta:{seq,id:`synthetic-event-${seq}`,createdAt:Date.parse(metadata.capturedAt)},event:{type:"thread/contextWindowUsage/updated",threadId:"synthetic-thread",providerThreadId:"synthetic-session",scope:threadScope(),contextWindowUsage}} as const);
const signals = [fromSnapshot(256000),streamed(1000000),fromSnapshot(256000),streamed(256000,160000),fromSnapshot(512000),streamed(200000,128000,"claude-haiku-4-5")];
const labels = ["Compact snapshot","Streamed model capacity","Next compact snapshot","Control: increased usage, same capacity","Control: new compact capacity","Control: model capacity transition"];
const steps = signals.map((input,index)=>({label:labels[index],input,usage:extractThreadContextWindowUsage(signals.slice(0,index+1).map((s,i)=>event(i+1,s)))}));
assert.deepEqual(steps.map(s=>s.usage?.modelContextWindow),[256000,1000000,256000,256000,512000,200000]);
assert.deepEqual(steps.map(s=>s.usage?.usedTokens),[128000,128000,128000,160000,128000,128000]);
assert.deepEqual(steps.map(s=>Boolean(s.usage?.snapshot)),[true,false,true,false,true,false]);
writeFileSync(new URL("steps.json",import.meta.url),JSON.stringify(steps,null,2));
console.log(JSON.stringify({checks:"PASS",steps},null,2));

apps/app/issue4441/main.tsx

import React, {useState} from "react";
import {createRoot} from "react-dom/client";
import {ThreadContextWindowCard,ThreadContextWindowIndicator} from "../src/components/thread/timeline/ThreadContextWindowIndicator";
import {calculateContextWindowUsagePercent} from "../src/components/thread/timeline/thread-context-window-usage";
import "../src/app.css";
import steps from "./steps.json";
function App(){const [index,setIndex]=useState(0);const step=steps[index];const usage=step.usage!;return <main style={{padding:40,maxWidth:900}}><h1>Synthetic context-window transitions</h1><p>Actual provider normalization, event projection and context components. No model service or full thread controller.</p><nav style={{display:"flex",gap:12,margin:"24px 0"}}>{steps.map((s,i)=><button key={s.label} data-step={i} onClick={()=>setIndex(i)}>Step {i+1}</button>)}</nav><h2 id="stage">{step.label}</h2><div id="indicator" style={{margin:"20px 0"}}><ThreadContextWindowIndicator usage={usage}/></div><div id="card"><ThreadContextWindowCard usage={usage}/></div><pre id="metadata" style={{marginTop:24}}>{JSON.stringify({step:index+1,usedTokens:usage.usedTokens,modelContextWindow:usage.modelContextWindow,percent:calculateContextWindowUsagePercent(usage),hasSnapshot:Boolean(usage.snapshot),autoCompactAtTokens:usage.snapshot?.autoCompactAtTokens??null},null,2)}</pre></main>};
createRoot(document.getElementById("root")!).render(<App/>);

apps/app/issue4441/vite.config.ts

import { defineConfig } from "vite";
import { sharedViteConfig } from "../vite.config";
export default defineConfig({ ...sharedViteConfig, root: __dirname, plugins: sharedViteConfig.plugins.filter(plugin => !["bb:font-preload", "bb:split-prefetch"].includes(plugin.name)), build: { ...sharedViteConfig.build, outDir: "dist", emptyOutDir: true } });

capture.mjs

import { writeFile } from 'node:fs/promises';
const [debugPort,appPort,output]=process.argv.slice(2);
const tabs=await(await fetch(`http://127.0.0.1:${debugPort}/json/list`)).json();
const ws=new WebSocket(tabs.find(t=>t.type==='page').webSocketDebuggerUrl);
await new Promise(r=>ws.addEventListener('open',r,{once:true}));let id=0;const pending=new Map();
ws.addEventListener('message',event=>{const x=JSON.parse(event.data);if(x.id){const p=pending.get(x.id);pending.delete(x.id);x.error?p.reject(new Error(JSON.stringify(x.error))):p.resolve(x.result);}});
const call=(method,params={})=>new Promise((resolve,reject)=>{const serial=++id;pending.set(serial,{resolve,reject});ws.send(JSON.stringify({id:serial,method,params}));});
const evaluate=async expression=>{const x=await call('Runtime.evaluate',{expression,returnByValue:true,awaitPromise:true});if(x.exceptionDetails)throw new Error(JSON.stringify(x.exceptionDetails));return x.result.value;};
await call('Page.enable');await call('Runtime.enable');await call('Network.enable');await call('Network.setCacheDisabled',{cacheDisabled:true});
await call('Emulation.setDeviceMetricsOverride',{width:1100,height:800,deviceScaleFactor:1,mobile:false});
const errors=[];
ws.addEventListener('message',event=>{const x=JSON.parse(event.data);if(x.method==='Runtime.exceptionThrown')errors.push(x.params.exceptionDetails.text+': '+(x.params.exceptionDetails.exception?.description??''));});
await call('Page.navigate',{url:`http://127.0.0.1:${appPort}/`});
await new Promise(r=>setTimeout(r,2500));
const observations=[];
for(let step=0;step<6;step++){
 await evaluate(`document.querySelector('[data-step="${step}"]').click()`);
 await new Promise(r=>setTimeout(r,300));
 const observed=await evaluate(`({stage:document.getElementById('stage').textContent,metadata:JSON.parse(document.getElementById('metadata').textContent),card:document.getElementById('card').innerText,aria:document.querySelector('#indicator button').getAttribute('aria-label'),dashOffset:Number(document.querySelectorAll('#indicator circle')[1].getAttribute('stroke-dashoffset'))})`);
 const percent=[50,13,50,63,25,64][step];
 if(observed.metadata.percent!==percent||observed.aria!==`Context window ${percent}% used`||!observed.card.includes(`${percent}% used`))throw new Error(JSON.stringify(observed));
 if(Math.abs(observed.dashOffset-2*Math.PI*6.5*(1-percent/100))>0.00001)throw new Error('Ring offset mismatch');
 observations.push(observed);
 if(step<3){const shot=await call('Page.captureScreenshot',{format:'png',captureBeyondViewport:false});await writeFile(`${output}-step${step+1}.png`,Buffer.from(shot.data,'base64'));}
}
if(errors.length)throw new Error(JSON.stringify(errors));
const result={observations,stableCompactDenominator:observations.slice(0,3).every(x=>x.metadata.modelContextWindow===256000),browser:await call('Browser.getVersion'),viewport:{width:1100,height:800},errors};
await writeFile(output+'.json',JSON.stringify(result,null,2));console.log(JSON.stringify(result));ws.close();

Same-agent second clean reproduction: actual evidence

The same agent personally repeated the generator and browser capture in the second checkout. Both generator runs exited 0 and produced byte-identical steps.json. Each browser run exited 0 after checking all six percentages, accessible labels, card text and SVG ring offsets. Both report stableCompactDenominator: false and no runtime exceptions. All three corresponding screenshots are byte-identical between runs; each file was inspected. This is a same-agent second clean reproduction, not independent verification.

The PASS checks assert the observed implementation behavior, including the denominator change. They do not mean the requested stable-denominator expectation passed: it failed in both runs. A preliminary generator launch exposed an incorrect fixture-relative import and then the missing SDK source export condition; both were corrected before the retained complete runs. Production code was unchanged.

first generator output

{
  "checks": "PASS",
  "steps": [
    {
      "label": "Compact snapshot",
      "input": {
        "snapshot": {
          "capturedAt": "2026-09-30T00:00:00.000Z",
          "providerSessionId": "synthetic-session",
          "providerTurnId": null,
          "model": "claude-sonnet-4-6",
          "usedTokens": 128000,
          "contextWindowTokens": 256000,
          "autoCompactAtTokens": 240000,
          "estimated": true,
          "categories": [
            {
              "id": "[\"claude\",\"Messages\",0]",
              "label": "Messages",
              "kind": "used",
              "tokens": 128000,
              "entries": []
            }
          ]
        },
        "usedTokens": 128000,
        "modelContextWindow": 256000,
        "estimated": true
      },
      "usage": {
        "snapshot": {
          "capturedAt": "2026-09-30T00:00:00.000Z",
          "providerSessionId": "synthetic-session",
          "providerTurnId": null,
          "model": "claude-sonnet-4-6",
          "usedTokens": 128000,
          "contextWindowTokens": 256000,
          "autoCompactAtTokens": 240000,
          "estimated": true,
          "categories": [
            {
              "id": "[\"claude\",\"Messages\",0]",
              "label": "Messages",
              "kind": "used",
              "tokens": 128000,
              "entries": []
            }
          ]
        },
        "estimated": true,
        "modelContextWindow": 256000,
        "usedTokens": 128000
      }
    },
    {
      "label": "Streamed model capacity",
      "input": {
        "usedTokens": 128000,
        "modelContextWindow": 1000000,
        "estimated": true
      },
      "usage": {
        "estimated": true,
        "modelContextWindow": 1000000,
        "usedTokens": 128000
      }
    },
    {
      "label": "Next compact snapshot",
      "input": {
        "snapshot": {
          "capturedAt": "2026-09-30T00:00:00.000Z",
          "providerSessionId": "synthetic-session",
          "providerTurnId": null,
          "model": "claude-sonnet-4-6",
          "usedTokens": 128000,
          "contextWindowTokens": 256000,
          "autoCompactAtTokens": 240000,
          "estimated": true,
          "categories": [
            {
              "id": "[\"claude\",\"Messages\",0]",
              "label": "Messages",
              "kind": "used",
              "tokens": 128000,
              "entries": []
            }
          ]
        },
        "usedTokens": 128000,
        "modelContextWindow": 256000,
        "estimated": true
      },
      "usage": {
        "snapshot": {
          "capturedAt": "2026-09-30T00:00:00.000Z",
          "providerSessionId": "synthetic-session",
          "providerTurnId": null,
          "model": "claude-sonnet-4-6",
          "usedTokens": 128000,
          "contextWindowTokens": 256000,
          "autoCompactAtTokens": 240000,
          "estimated": true,
          "categories": [
            {
              "id": "[\"claude\",\"Messages\",0]",
              "label": "Messages",
              "kind": "used",
              "tokens": 128000,
              "entries": []
            }
          ]
        },
        "estimated": true,
        "modelContextWindow": 256000,
        "usedTokens": 128000
      }
    },
    {
      "label": "Control: increased usage, same capacity",
      "input": {
        "usedTokens": 160000,
        "modelContextWindow": 256000,
        "estimated": true
      },
      "usage": {
        "estimated": true,
        "modelContextWindow": 256000,
        "usedTokens": 160000
      }
    },
    {
      "label": "Control: new compact capacity",
      "input": {
        "snapshot": {
          "capturedAt": "2026-09-30T00:00:00.000Z",
          "providerSessionId": "synthetic-session",
          "providerTurnId": null,
          "model": "claude-sonnet-4-6",
          "usedTokens": 128000,
          "contextWindowTokens": 512000,
          "autoCompactAtTokens": 496000,
          "estimated": true,
          "categories": [
            {
              "id": "[\"claude\",\"Messages\",0]",
              "label": "Messages",
              "kind": "used",
              "tokens": 128000,
              "entries": []
            }
          ]
        },
        "usedTokens": 128000,
        "modelContextWindow": 512000,
        "estimated": true
      },
      "usage": {
        "snapshot": {
          "capturedAt": "2026-09-30T00:00:00.000Z",
          "providerSessionId": "synthetic-session",
          "providerTurnId": null,
          "model": "claude-sonnet-4-6",
          "usedTokens": 128000,
          "contextWindowTokens": 512000,
          "autoCompactAtTokens": 496000,
          "estimated": true,
          "categories": [
            {
              "id": "[\"claude\",\"Messages\",0]",
              "label": "Messages",
              "kind": "used",
              "tokens": 128000,
              "entries": []
            }
          ]
        },
        "estimated": true,
        "modelContextWindow": 512000,
        "usedTokens": 128000
      }
    },
    {
      "label": "Control: model capacity transition",
      "input": {
        "usedTokens": 128000,
        "modelContextWindow": 200000,
        "estimated": true
      },
      "usage": {
        "estimated": true,
        "modelContextWindow": 200000,
        "usedTokens": 128000
      }
    }
  ]
}

first browser observations

{
  "observations": [
    {
      "stage": "Compact snapshot",
      "metadata": {
        "step": 1,
        "usedTokens": 128000,
        "modelContextWindow": 256000,
        "percent": 50,
        "hasSnapshot": true,
        "autoCompactAtTokens": 240000
      },
      "card": "Estimated context\n50% used\n128k / 256k tokens\n50% left\nIn context\nMessages\n128,000\n50.0%\nShow details",
      "aria": "Context window 50% used",
      "dashOffset": 20.420352248333657
    },
    {
      "stage": "Streamed model capacity",
      "metadata": {
        "step": 2,
        "usedTokens": 128000,
        "modelContextWindow": 1000000,
        "percent": 13,
        "hasSnapshot": false,
        "autoCompactAtTokens": null
      },
      "card": "Estimated context\n13% used\n128k / 1m tokens\n87% left",
      "aria": "Context window 13% used",
      "dashOffset": 35.53141291210056
    },
    {
      "stage": "Next compact snapshot",
      "metadata": {
        "step": 3,
        "usedTokens": 128000,
        "modelContextWindow": 256000,
        "percent": 50,
        "hasSnapshot": true,
        "autoCompactAtTokens": 240000
      },
      "card": "Estimated context\n50% used\n128k / 256k tokens\n50% left\nIn context\nMessages\n128,000\n50.0%\nShow details",
      "aria": "Context window 50% used",
      "dashOffset": 20.420352248333657
    },
    {
      "stage": "Control: increased usage, same capacity",
      "metadata": {
        "step": 4,
        "usedTokens": 160000,
        "modelContextWindow": 256000,
        "percent": 63,
        "hasSnapshot": false,
        "autoCompactAtTokens": null
      },
      "card": "Estimated context\n63% used\n160k / 256k tokens\n37% left",
      "aria": "Context window 63% used",
      "dashOffset": 15.111060663766906
    },
    {
      "stage": "Control: new compact capacity",
      "metadata": {
        "step": 5,
        "usedTokens": 128000,
        "modelContextWindow": 512000,
        "percent": 25,
        "hasSnapshot": true,
        "autoCompactAtTokens": 496000
      },
      "card": "Estimated context\n25% used\n128k / 512k tokens\n75% left\nIn context\nMessages\n128,000\n25.0%\nShow details",
      "aria": "Context window 25% used",
      "dashOffset": 30.630528372500486
    },
    {
      "stage": "Control: model capacity transition",
      "metadata": {
        "step": 6,
        "usedTokens": 128000,
        "modelContextWindow": 200000,
        "percent": 64,
        "hasSnapshot": false,
        "autoCompactAtTokens": null
      },
      "card": "Estimated context\n64% used\n128k / 200k tokens\n36% left",
      "aria": "Context window 64% used",
      "dashOffset": 14.702653618800232
    }
  ],
  "stableCompactDenominator": false,
  "browser": {
    "protocolVersion": "1.3",
    "product": "Chrome/151.0.7922.173",
    "revision": "@a96602f30358e9b5d256a0464e7e4d4bec223004",
    "userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/151.0.0.0 Safari/537.36",
    "jsVersion": "15.1.206.23"
  },
  "viewport": {
    "width": 1100,
    "height": 800
  },
  "errors": []
}

first, transition 1

Actual first Chromium capture, transition 1: context ring and token label

first, transition 2

Actual first Chromium capture, transition 2: context ring and token label

first, transition 3

Actual first Chromium capture, transition 3: context ring and token label

second generator output

{
  "checks": "PASS",
  "steps": [
    {
      "label": "Compact snapshot",
      "input": {
        "snapshot": {
          "capturedAt": "2026-09-30T00:00:00.000Z",
          "providerSessionId": "synthetic-session",
          "providerTurnId": null,
          "model": "claude-sonnet-4-6",
          "usedTokens": 128000,
          "contextWindowTokens": 256000,
          "autoCompactAtTokens": 240000,
          "estimated": true,
          "categories": [
            {
              "id": "[\"claude\",\"Messages\",0]",
              "label": "Messages",
              "kind": "used",
              "tokens": 128000,
              "entries": []
            }
          ]
        },
        "usedTokens": 128000,
        "modelContextWindow": 256000,
        "estimated": true
      },
      "usage": {
        "snapshot": {
          "capturedAt": "2026-09-30T00:00:00.000Z",
          "providerSessionId": "synthetic-session",
          "providerTurnId": null,
          "model": "claude-sonnet-4-6",
          "usedTokens": 128000,
          "contextWindowTokens": 256000,
          "autoCompactAtTokens": 240000,
          "estimated": true,
          "categories": [
            {
              "id": "[\"claude\",\"Messages\",0]",
              "label": "Messages",
              "kind": "used",
              "tokens": 128000,
              "entries": []
            }
          ]
        },
        "estimated": true,
        "modelContextWindow": 256000,
        "usedTokens": 128000
      }
    },
    {
      "label": "Streamed model capacity",
      "input": {
        "usedTokens": 128000,
        "modelContextWindow": 1000000,
        "estimated": true
      },
      "usage": {
        "estimated": true,
        "modelContextWindow": 1000000,
        "usedTokens": 128000
      }
    },
    {
      "label": "Next compact snapshot",
      "input": {
        "snapshot": {
          "capturedAt": "2026-09-30T00:00:00.000Z",
          "providerSessionId": "synthetic-session",
          "providerTurnId": null,
          "model": "claude-sonnet-4-6",
          "usedTokens": 128000,
          "contextWindowTokens": 256000,
          "autoCompactAtTokens": 240000,
          "estimated": true,
          "categories": [
            {
              "id": "[\"claude\",\"Messages\",0]",
              "label": "Messages",
              "kind": "used",
              "tokens": 128000,
              "entries": []
            }
          ]
        },
        "usedTokens": 128000,
        "modelContextWindow": 256000,
        "estimated": true
      },
      "usage": {
        "snapshot": {
          "capturedAt": "2026-09-30T00:00:00.000Z",
          "providerSessionId": "synthetic-session",
          "providerTurnId": null,
          "model": "claude-sonnet-4-6",
          "usedTokens": 128000,
          "contextWindowTokens": 256000,
          "autoCompactAtTokens": 240000,
          "estimated": true,
          "categories": [
            {
              "id": "[\"claude\",\"Messages\",0]",
              "label": "Messages",
              "kind": "used",
              "tokens": 128000,
              "entries": []
            }
          ]
        },
        "estimated": true,
        "modelContextWindow": 256000,
        "usedTokens": 128000
      }
    },
    {
      "label": "Control: increased usage, same capacity",
      "input": {
        "usedTokens": 160000,
        "modelContextWindow": 256000,
        "estimated": true
      },
      "usage": {
        "estimated": true,
        "modelContextWindow": 256000,
        "usedTokens": 160000
      }
    },
    {
      "label": "Control: new compact capacity",
      "input": {
        "snapshot": {
          "capturedAt": "2026-09-30T00:00:00.000Z",
          "providerSessionId": "synthetic-session",
          "providerTurnId": null,
          "model": "claude-sonnet-4-6",
          "usedTokens": 128000,
          "contextWindowTokens": 512000,
          "autoCompactAtTokens": 496000,
          "estimated": true,
          "categories": [
            {
              "id": "[\"claude\",\"Messages\",0]",
              "label": "Messages",
              "kind": "used",
              "tokens": 128000,
              "entries": []
            }
          ]
        },
        "usedTokens": 128000,
        "modelContextWindow": 512000,
        "estimated": true
      },
      "usage": {
        "snapshot": {
          "capturedAt": "2026-09-30T00:00:00.000Z",
          "providerSessionId": "synthetic-session",
          "providerTurnId": null,
          "model": "claude-sonnet-4-6",
          "usedTokens": 128000,
          "contextWindowTokens": 512000,
          "autoCompactAtTokens": 496000,
          "estimated": true,
          "categories": [
            {
              "id": "[\"claude\",\"Messages\",0]",
              "label": "Messages",
              "kind": "used",
              "tokens": 128000,
              "entries": []
            }
          ]
        },
        "estimated": true,
        "modelContextWindow": 512000,
        "usedTokens": 128000
      }
    },
    {
      "label": "Control: model capacity transition",
      "input": {
        "usedTokens": 128000,
        "modelContextWindow": 200000,
        "estimated": true
      },
      "usage": {
        "estimated": true,
        "modelContextWindow": 200000,
        "usedTokens": 128000
      }
    }
  ]
}

second browser observations

{
  "observations": [
    {
      "stage": "Compact snapshot",
      "metadata": {
        "step": 1,
        "usedTokens": 128000,
        "modelContextWindow": 256000,
        "percent": 50,
        "hasSnapshot": true,
        "autoCompactAtTokens": 240000
      },
      "card": "Estimated context\n50% used\n128k / 256k tokens\n50% left\nIn context\nMessages\n128,000\n50.0%\nShow details",
      "aria": "Context window 50% used",
      "dashOffset": 20.420352248333657
    },
    {
      "stage": "Streamed model capacity",
      "metadata": {
        "step": 2,
        "usedTokens": 128000,
        "modelContextWindow": 1000000,
        "percent": 13,
        "hasSnapshot": false,
        "autoCompactAtTokens": null
      },
      "card": "Estimated context\n13% used\n128k / 1m tokens\n87% left",
      "aria": "Context window 13% used",
      "dashOffset": 35.53141291210056
    },
    {
      "stage": "Next compact snapshot",
      "metadata": {
        "step": 3,
        "usedTokens": 128000,
        "modelContextWindow": 256000,
        "percent": 50,
        "hasSnapshot": true,
        "autoCompactAtTokens": 240000
      },
      "card": "Estimated context\n50% used\n128k / 256k tokens\n50% left\nIn context\nMessages\n128,000\n50.0%\nShow details",
      "aria": "Context window 50% used",
      "dashOffset": 20.420352248333657
    },
    {
      "stage": "Control: increased usage, same capacity",
      "metadata": {
        "step": 4,
        "usedTokens": 160000,
        "modelContextWindow": 256000,
        "percent": 63,
        "hasSnapshot": false,
        "autoCompactAtTokens": null
      },
      "card": "Estimated context\n63% used\n160k / 256k tokens\n37% left",
      "aria": "Context window 63% used",
      "dashOffset": 15.111060663766906
    },
    {
      "stage": "Control: new compact capacity",
      "metadata": {
        "step": 5,
        "usedTokens": 128000,
        "modelContextWindow": 512000,
        "percent": 25,
        "hasSnapshot": true,
        "autoCompactAtTokens": 496000
      },
      "card": "Estimated context\n25% used\n128k / 512k tokens\n75% left\nIn context\nMessages\n128,000\n25.0%\nShow details",
      "aria": "Context window 25% used",
      "dashOffset": 30.630528372500486
    },
    {
      "stage": "Control: model capacity transition",
      "metadata": {
        "step": 6,
        "usedTokens": 128000,
        "modelContextWindow": 200000,
        "percent": 64,
        "hasSnapshot": false,
        "autoCompactAtTokens": null
      },
      "card": "Estimated context\n64% used\n128k / 200k tokens\n36% left",
      "aria": "Context window 64% used",
      "dashOffset": 14.702653618800232
    }
  ],
  "stableCompactDenominator": false,
  "browser": {
    "protocolVersion": "1.3",
    "product": "Chrome/151.0.7922.173",
    "revision": "@a96602f30358e9b5d256a0464e7e4d4bec223004",
    "userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/151.0.0.0 Safari/537.36",
    "jsVersion": "15.1.206.23"
  },
  "viewport": {
    "width": 1100,
    "height": 800
  },
  "errors": []
}

second, transition 1

Actual second Chromium capture, transition 1: context ring and token label

second, transition 2

Actual second Chromium capture, transition 2: context ring and token label

second, transition 3

Actual second Chromium capture, transition 3: context ring and token label

Limits and trust boundary

No Claude CLI/model request, actual autoCompactWindow configuration, native desktop app, real provider session, network transport, server event persistence, or full thread controller was exercised. The fixture supplies synthetic rawMaxTokens and modelUsage values derived from the trusted schemas. It establishes what bb does when those values arrive; it does not prove that a currently installed Claude version produces those values or that their real timing matches the reported turn lifecycle. Hence the overall verdict is partial, not a fully verified live-provider reproduction.

Issue narrative, command examples and source links were treated only as untrusted claims. No embedded command or code was executed, and no issue-provided URL or branch was fetched. Tests were derived from trusted fetched source. All thread/session identifiers and context content in this report are synthetic. No real user runtime, account data or credentials were accessed.