patch-cc 0.2.3 — repair the 2.1.226 reducer drift
Repairs live-thinking on Claude 2.1.226. On that build the patch was
dropped at bake time, so a patched binary silently lost live thinking. Re-run
patch-cc (or patch-cc apply --from-cache) to get it back.
What broke
2.1.226 threaded a new progress flag through the stream reducer: a second
declarator appended to the head's let (let{...}=t,d=...;) and five arm
bodies rewritten from stmt1,stmt2; into if(stmt1,stmt2,d)call;. The
handler matcher hard-required }=t;, so the reducer was never recognised and
every required step reported nothing — while all four anchor strings sat
healthy in the bundle, which is exactly what the release-watch ledger saw. The
arm rewrites had separately, and silently, killed the message_stop literal
pair.
The fix
The reducer rewrites no longer model anything the minifier owns — the same
doctrine as 0.2.2's ARRAY_CALL repair, applied to control flow:
- The head is bounded at the grammar's declarator edge (
(?=[;,])): after
let{…}=tonly;or,can follow in a minified bundle, and which one is
noise. reducer-destructuredandreducer-innercollapse into one
reducer-optionsstep — the options bag carryingonStreamingThinkingor
not is the same shape with the prop present or absent, reused or threaded on
one code path.- Every arm-body literal (~15 enumerated spellings) is gone. Each state update
is an insertion at the dispatch point: after acaselabel chain, or
wrapping the dispatch test itself as(test&&((update),!0))—
value-preserving, so any surrounding composition survives unread. A
2.1.226-style body reshape is invisible to the patch now. - Each dispatch point is its own named step (
request-start,message-stop,
text-clear,message-delta-clear,thinking-start,thinking-append):
a folded-away arm reads as that point's absence by name, and
live-thinking's counts are uniform across every supported build —
deviation is signal, not noise.
The playbook records the rule: rewrite at the dispatch point; never model
the arm.
Housekeeping: the codebase conforms to ruff 0.16's widened default rule set,
and the lockfile picks up the refreshed dev toolchain.
Verification
doctor green against all ten pristine backups, 2.1.216 → 2.1.226, with
uniform counts on every build; the fully patched 2.1.226 bundle passes
node --check; and the rewritten reducer from every build was executed
against a synthetic stream and passes the state-machine checks — clear on
request start, virtual message on block start, delta accumulation, redacted
data, end timestamp on stop.
No new options; upgrading matters if you are on 2.1.226 or later.
Full changelog: v0.2.2...v0.2.3