chore(compat): finish the Claude Code 2.1.220 pin — live recipe re-verification on the dev host + two stale ReadChat assertions (pin itself already landed in 52a9176) #235
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Cloonar/coding-lab#235
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Goal
Close out the Claude Code 2.1.220 pin by doing the one thing the bump shipped without: run the live recipe suite against the real 2.1.220 binary, and fix the two test assertions that fail before it can tell you anything.
internal/compat/compat.md:43-45states the debt in its own words:and
compat.md:71-77:So the shipped pin is verified statically (bundle strings, CLI probes) but the tmux keystroke recipes — the most fragile couplings in the record — are still pinned to evidence from 2.1.198/2.1.206.
Already done, do not redo
containers/agent-tools/versions.env:20-21—CLAUDE_CODE_VERSION=2.1.220,CLAUDE_CODE_SHA256_X64_MUSL=f1c20514a3571cdf9982e25c490042d740ed7cfed3f00c64ba92dc7ec47c3c5b. Landed.internal/compat/compat.md:3— pin header reads Claude Code 2.1.220, with the 2026-07-28 static re-verification note (§1 spawn flags, §3/§3a auth + config dir, §10 slash-command rows, and the §2/§4/§5/§9/§11/§12 static markers) recorded atcompat.md:43-77. Landed.@anthropic-ai/claude-codedist-tags:latest=2.1.220(published 2026-07-24),stable=2.1.212. There is nothing newer to chase; do not open the pin again as part of this.Work item 1 — fix the two stale live-recipe assertions (pre-existing bug, not 2.1.220 drift)
Both tests still end by asserting a resolved dialog surfaces as a tool chip:
internal/compat/live_recipes_test.go:286(inTestCompat_Live_askUserQuestionRecipe):internal/compat/live_recipes_test.go:344(inTestCompat_Live_exitPlanModeApproval):Issue #56 changed resolved dialogs to stay dialog messages carrying their recorded outcome ("never a demoted tool chip",
dialogoutcome.go). These assertions were never re-run live afterwards, so they fail identically on the old 2.1.198 pin — this is not version drift. Everything earlier in both tests (recipe driving, recorded-answer comparison) is correct and must not be weakened.Fix: assert a dialog message whose recorded outcome carries the answers —
"Blue"for the single-question case,"Apple, Cherry"order-insensitively for the multi-select — and plan-approval forExitPlanMode.Work item 2 — run the live suite on 2.1.220 and record what it finds
Needs the dev host: tmux plus a logged-in
claude2.1.220 on PATH (the tests carry their own skip-gates and will quietly skip otherwise — a skipped run is not a pass; confirm the tests actually executed).Then update
internal/compat/compat.mdto match what was observed: re-date the per-section provenance for every section the live run covers, and replace the "NOT yet re-verified on 2.1.220" bullet atcompat.md:71-77with the outcome.One drift is expected and is the main thing to confirm or refute. The original issue body reported that on 2.1.220 a session spawned without
--remote-controlno longer flushes a pending dialogtool_useto the transcript JSONL — 2.1.220 defers to flush-on-resolve on both spawn arms, where 2.1.198 flushed immediately on the non-remote arm. §12 (compat.md:1186) still carries its original heading,## 12. Spawning WITHOUT --remote-control — live (2.1.206, 2026-07-14), so this rewrite has not happened. If the live run confirms the reversal:pendingDialog's suppression rule (a spooledtool_use_idalready present in the transcript means answered) already models flush-on-resolve. If you find yourself editing the port, that is a finding: report it here rather than expanding scope.If the live run refutes the reversal, say so and leave §12 as it stands. Either outcome closes this issue; an unverified rewrite does not.
Incidental 2.1.220 notes still owed to the compat record
From the original investigation, to be folded into the relevant sections if the live run corroborates them:
--permission-moderenamesdefault→manual. Lab pinsauto; unaffected.--forward-subagent-textflag; unused by lab.mode,permission-mode,file-history-snapshot,attachment,ai-title,last-prompt— ignored gracefully byParseTranscript.prompt_idandpermission_mode; both ignored.CLAUDE_CODE_CHILD_SESSIONenv var disables transcript saving. Inert for lab spawns (we do not set it), but footnote-worthy given the transcript is lab's whole chat surface.Done means
LAB_COMPAT_LIVE=1against a real 2.1.220 binary.-run Live) is confirmed to have executed, not skipped, and passes.internal/compat/compat.mdper-section provenance re-dated to the live 2.1.220 run; the "NOT yet re-verified" bullet atcompat.md:71-77replaced by the outcome.go test ./...green hermetically, with no fixture changes (none are expected).golangci-lint runclean.Closes #235.Out of scope
versions.envpin and its sha256 — already landed; do not touch.bridgeSessionIdunder--remote-control, async-marker live roundtrip, and live commit-flow attribution — the four deferrals from the original spec. Still deferred; not gates for closing this.Agent Brief
Category: enhancement
Summary: Move the agent-tools Claude Code pin from 2.1.198 to 2.1.220 (compat re-verification already done, recorded in the issue body) and repair the two stale live-recipe test assertions that re-verification exposed.
Current behavior:
The agent-tools version catalog (
versions.envin the agent-tools container directory) pins Claude Code 2.1.198. The Claude Code compat record (the compat markdown in the compat package) documents 2.1.198-era behavior, including the claim that a session spawned without--remote-controlwrites a pending dialogtool_useto the transcript JSONL immediately. The two opt-in live recipe tests (TestCompat_Live_askUserQuestionRecipe,TestCompat_Live_exitPlanModeApproval, gated byLAB_COMPAT_LIVE=1) end by asserting that the provider'sReadChatsurfaces a resolved dialog as a tool chip (a message withTool.NameofAskUserQuestion/ExitPlanMode). That expectation predates the answered-dialog model (issue #56), under which a resolved dialog stays a dialog message carrying its recorded outcome — so both tests fail at their final assertion on every binary version, including the current 2.1.198 pin, even though the recipe-driving and recorded-answer halves pass.Desired behavior:
f1c20514a3571cdf9982e25c490042d740ed7cfed3f00c64ba92dc7ec47c3c5b, moved together in one commit with the compat-record update (the documented bump procedure — the re-verification precondition is satisfied per the issue body, dated 2026-07-25).LAB_COMPAT_LIVE=1against the 2.1.220 binary.Key interfaces:
CLAUDE_CODE_VERSION/CLAUDE_CODE_SHA256_X64_MUSLin the agent-tools version catalog — the only build-input change; the value pair must move atomically with the compat-record update.Outcome(answers / approval), not aToolchip. The earlier stages of those tests (recipe driving, recordedtoolUseResultcomparison) are correct and must not be weakened.Acceptance criteria:
LAB_COMPAT_LIVE=1live probes (auth status, isolated logout, config-dir resolution, both dialog recipe tests) pass end-to-end with the 2.1.220 binary on PATH (requires tmux and a logged-in claude, as the tests' own skip-gates state).Closes #235.Out of scope:
--remote-controlbridge/deep-link capture, async-marker live roundtrip, live commit-flow attribution) — host-side or follow-up work, not gates for this bump.chore(agent-tools): bump Claude Code pin to 2.1.220 (compat re-verified 2026-07-25) + fix two stale ReadChat assertions in the live recipe teststo chore(compat): finish the Claude Code 2.1.220 pin — live recipe re-verification on the dev host + two stale ReadChat assertions (pin itself already landed in 52a9176)Update from the Daily agent update check schedule, 2026-07-31 — rescoped, roughly half of this landed.
Checked the tree against the original spec. Here is the diff between what the issue asked for and what is on
main:Landed (commit
52a9176, "chore(agent-tools): bump Claude Code pin 2.1.198 → 2.1.220 (opus alias → Opus 5)", merged via #246):containers/agent-tools/versions.env:20-21now readsCLAUDE_CODE_VERSION=2.1.220/CLAUDE_CODE_SHA256_X64_MUSL=f1c2051….internal/compat/compat.md:3pin header reads 2.1.220.Did not land — this is what the issue now covers:
Change 1 (the stale assertions) was not done.
internal/compat/live_recipes_test.go:286and:344still readm.Tool != nil && m.Tool.Name == "AskUserQuestion"/== "ExitPlanMode"— the pre-#56 tool-chip model, unchanged.The live re-verification did not happen the way the body claimed. The issue body asserted a full live checklist drive on 2026-07-25. What the compat record actually documents (
compat.md:43-45) is a 2026-07-28 static bundle extraction + in-container CLI probe, with its own caveat: "the probing container had no go/tmux, so the live recipe suite below is still owed".compat.md:71-77then lists the live tmux recipe couplings and the §3b refresh recipe as NOT yet re-verified on 2.1.220, and says the per-section "live (2.1.198/2.1.206)" provenance remains the newest live evidence.The §12 rewrite did not happen. §12 still carries its original heading at
compat.md:1186:## 12. Spawning WITHOUT --remote-control — live (2.1.206, 2026-07-14). The flush-on-resolve reversal the body reported is neither recorded nor refuted in the record — it is currently an unverified claim living only in this issue.So the pin shipped on static evidence and the live gate is still open. The body above has been rewritten to that remaining scope, with the already-landed parts marked do-not-redo.
Also checked, no action needed: Claude Code 2.1.220 is still the newest release. npm
@anthropic-ai/claude-codedist-tags today:latest= 2.1.220 (published 2026-07-24),stable= 2.1.212,next= 2.1.220. Nothing to chase; leave the pin alone.Related, filed separately today: the codex pin is the agent-tools drift that actually matters now —
CODEX_VERSION=0.133.0against upstream stable0.146.0, 13 stable releases and ~2 months behind, including an explicit security-advisory dependency sweep in 0.143.0. That has its own issue with the full changelog analysis.Re-verified 2026-08-03 (Daily agent update check):
2.1.220is still the newest Claude Code release. The pin needs nothing; this issue's remaining scope — the live tmux re-verification and the two stale assertions — is unchanged and still open.Nothing has published in the ten days since
2.1.220.containers/agent-tools/versions.env:20-21andinternal/compat/compat.md:3both already name it, as the "already done, do not redo" section says. Do not reopen the pin as part of this.Still open, unchanged since the 2026-07-31 rescope — re-checked against the tree today:
internal/compat/live_recipes_test.go:286still readsm.Tool != nil && m.Tool.Name == "AskUserQuestion" && strings.Contains(m.Tool.Output, …), and:344still readsm.Tool != nil && m.Tool.Name == "ExitPlanMode" && strings.HasPrefix(m.Tool.Output, "User has approved your plan"). Both are the pre-#56 tool-chip model and fail on every binary version, not just 2.1.220. Work item 1.internal/compat/compat.md:71-77still carries the "NOT yet re-verified on 2.1.220" bullet, and §12 atcompat.md:1186still carries its original heading## 12. Spawning WITHOUT --remote-control — live (2.1.206, 2026-07-14). The flush-on-resolve reversal is still neither confirmed nor refuted in the record. Work item 2.The blocker remains what it always was: this needs the dev host (tmux plus a logged-in
claude2.1.220 on PATH). Today's sweep ran in an environment with no Go toolchain, no node and no tmux, so it could not be discharged here either — and a skipped-run Liveis not a pass.One adjacent note, for context only.
flake.lockmoved on 2026-08-02 (commitbbc7f99, nixpkgsd407951→148bab9c). Unlike codex — where the new nixpkgs rev conveniently ships the exact version #249 targets — nixpkgs at148bab9chas nopkgs/by-name/cl/claude-codederivation to read a version out of, so the flake bump does not hand you a 2.1.220 binary the way it does a 0.146.0 codex.nix/module.nix:167still defaultsagentPackages."claude-code" = pkgs.claude-code. Getting a real 2.1.220 on PATH for the live suite remains a dev-host job; plan for that rather than expecting the devShell to provide it.Nothing else to fold in. The body is accurate as written.
Correction from the Daily agent update check sweep, 2026-08-04: the "nothing newer to chase" statement in this body is now false.
This issue's Already done, do not redo section says:
That was accurate when written. 2.1.221 published 2026-08-03T22:16:25Z and the channels have both moved:
So the pin this issue is closing out (2.1.220) is now the stable channel — which is a mild vote of confidence in it, not a reason to abandon this work.
This issue's scope does not change. Do not chase 2.1.221 here. The live tmux re-verification against a real 2.1.220 binary, and the two stale
live_recipes_test.goassertions blocking it, are exactly the right work and are unaffected by a newer release existing. The instruction "do not open the pin again as part of this" still stands — only its stated justification ("there is nothing newer") is stale.The 2.1.221 bump is filed separately as #273, which names this issue as a hard prerequisite: without a green live suite on 2.1.220 there is no baseline to diff 2.1.221 against, and real drift would be indistinguishable from the pre-existing #56 assertion bug. Land this one first.
For context when you get there, 2.1.221's one item that reaches lab is a Bash-tool permission-check bypass fix (zsh
[[ ]]regex conditionals) — full reachability analysis on #273.Nothing else about this issue was re-verified in this sweep; the Work item 1 / Work item 2 / §12 specification below stands as written.
Both work items landed in PR #274 (the 2.1.220 → 2.1.221 pin bump, #273), because #273 could not produce a readable result without them.
Work item 1 — the two stale assertions at
live_recipes_test.go:286and:344are fixed. They now assert a dialog message whose recordedOutcomecarries the answers (issue #56's shape, perdialogoutcome.go) instead of a demoted tool chip:Bluefor the single-select question and{Apple, Cherry}order-insensitively for the multi-select, andApprovedforExitPlanMode. One correction to this issue's framing: the AskUserQuestion test drives one 2-question form, not two separate cases, so the outcome is a single dialog message withResultsof length 2. Nothing earlier in either test was weakened — the recipe driving, pane polling and recorded-answer comparison are byte-identical.Work item 2 — the live suite ran green on 2.1.220, which is what this issue asked for:
Six tests, zero skips, all PASS. It was then re-run on 2.1.221 with identical verdicts, so the 2.1.220 result stands on its own as the baseline.
compat.md's "NOT yet re-verified on 2.1.220" bullet is replaced with that outcome.Two notes for whoever closes this issue:
tool_useflush reversal was NOT settled. This issue expected it as the main thing to confirm or refute. The live recipe tests read the transcript after resolve, which does not exercise the pre-resolve flush, so they cannot answer it either way. §12 keeps its original heading and its 2.1.206 provenance, andcompat.mdnow says explicitly that the A/B was not re-driven rather than implying the green suite covered it. If you want that reversal settled it needs its own two-arm spawn probe.The §3b by-hand credential-refresh recipe also remains un-re-run; it rotates the host's real OAuth family, so it stayed out of an automated run.