Pangram verdict · v3.3
We believe that this document is a mix of AI-generated, AI-assisted, and human-written content
AI likelihood · overall
MixedArticle text · 1,704 words · 6 segments analyzed
"Mechanical egg timer" by Hustvedt is licensed under CC BY-SA 3.0 . Padded to a wider frame; this adaptation is likewise licensed CC BY-SA 3.0.On Canada Day (July 1), 2026, Anthropic shipped a surprising “easter egg” to users of Claude Code: 2.1.198 includes an efficiency bypass which allows agents to continue on without being blocked on direction from a human. You essentially get a 60 second timer after Claude Code asks for input. If you miss the window, Claude Code helpfully does what it thinks is best and continues on its way. It looks like this:● Claude asked: ⎿ … ● No response after 60s — continued without an answer ● The user stepped away. I'll proceed with best judgment. My plan: Note: the above is taken verbatim from one of my own claude sessions, with the questions having been trimmed.If you find this behaviour surprising, you’re not alone. Let’s consider the possible consequences:Do you have to take your laptop to the kitchen with you when you’re making a sandwich? What happens if you are afk during this window?How many agents are you running at once? Can you possibly observe them all at the same time? What if two or more agents ask for your input during the same 60 second window?What if the agent makes the wrong choice? How many tokens have been burned in the meantime?What if you are using agents for deployments? (Yes, I know, but what if)These are reasonable things you might consider when shipping this feature and maybe you’d document your reasoning in the changelog. But what if you never mentioned the new defaults in the changelog at all? Wouldn’t that be even more surprising? (Spoiler: it was!)The story has a (sort of) happy ending. Move fast and break things does not necessarily preclude move fast and fix things.
Within a couple of days a fix was shipped, but where does that leave user trust in this product?We’ve learned a few things:Surprising features in Claude Code can in theory (and in practice) be shipped by Anthropic on a daily cadenceNot every feature will necessarily appear in the changelogThings that should not be defaults may not have a documented off switchClaude Code’s auto update feature feels more like YOLO mode than we might have suspected early onThere are a few things I don’t know if we have learned:How do humans fit into this equation?Did a human dream up the feature?Did a human write (or have an agent write) this feature?Did a human review the feature?Did a human sign off on the feature?Did a human merge the feature?Did a human opt out of documenting the feature or adding it to the changelog?Did a human release manager diff the release with the previous release and give it their seal of approval before it went out the door?Personally I would find it hard to believe that a human was gating all of these steps without asking “is this a good idea?”. If you told me that Claude Code actually built the feature, shipped it, signed off on it and then deemed it unworthy of documentation, that’s something I’m more inclined to believe, but I just don’t know. Maybe it’s some combination of those two things. Maybe a number of things went wrong, but I think it’s clear that this never should have happened. And I say this as someone who has had at least one performance review where my manager said “well, you did put a serious bug into production”.I’ve wondered a bit about how this happened and what kind of post-mortem is available in the public record. So, I’ve asked Claude Code to investigate itself. To Claude’s credit, it seems to have no filter that prevents self-reflection regarding this code. So, full disclosure, what follows is mostly Claude’s work, so take that for what it’s worth and if you rely on any key assumptions, it’s worth reproducing them in isolation.
Claude’s research begins here.#Timeline2026-06-29 — 2.1.196 released; the reporter’s “last working version (I am guessing)”2026-06-30 — 2.1.197 released; one changelog line, the Sonnet 5 launch2026-07-01 — 2.1.198 released — the version the reporter pins the regression to. No public commit shows the change; the only public trace of this release is the bot commit publishing its notes (75709ea), which touches nothing but CHANGELOG.md and feed.xml2026-07-02 02:54 UTC — issue #73125 filed by Aleksey Nogin2026-07-02 03:45 UTC — a commenter surfaces the escape hatch: CLAUDE_AFK_TIMEOUT_MS. Traded peer-to-peer in the thread, not pointed to from any release note2026-07-02 — 2.1.199 ships 24 entries while the issue is open. Still no mention.2026-07-03 — 2.1.200 reverses the behaviour; again the only public trace is the notes commit (1322e9b)2026-07-04 18:04 UTC — issue closedReaction/scale on the issue: 384 👍, 143 comments — not a niche complaintReporter’s environment: 2.1.198, “last working 2.1.196 (guessing)”, Opus, AWS Bedrock, VS Code terminalgit clone https://github.com/anthropics/claude-code.git cd claude-code # When did the fix land, and in which version? git log -1 --format='%h %ai' -S'no longer auto-continue by default' -- CHANGELOG.md # 1322e9ba 2026-07-03 16:52:26 +0000 # When did the version that shipped the bug land?
git log -1 --format='%h %ai' -S'## 2.1.198' -- CHANGELOG.md # 75709eac 2026-07-01 20:45:29 +0000 #The misfeatureAskUserQuestion is the tool Claude Code uses to stop and ask the human a question mid-taskNew behaviour: after 60 seconds of inactivity, the tool auto-returns a “proceed anyway” result instead of blockingThe message handed back to the model — this is the template, rendered here at the 60-second default:// v2.1.198, verbatim. `Thl` is the minifier's name; the prose is the binary's own. // Note "60s" is interpolated, not a literal in the file: function Thl(e){return `No response after ${Math.round(e/1000)}s — the user may be away from keyboard. Proceed using your best judgment based on the context so far; you can re-ask this question later if it's still relevant.`} The “re-ask later” escape hatch is circular: the re-asked question hits the same timeout. Aleksey Nogin made this point in the issue thread within minutes of filing itThe transcript line has two variants — the binary picks between them on whether you’d started answering:// v2.1.198, verbatim. `a` is the minifier's name for "some answers exist" // (`s=Object.entries(r)` over the answers, `a=s.length>0`); both string values // are the binary's own. let d=a?"continued with the answers selected so far":"continued without an answer" So a half-answered dialog does not discard the partial input — it submits it. Answer question one of three, step away, and the timeout commits your one answer plus whatever the model picks for the other twoBoth strings are absent from 2.1.197 and present in 2.1.198In fairness: it was not silent on screen. The dialog rendered a live countdown, and a keypress restarted the timer.
Assembled at runtime rather than stored as one string, so this is the rendered form, not a literal grep hit:// v2.1.198, verbatim — the pieces. `s` is the remaining-seconds value. children:["auto-continue in ",s,"s \xB7 any key to stay"] // renders as: auto-continue in 12s · any key to stay Which cuts less far than it looks. The countdown only reaches someone watching the screen, and the premise of the feature is that you aren’t:the internal name is AFK; the message says “the user may be away from keyboard”running several agents at once, “watching the screen” is not one place — the countdown you needed was on another tabAnd the countdown is late. The threshold defaults to 20 seconds (CLAUDE_AFK_COUNTDOWN_MS), and it gates on remaining time, not elapsed — so for the first 40 seconds the dialog looks like an ordinary blocking question. It is on screen, but nothing on it says a timer is running:// v2.1.198 ships this minified — the locals are mangled, but the property // names survive, so `showCountdown` and `remainingSeconds` are its own words: let u=i*1000<=n;return{remainingSeconds:i,showCountdown:u,timeoutMs:t} // ...which reads, with n at its default of 20000: showCountdown = remainingSeconds * 1000 <= 20000 The warning arrives in the last thirdWhat it does not touch: the timeout applies only to AskUserQuestion. Anthropic’s tools reference says “permission prompts, including plan approval, never auto-resolve on idle” — and unlike the docs claims elsewhere in this post, this one is checkable against the shipped 2.1.198 code rather than a page written after the fix:the countdown component (q0m) has exactly one call site in the entire bundle, and its timer hook (_Rc) has exactly one caller — q0m itself.
The timer exists in one componentthat component’s props identify it past argument: jsx(dRc,{question:V, questions:s, currentQuestionIndex:$, answers:R, questionStates:O, onAnswer:be, onSubmit:N, …}). Its timeout handler is what fires tengu_ask_user_question_afk_auto_advancethe permission prompt (Do you want to proceed, Do you want to allow …) is a separate component with no timer attachedBut the exemption only protects you if a permission prompt appears at all. 2.1.198 ships bypassPermissions, acceptEdits, allowedTools, --dangerously-skip-permissions and PreToolUse hooks. Anyone running agents against deployments has plausibly allowlisted the deploy command or turned prompts off — that is what automating it means. For them the permission layer was never going to fire, so its immunity to the timer buys nothingThe narrower claim, and the one that bites: the timer could not grant permission, but it could make the choice. AskUserQuestion doesn’t ask permission, it asks you to decide — “staging or production?”, “which config?” On timeout the model is told to proceed using your best judgment, and the partial-answers path continues “with the answers selected so far”. If permission was already granted by allowlist or bypass, the choice was the only gate leftNo timeout parameter exists in the tool schema — the model can neither set nor control it. Verified in the binary (U_f=…H.strictObject({questions:…})), not taken from the issue thread. The input params are only:questions, answers, annotations, metadata So the model is truthful when it says it didn’t skip anything — the harness returned the answer, not the model#The fix2.1.200 made auto-continue off by defaultIdle timeout is now opt-in via /config, not forced on everyoneNote the changelog’s verb: “no longer auto-continue by default”. Nothing was removed — the default flipped.The /config setting the note points you to did not exist before the fix. Grep 2.1.198 for askUserQuestionTimeout and you get zero hits: when this shipped, the only way to escape it was an env var — and the release notes never named it.