# Claude Code v2.1.280

> Claude Code v2.1.280, released 22 Sep 2026 (2026-09-22). 771 entries read out of the shipped bundle. Unofficial, and not affiliated with Anthropic.

Web version: https://changelogs.core-directive.com/v/2.1.280

Twelve of this build's 27 gated additions stay out of reach. A warning for dispatching multiple write-capable agents into the same directory sits unreleased alongside a new sessionRecord capability flag for remote session negotiation, both off by default. A max-effort reminder that would point users to /effort stays gated off, and rich remote-control approval details like the raw command remain hidden behind their own gate. Also present but inactive: a "tether" subsystem that would recreate a thinking thread when the server drops it on a prefix mismatch, an inline-tools flag for mid-conversation tool declarations, and a diskless mode for task output.

Among 267 shipped changes, Opus 5.5 arrives with a 1M-token context window and its own pricing tier, and a new "max effort" mode is now reachable through the /effort command. MCP servers can hide individual tools from Claude while still showing them to the human via _meta.ui.visibility, and Claude Code adds MCP Apps support (SEP-1865) for UI panels served by connected MCP servers. Plugin authors get a process.spawn host operation for streaming subprocesses and a new cross-session messaging API ($.session.send, $.session.messages, $.session.authorize). A remote PowerShell tool now lets Claude Code run commands on an attached Windows machine instead of locally.

Among 62 fixes and removals, the rate-limit banner is now cross-checked against the actual limit type before it renders, and sending a queued message now uses whatever permission mode is currently active rather than the one from when it was queued. The proxy auth helper's retry detection widens to catch 407 errors hidden inside proxy-tunnel/CONNECT failures, and plugin uninstall no longer deletes a data directory still shared by a same-named plugin in another scope. Opus 4.1 is removed from the offered model list, and the MCP server detail menu drops its Restart option, leaving only Remove and Back.

## What probably matters to you

Anything you can use today, anything that visibly changes, and anything worth poking at. One line each, open for detail.

### AGENTS.md-as-instructions plugin gate simplified, still off by default

The availability check for the built-in AGENTS.md plugin was simplified, but it's still off by default

**What**

Claude Code includes a built-in plugin called `agents-md` that, when active, loads a project's `AGENTS.md` file and uses it as instructions (the same role `CLAUDE.md` normally plays). The internal check that decides whether this plugin is available has been simplified: it used to test an extra condition before checking anything else, and now it just checks the remote flag `tengu_agents_md_mod`, falling back to the plugin's own default-on setting if that flag isn't present.

This is an internal cleanup to how the plugin decides whether it can turn on, not a change to what the plugin does once it's active.

**Why**

Simplifying this check makes the plugin's availability easier to reason about and reduces the chance of an outdated precondition blocking it unnecessarily. Whether it actually turns on for a given account still depends on the `tengu_agents_md_mod` flag, which is controlled server-side.

- Flag `tengu_agents_md_mod`: Off by default, switched on for this account (read for one account on one subscription tier against v2.1.280; this account: on, anonymous baseline: on, compiled default: off) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: AGENTS.md
- Names: `AGENTS.md`, `tengu_agents_md_mod`
- Tier: Use it now
- Useful: 4/5
- Signal: 4/5

### Remote PowerShell tool can now run on an attached Windows machine

A new remote PowerShell tool lets Claude Code run PowerShell commands on an attached Windows machine instead of locally

**Unclear.** The finding doesn't say how a machine becomes "attached" or what triggers this remote routing in practice.

**What**

Claude Code has a new session-channel PowerShell tool. It wraps the existing PowerShell tool but removes the `run_in_background` option and adds a field for picking which attached machine to run on. The tool itself never actually runs the command; instead it always responds with a message saying PowerShell only runs on the target machine and that the session there has to run it, not the current one. This means the tool exists so the model can point a PowerShell command at a remote machine, while the real execution happens elsewhere in that machine's own session.

Alongside this, the regular PowerShell tool now reports itself as able to be dispatched remotely, but only when the machine it's running on is Windows. On other operating systems it falls back to being marked as not remotely dispatchable, same as before.

**Why**

This lets Claude Code target PowerShell commands at a separate, attached Windows machine rather than only running them on the machine the session is on, which matters for anyone controlling or automating a remote Windows box from Claude Code.

- Flag `tengu_cobalt_ridge`: Off by default, switched on for this account (read for one account on one subscription tier against v2.1.280; this account: on, anonymous baseline: on, compiled default: off) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Remote Control
- Names: `tengu_cobalt_ridge`
- Tier: Use it now
- Useful: 4/5
- Signal: 4/5

### Fast mode no longer restricted to Opus 5/4.8 in the system prompt

The system prompt no longer says fast mode is limited to Opus 5/4.8, and now lists Opus 5.5 in the model catalog

**What**

The system prompt Claude Code sends to the model describes fast mode, a setting toggled with `/fast` that makes Claude Opus respond faster. Previously the prompt said fast mode "is available on Opus 5/4.8"; that restriction has been dropped, and the prompt now just says it can be toggled with `/fast`. The model catalog line in the same prompt now lists `claude-opus-5-5` (Opus 5.5) where it used to list `claude-opus-5`.

**Why**

Dropping the model-restriction wording means the model is no longer told fast mode only works on specific Opus versions, in step with the newly listed Opus 5.5 model.

- Area: Models
- Names: `/fast`, `claude-opus-5-5`
- Tier: You'll notice
- Useful: 4/5
- Signal: 4/5

### VSCode extension gates: inline pastes and 'tranquil cloud' now on by default; new max-effort reminder gate

VS Code extension adds default-on settings for inline pastes and 'tranquil cloud', plus a new max-effort reminder option

**Unclear.** What `tengu_vscode_inline_pastes`, `tengu_tranquil_cloud`, and the max-effort reminder actually do or show to the user is not stated in the finding.

**What**

The VS Code extension's internal settings table has three additions:

- `tengu_vscode_inline_pastes`, defaulting to on

- `tengu_tranquil_cloud`, defaulting to on

- a new max-effort reminder option (backed by `tengu_proud_clover`), wired from a `maxEffortReminderEnabled` value and defaulting to off

No description of what the inline pastes setting does, what 'tranquil cloud' refers to, or what the max-effort reminder says to the user is available yet.

**Why**

These are internal settings, so most users won't interact with them directly, but they indicate new behavior arriving in the VS Code extension: something about how pasted content is handled, a cloud-related feature, and a reminder tied to running at maximum effort.

- Flag `tengu_vscode_inline_pastes`: Not enough to say (read for one account on one subscription tier against v2.1.280; this account: no value returned, anonymous baseline: no value returned, compiled default: on) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Flag `tengu_tranquil_cloud`: Not enough to say (read for one account on one subscription tier against v2.1.280; this account: no value returned, anonymous baseline: no value returned, compiled default: on) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Flag `tengu_proud_clover`: Not enough to say (read for one account on one subscription tier against v2.1.280; this account: no value returned, anonymous baseline: no value returned, compiled default: off) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: VSCode Extension
- Names: `tengu_vscode_inline_pastes`, `tengu_tranquil_cloud`, `tengu_proud_clover`
- Tier: You'll notice
- Useful: 4/5
- Signal: 4/5

### Artifact verify/preview tools merged into a single 'check' tool

Artifact verify and preview tools are merged into one 'check' tool with old verb names still accepted

**What**

The separate artifact-verify and artifact-preview capabilities are combined into a single tool called `check`. Its search hint dynamically lists "preview a page locally" and/or "read viewers' runtime diagnostics" depending on which capabilities are enabled for a given session. An `offersLegacyVerb` mechanism maps the old `verify` and `preview` verbs back to the new tool for compatibility.

**Why**

This consolidates two related artifact tools into one, while `offersLegacyVerb` means existing usage of the old verb names should keep working.

- Flag `tengu_osier_pylon_trace`: Not enough to say (read for one account on one subscription tier against v2.1.280; this account: no value returned, anonymous baseline: no value returned, compiled default: off) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Flag `tengu_cobalt_plinth_aspen`: Not enough to say (read for one account on one subscription tier against v2.1.280; this account: no value returned, anonymous baseline: no value returned, compiled default: off) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Artifacts
- Names: `check`
- Tier: Nothing to try yet
- Useful: 4/5
- Signal: 4/5
- Present in the build but not switched on

### New sessionRecord capability flag, default off

A new sessionRecord capability flag was added to remote session negotiation, off by default

**Unclear.** What the sessionRecord capability actually enables isn't specified beyond its name and default.

**What**

A capabilities map used in remote or session negotiation gained a new entry, `sessionRecord`, which defaults to false. It sits alongside existing entries `controlChannel`, `modelCatalog`, and `setPermissionMode` (all true by default), and `fanout`, `presence`, and `catchupReplay` (all false by default).

**Why**

This adds a new capability flag that can be negotiated between client and server, though the finding doesn't specify what session recording feature it controls.

- Area: Sessions
- Names: `sessionRecord`
- Tier: Nothing to try yet
- Useful: 4/5
- Signal: 4/5
- Present in the build but not switched on

### Warning added when dispatching parallel write-capable agents into the same directory

Claude now warns when dispatching multiple write-capable agents into the same working directory

**What**

When Claude dispatches two or more agents (subagents that carry out a task on Claude's behalf) that will write or edit files in the same repository, it can now be told to give each one `isolation: "worktree"`, which runs them against separate copies of the repository instead of the same files. Separately, if an agent is launched asynchronously and another write-capable agent (one with Edit or Write tools) is already running in the same working directory, its result can now come back with a warning about the conflict, via a new `sharesCwd` field, suggesting worktree isolation or careful editing.

**Why**

This helps prevent two agents from stepping on each other's changes when they're set loose on the same directory at the same time, either by keeping their work separated automatically or by flagging the risk so Claude can be more careful.

- Flag `tengu_twinkling_boole`: Not enough to say (read for one account on one subscription tier against v2.1.280; this account: no value returned, anonymous baseline: no value returned, compiled default: off) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Agent Tool
- Names: `worktree`
- Tier: Nothing to try yet
- Useful: 4/5
- Signal: 4/5
- Present in the build but not switched on

### sideQuery / API dispatch gains an `effort` (output_config.effort) parameter with automatic fallback

Side-query API calls now send an effort setting and automatically retry without it if the model rejects it

**What**

When Claude Code sends a side query (a request to the API made outside the main conversation) it can now include an `effort` option, which is passed through as `output_config.effort` on the API call. Effort controls how much work the model puts into its response.

If a given model rejects the `effort` field, Claude Code remembers that the model doesn't support it and automatically retries the same request with the field removed, so the query still completes.

**Why**

This lets Claude Code tune how much effort a model spends on background or auxiliary requests, while quietly working around models that don't yet accept the setting instead of failing the request outright.

- Area: API Dispatch
- Names: `output_config.effort`
- Tier: Under the hood
- Useful: 4/5
- Signal: 4/5

### MCP Apps (SEP-1865) UI resources: new mcp_read_resource protocol subtype and tool _meta.ui schema

Claude Code adds MCP Apps support for UI panels served by connected MCP servers

**What**

Claude Code now supports MCP Apps (SEP-1865), a way for MCP (Model Context Protocol) servers to serve interactive UI panels alongside their tools:

- A new protocol message type, `mcp_read_resource`, lets Claude Code fetch a `ui://` resource from a connected MCP server so it can render that panel.

- Tool definitions can now carry a validated `_meta` field with `ui.resourceUri` and `ui.visibility`, telling Claude Code which UI resource belongs to a tool and how visible it should be. A previous, deprecated flat form (`ui/resourceUri`) is still recognized.

- Both capabilities are advertised through new capability flags so servers and Claude Code can negotiate support.

**Why**

This lets MCP server authors ship a richer, custom UI alongside their tools instead of relying solely on plain text output, and gives Claude Code a standard way to discover and load that UI.

- Area: MCP
- Names: `mcp_read_resource`, `_meta.ui`
- Tier: Use it now
- Useful: 5/5
- Signal: 3/5

### MCP servers can now hide tools from the model via `_meta.ui.visibility`, live and wired

MCP servers can now hide specific tools from Claude while still showing them to the human in mcp_status

**What**

An MCP (Model Context Protocol, the standard Claude Code uses to connect external tools) server can now mark a tool as hidden from the model. It does this through a `_meta.ui.visibility` field on the tool: if that field's list of visibility targets leaves out `"model"`, or can't be parsed at all, Claude Code treats the tool as hidden and drops it from the list of tools the model can call.

The hiding only applies to what the model sees. The tool still shows up for the person running Claude Code, in the `mcp_status` view.

**Why**

This lets an MCP server author ship a tool meant for humans (or some other consumer) without cluttering the model's own tool list or letting it be called unintentionally, while still keeping the tool visible to the person using Claude Code.

- Area: MCP
- Names: `_meta.ui.visibility`
- Tier: Use it now
- Useful: 5/5
- Signal: 3/5

### New "max effort" mode with /effort command

A new "max effort" mode appears with a footer hint pointing to the /effort command

**Unclear.** Whether the tengu_proud_clover gate controls this feature, and whether it's switched on, is unread and not stated by the finding.

**What**

Claude Code has a new max-effort mode. When active, a footer line reads "Max effort · /effort to change", and a helper decides whether to force this mode on, gated behind an internal reminder check. The `/effort` command lets you set the effort level, including a `max` level alongside the existing `low` through `xhigh` and `auto` options.

**Why**

This gives users a visible indicator and a documented way to push Claude to its highest effort setting for a task, and a way to change back via the same `/effort` command.

- Flag `tengu_proud_clover`: Not enough to say (read for one account on one subscription tier against v2.1.280; this account: no value returned, anonymous baseline: no value returned, compiled default: off) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Effort
- Names: `/effort`, `max`
- Tier: Use it now
- Useful: 5/5
- Signal: 3/5

### New plugin/hooks host op: process.spawn

Plugins can now spawn and stream a subprocess via a new process.spawn host operation

**What**

Claude Code's plugin system (which lets extensions run code through "hooks" that respond to events) has a new low-level capability called `process.spawn`. It lets plugin code launch a subprocess and stream its output back, running through the same sandboxed bridge that mediates what plugins are allowed to do on the host machine.

**Why**

This gives plugin authors a supported way to run external programs and receive their output as it streams in, rather than only making one-shot request/response calls.

- Area: Plugins
- Names: `process.spawn`
- Tier: Use it now
- Useful: 5/5
- Signal: 3/5

### Opus 5.5 model added

New Opus 5.5 model added with a 1M-token context window and its own pricing tier

**What**

A new model, `claude-opus-5-5` (display name "Opus 5.5"), has been added to Claude Code's model registry, with provider IDs across Bedrock, Vertex, and Foundry, a 1-million-token context window, and its own pricing tier. It's now recognized as a valid model ID throughout the client: in the model-name normalization table, the list of models allowed the 1M-token/auto-compact context window, and the model-family checks used for capabilities like fast mode and thinking.

The system prompt now lists "Opus 5.5: claude-opus-5-5" as the most capable model, in place of the previous "Opus 5" entry, and no longer ties fast mode's availability to "Opus 5/4.8."

**Why**

This makes Opus 5.5 usable across Claude Code's model selection, context-window handling, and pricing, and it becomes the model the system prompt now points to as the most capable option.

- Area: Models
- Names: `claude-opus-5-5`
- Tier: Use it now
- Useful: 5/5
- Signal: 3/5

### New 'promoteMemory' / 'promoteMemoryNonInteractive' commands, currently build-disabled

Two new memory-promotion commands exist in the code but are disabled in this build

**What**

Two new commands, `promoteMemory` and `promoteMemoryNonInteractive`, have been added to Claude Code's command list. However, the object they would be read from is set to `null` in this build, so the condition that would add them to the available commands never triggers, and they don't actually appear.

**Why**

This is groundwork for a future feature rather than something usable now; the commands exist in the code but are inert until a later release enables them.

- Area: Memory
- Names: `promoteMemory`, `promoteMemoryNonInteractive`
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 4/5
- Present in the build but not switched on

### New hostScheduledRun session flag

A new hostScheduledRun flag was added to session descriptors, off by default

**Unclear.** What sets hostScheduledRun to true or how it's used isn't specified.

**What**

A session/environment descriptor gained a new boolean field, `hostScheduledRun`, which defaults to false. It joins existing flags `childSession`, `claudecode`, and `coworkFrameArtifacts`.

**Why**

This adds a new way to mark a session as having been started by a host's scheduler, though the finding doesn't specify where this flag is read or acted on.

- Area: Sessions
- Names: `hostScheduledRun`
- Tier: Under the hood
- Useful: 3/5
- Signal: 4/5

### Agent SDK / control protocol gains remote dialog and status request methods

Agent SDK's control-protocol client adds methods for remote dialogs, status, conversation export and Chrome browser selection

**Unclear.** The finding does not say what client or interface actually calls these new methods or what feature they support.

**What**

The Agent SDK's control-protocol client (the internal channel Claude Code uses to send commands and get responses back) gained several new request methods:

- `getSkillsDialog` — requests the skills dialog

- `getStatus` — requests status information

- `exportConversation` — requests a conversation export

- `getChromeDialog` — requests the Chrome dialog

- `getChromeBrowsers` — requests the list of available Chrome browsers

- `selectChromeBrowser` — requests selection of a specific Chrome browser

- `getSandboxDialog` — requests the sandbox dialog

Each method sends a matching request subtype (like `get_status` or `select_chrome_browser`) and waits for the response.

**Why**

These methods let code built on the Agent SDK trigger the same dialogs and status lookups that Claude Code's own interface uses, including picking which Chrome browser to use and exporting a conversation, without needing to reimplement that logic.

- Area: SDK
- Tier: Use it now
- Useful: 4/5
- Signal: 3/5

### New cross-session/agent messaging plugin API: $.session.send, $.session.messages, $.session.authorize

New plugin API lets plugins read, authorize, and message other sessions

**What**

A new API for plugins adds three capabilities for working across sessions or agents:

- `$.session.messages` reads another session's or agent's conversation transcript

- `$.session.authorize` authorizes a first-party credential for a session

- `$.session.send` sends a message to another live session or agent, using the same underlying `SendMessage` tool Claude Code itself uses, and reports back if delivery fails

**Why**

This gives plugin authors a supported way to build features that coordinate across multiple sessions or agents, such as relaying messages or checking another session's history, instead of working around the lack of such an API.

- Area: Plugins
- Tier: Use it now
- Useful: 4/5
- Signal: 3/5

### Plugin hooks can intercept and readdress SendMessage sends

Plugin hooks can now intercept SendMessage calls, rewriting or blocking who a message goes to

**What**

`SendMessage`, the mechanism used to send messages between agents or sessions, now passes through a hook pipeline before delivery. A hook (a piece of plugin code that runs at a defined point) can:

- Rewrite the recipient of a message, or rewrite the message text itself

- Trigger a fresh permission check if the recipient is changed

- Cause the send to be dropped entirely, with an explicit refusal message, if the readdress isn't backed by an `ask` handler or is denied

A related change adds a `session.send` hook path, where a registered runner can intercept an outgoing send. If no runner is registered, sending proceeds normally. When a hook does substitute the delivery, a new message tells the user a plugin hook handled it rather than the original send.

**Why**

This lets plugins control or audit message routing between agents, but it also means a message you send may not go where you expect, or may be silently dropped, if a plugin hook intervenes.

- Area: Plugins
- Names: `SendMessage`
- Tier: Use it now
- Useful: 4/5
- Signal: 3/5

### CLAUDE_CODE_PLUGIN_DIRS env var for sideloading plugin directories

New CLAUDE_CODE_PLUGIN_DIRS environment variable lets you register extra plugin directories without --plugin-dir flags

**What**

A new environment variable, `CLAUDE_CODE_PLUGIN_DIRS`, lets a session specify extra plugin folders, as a colon- or path-list-separated list, without passing `--plugin-dir` on the command line. These are merged with any `--plugin-dir` entries at startup. Entries that aren't absolute paths, aren't under the home directory, or use `~`, are rejected with a warning rather than silently accepted.

Like `--plugin-dir` and `--plugin-dir-no-mcp`, this variable is subject to the enterprise policy that can block sideloading (loading plugins from outside approved sources), and gives its own recovery hint when blocked.

**Why**

This gives another way to load local plugins for a session, useful for scripting or environment-based setups, while still respecting the same enterprise controls and path-safety checks as the existing flags.

- Area: Plugins
- Names: `CLAUDE_CODE_PLUGIN_DIRS`, `--plugin-dir`
- Tier: Use it now
- Useful: 5/5
- Signal: 2/5

### New built-in plugin: responsive mode

A new built-in 'responsive mode' plugin makes Claude send a quick acknowledgment before thinking or using tools

**What**

Claude Code now ships a built-in plugin called `responsive-mode`. When active, it makes Claude reply with a short acknowledgment message on every prompt before it starts thinking or calling any tool. It works by adding a "# Responsive mode" section to the system prompt (the hidden instructions guiding Claude's behavior) and by using hooks (automated checks that run at specific points, here `prompt.submit` and `turn.abort`) to interrupt and redirect the turn so the acknowledgment happens first.

**Why**

This gives users faster visible feedback that Claude has received a prompt and is working on it, rather than waiting silently through thinking and tool calls before seeing any response.

- Area: Plugins
- Names: `responsive-mode`
- Tier: Use it now
- Useful: 5/5
- Signal: 2/5

### SDK gains an MCP resource-read method

Claude Code SDK adds a method to read an MCP resource directly

**What**

The SDK's control-protocol client now has a `readMcpResource(serverName, uri)` method, which sends a new `mcp_read_resource` request and returns the server's response.

**Why**

This lets code using the SDK fetch a specific resource from an MCP (Model Context Protocol) server directly, rather than only being able to invoke tools that server exposes.

- Area: SDK
- Names: `readMcpResource`
- Tier: Use it now
- Useful: 5/5
- Signal: 2/5

### A 'chained' directory-sync mode exists, gated by an undocumented env var

A new 'chained' directory-sync mode exists behind an undocumented CLAUDE_CODE_DIR_SYNC_CHAIN env var

**Unclear.** The finding does not say what directory-sync 'chained' mode actually does differently, or who it is intended for.

**What**

The engine that keeps directories in sync now has a `chained` mode. It stays off unless an environment variable called `CLAUDE_CODE_DIR_SYNC_CHAIN` is set to exactly `true`.

**Why**

Since this isn't documented and requires manually setting an environment variable, most users won't encounter it. It appears to be an internal or experimental switch rather than a supported option.

- Area: Directory Sync
- Names: `CLAUDE_CODE_DIR_SYNC_CHAIN`
- Tier: Use it now
- Useful: 3/5
- Signal: 3/5

### New CLAUDE_CODE_HOST_SCHEDULED_RUN env var gates a local host's scheduled-run claims

Scheduled-run tasks can now report why they fired, but only if the host explicitly opts in via CLAUDE_CODE_HOST_SCHEDULED_RUN=1

**What**

Claude Code can now attach a `fireReason` to a scheduled-trigger task delivery, a short label saying why the task ran, such as `scheduled`, `manual`, `retry`, `catch_up`, or `api`. This value is only accepted if the process was started by the host with a new environment variable, `CLAUDE_CODE_HOST_SCHEDULED_RUN=1`. Even then, the value must be a short lowercase token (1 to 32 lowercase letters or underscores) or it is rejected.

The new `CLAUDE_CODE_HOST_SCHEDULED_RUN` variable is also added to the internal lists of environment variables that get passed through when Claude Code spawns subprocesses or sandboxed environments, so the setting carries over correctly.

**Why**

This prevents a task from falsely claiming to have been fired by a scheduler unless the host process that started it specifically declares that intent. It matters mainly to hosts or tooling that integrate with Claude Code's scheduled-trigger system, giving them a reliable, trusted way to record why a run happened.

- Area: Scheduled Tasks
- Names: `CLAUDE_CODE_HOST_SCHEDULED_RUN`
- Tier: Use it now
- Useful: 3/5
- Signal: 3/5

### New remote-tools 'jump queue' gate

A new gate controls whether remote tools can jump the queue

**Unclear.** The finding does not say what 'remote tools' or the queue itself are, or what concretely happens when a request jumps the queue.

**What**

Claude Code now has an internal check that decides whether certain remote-tools requests can skip ahead in a queue rather than waiting their turn. It first looks at the environment variable `CLAUDE_CODE_REMOTE_TOOLS_JUMP_QUEUE`, and if that is not set, falls back to a feature gate called `tengu_valiant_rain`, which is off by default.

**Why**

This affects how remote tool calls are scheduled internally; setting `CLAUDE_CODE_REMOTE_TOOLS_JUMP_QUEUE` gives control over queue-jumping behavior without waiting for the underlying default to change.

- Flag `tengu_valiant_rain`: Off by default, switched on for this account (read for one account on one subscription tier against v2.1.280; this account: on, anonymous baseline: on, compiled default: off) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Remote Tools
- Tier: Use it now
- Useful: 3/5
- Signal: 3/5

### Max-effort reminder UI, gated off by default

A new reminder can appear in the status line when effort is set to max, pointing you to /effort to change it

**What**

Claude Code now has support for a status-line reminder that reads "Max effort · … · /effort to change", shown when the effort level is set to `max`. Whether it actually appears is controlled by a gate: it checks the environment variable `CLAUDE_CODE_MAX_EFFORT_REMINDER` first, and if that isn't set, falls back to a remote flag from Anthropic's servers.

Related to this, a new `maxEffortReminderEnabled` setting is now computed and passed through the setup path for MCP (Model Context Protocol, the standard Claude Code uses to connect to external tools) clients, alongside other similar flags, and is reported in Claude Code's usage telemetry.

**Why**

This gives users running at `max` effort a visible cue in the status line and a reminder of the `/effort` command to change it, though whether it's switched on for a given account depends on server-side configuration or the `CLAUDE_CODE_MAX_EFFORT_REMINDER` environment variable.

- Flag `tengu_proud_clover`: Not enough to say (read for one account on one subscription tier against v2.1.280; this account: no value returned, anonymous baseline: no value returned, compiled default: off) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Terminal UI
- Names: `CLAUDE_CODE_MAX_EFFORT_REMINDER`, `/effort`
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### New `$.ui.copy` plugin API for writing to the terminal clipboard

A new $.ui.copy API lets plugins copy text to the terminal clipboard

**What**

Plugins can now use a new `$.ui.copy` function to copy text to the clipboard. It works via OSC 52 (a terminal escape sequence that lets a program set the system clipboard) and only works when a terminal is attached. It declines to copy, with a reason, in two cases:

- `no-surface`: there is no attached terminal/UI to copy to

- `no-clipboard`: the text is too long for the OSC 52 write limit

**Why**

This gives plugins a supported, built-in way to put text on the user's clipboard directly from the terminal, without needing their own clipboard integration.

- Area: Plugins
- Tier: Use it now
- Useful: 4/5
- Signal: 2/5

### New control-plane request: mcp_read_resource (MCP Apps UI resources)

New control-plane request lets a host read MCP Apps UI resources without triggering a model turn

**What**

A new SDK control request, `mcp_read_resource`, lets a host application read a single `ui://`-scheme resource from a connected MCP server using the `resources/read` method. It's read-only and doesn't trigger a model turn. It comes with a full schema, defined error handling, and a size limit, and is advertised during session setup as the `mcp_read_resource_v1` capability.

**Why**

This gives host applications a way to fetch MCP Apps UI resources (part of the SEP-1865 proposal for richer MCP UI integrations) directly and cheaply, without needing to route the request through a model turn.

- Area: SDK
- Names: `mcp_read_resource`
- Tier: Use it now
- Useful: 4/5
- Signal: 2/5

### New plugin-hookable event: session.send

Plugin hooks can now listen for a new session.send event, alongside session.receive/detach/end

**What**

Claude Code adds a new event, `session.send`, to the plugin hook system, sitting alongside the existing `session.receive`, `session.detach`, and `session.end` events. Plugins can write hooks that intercept this event, and it comes with a full setup:

- validation and normalization logic that fills in `to` and `origin` fields

- inclusion in the delivery-tracking system, with success/failure states

- inclusion in the warning that fires if a hook holds up an answer for too long

**Why**

This gives plugin authors a way to intercept and react to outbound messages being sent within a session, in addition to receiving, detaching, or ending one, expanding the range of session activity a plugin hook can observe or intervene in.

- Area: Plugins
- Names: `session.send`
- Tier: Use it now
- Useful: 4/5
- Signal: 2/5

### Plugin/SDK host API: new `$.session.send` operation

Plugins and SDK integrations gain a session.send call to message a target by name, agent id, or session/agent address

**What**

The host bridge that plugins and SDK integrations use to talk to Claude Code now exposes a `$.session.send` operation. It lets a plugin send a text message to a named target, an agent id, or an address given as `{sessionId}` or `{agentId}`. Both `to` and `text` must be non-empty or the call is rejected.

**Why**

This gives plugins and SDK-based tools a direct way to send messages to a specific session or agent, rather than only being able to act within their own context.

- Area: Plugins
- Tier: Use it now
- Useful: 4/5
- Signal: 2/5

### SDK gains a getPlan() control request

The Agent SDK adds a getPlan() method to fetch the current plan via a control request

**What**

The Agent SDK's control-protocol client (used to send commands to a running Claude Code session) now has a `getPlan()` method. It sends a `get_plan` control request and returns the response, joining the existing `reloadPlugins` method.

**Why**

This lets SDK-based integrations programmatically retrieve the current plan from a session rather than only reading it through other means.

- Area: SDK
- Names: `getPlan`
- Tier: Use it now
- Useful: 4/5
- Signal: 2/5

### SDK gets a verbatimPrompts option marking client-composed messages

The Agent SDK gets a verbatimPrompts option that skips marking messages as client-composed

**What**

The Agent SDK (the toolkit for building programs on top of Claude Code) has a new `verbatimPrompts` option. By default (`verbatimPrompts: false`), outgoing user messages sent to Claude Code are tagged internally with `client_composed: true`, marking them as composed by the SDK client. When `verbatimPrompts` is set, that tag is left off.

**Why**

This lets SDK integrations choose whether their messages get flagged as client-composed, which is useful for cases where a message should be treated as if it came directly from the user rather than being assembled by client code.

- Area: SDK
- Names: `verbatimPrompts`
- Tier: Use it now
- Useful: 4/5
- Signal: 2/5

### New 'model_consent_fallback' system message for usage-credit model swaps

New system message explains when Claude Code auto-switches models over usage-credit consent

**What**

Claude Code now emits a new kind of system message, `model_consent_fallback`, when a session automatically falls back to a different model because the originally requested model requires usage credits the user hasn't agreed to spend. It's shown as a highlighted (gold) line in the transcript, is included in transcript filtering, and is mapped into SDK messages. The message follows the pattern: "Switched to X — now your default model / for this session · Y requires usage credits · /model to change".

**Why**

This makes it clear to the user why their model changed mid-session, and tells them to use `/model` if they want to change it back or adjust their consent.

- Area: Model Fallback
- Names: `/model`
- Tier: You'll notice
- Useful: 4/5
- Signal: 2/5

### 'telemetry' added as a lazily-loaded plugin-runtime module

Plugins can now log analytics events through a new telemetry module

**What**

A new `telemetry` module was added to Claude Code's plugin runtime (the internal system that loads extra capabilities for plugins on demand). It exposes two functions, `$.telemetry.log` and `$.telemetry.mark`, that a plugin can call to send first-party analytics events.

**Why**

This gives plugin authors a supported way to record when their plugin's features are used, without having to build their own analytics pipeline.

- Area: Plugins
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### MCP output/description truncation length now overridable via env var

MCP output and description truncation length is now configurable via CLAUDE_CODE_MAX_MCP_DESCRIPTION_LENGTH

**What**

The character limit used to truncate MCP (Model Context Protocol) tool output and instructions was previously a fixed, hardcoded number. It can now be set with the environment variable `CLAUDE_CODE_MAX_MCP_DESCRIPTION_LENGTH`. If the variable isn't set, Claude Code falls back to the same default length as before.

**Why**

This lets users or teams with MCP tools that produce longer descriptions or output raise the truncation limit instead of being stuck with the built-in default.

- Area: MCP
- Names: `CLAUDE_CODE_MAX_MCP_DESCRIPTION_LENGTH`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### MCP tools can be hidden from the model and marked as account-memory-backed

MCP tools can now be hidden from the model and flagged as backed by account memory

**What**

MCP (Model Context Protocol, the standard Claude Code uses to connect external tools) tools can now carry extra metadata that controls how they show up:

- A hidden-from-model marker that removes the tool from the list the model sees, so it never gets called even though it's registered.

- A `uiMeta` payload carried alongside the tool definition.

- An `accountMemory` flag marking tools that come from account-memory servers.

Building on the earlier `_meta` fields that let MCP tool authors set result-size caps and similar behavior, this adds the ability to keep a tool registered but invisible to the model, and to distinguish account-memory-backed tools from others.

**Why**

This lets MCP server authors register tools that exist for bookkeeping or UI purposes without cluttering the model's tool list or risking it calling them by mistake.

- Area: MCP
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### New `ui.copy` capability added to the plugin/hooks permission surface

New ui.copy capability added to the permission list plugins and hooks can request

**Unclear.** What `ui.copy` actually lets a plugin or hook do is not stated beyond its name.

**What**

The list of capabilities that plugins and hooks (scripts that run automatically at certain points) can be granted now includes `ui.copy`, alongside existing ones like `ui.open`, `ui.close`, `ui.panes`, `ui.blit`, `fs.read`, and `fs.write`.

**Why**

This suggests plugins and hooks can now request permission to copy content to the clipboard as part of their sandboxed capabilities.

- Area: Plugins
- Names: `ui.copy`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### New Artifacts 'preview' action documented

Artifacts gains a preview action that renders a single page locally with screenshots before publishing

**What**

The Artifacts tool now documents a `preview` action. Given a `file_path` pointing at a page file, it renders that one file locally the same way `publish` would wrap it, and returns:

- Screenshots in both light and dark themes

- Screenshots at desktop and phone widths

- A checklist noting any layout or load problems found

This happens before publishing, and it does not need an artifact URL or the artifact runtime, so any capability code in the file does not actually run during preview.

**Why**

This lets a page be checked for how it looks and whether it loads cleanly across themes and screen sizes before it goes live as a published artifact, without wiring up a real runtime environment first.

- Area: Artifacts
- Names: `preview`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### New MCP capabilities advertised: mcp_read_resource_v1, mcp_tool_ui_meta_v1

Claude Code now advertises support for reading MCP UI resources and tool UI metadata, unless disabled locally

**What**

During session setup, Claude Code's client now advertises two additional capabilities to connected servers: `mcp_read_resource_v1` and `mcp_tool_ui_meta_v1`. These are added unless a local flag disables them.

**Why**

Advertising these capabilities lets MCP (Model Context Protocol) servers know that this client can read certain UI-related resources and tool metadata, enabling richer integrations from servers that support them.

- Area: MCP
- Names: `mcp_read_resource_v1`, `mcp_tool_ui_meta_v1`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### New MCP tool `uiMeta` passthrough from `_meta`

MCP tools can now pass a small `ui`-related metadata block through to the tool definition

**Unclear.** The finding does not say what the `ui` field is used for or what the other allow-listed symbol-keyed field is.

**What**

MCP (Model Context Protocol, the standard Claude Code uses to connect external tools) tools can now supply a `uiMeta` value, extracted from an allow-listed subset of the tool's `_meta` field, including a `ui` key. When present, this `uiMeta` is attached to the tool's internal info and then passed back out as `_meta` when the tool definition is built.

**Why**

This lets an MCP tool pass a small piece of UI-related metadata through Claude Code unchanged, so the host application or interface can use it, without that data being altered or stripped along the way.

- Area: MCP
- Names: `uiMeta`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### New mcp_read_resource capability restricted to ui:// URIs

Claude Code can now read MCP resources, but only ones using the ui:// URI scheme

**Unclear.** The finding does not say what ui:// resources are used for or what kind of content they contain.

**What**

Claude Code has gained an internal capability called `mcp_read_resource` that lets it read a resource from an MCP server (Model Context Protocol, a standard that lets Claude Code connect to external tools and data sources). This works through the `resources/read` request, but only for resources whose address (URI) starts with `ui://` — requests for any other scheme are rejected.

Before returning content, the capability runs several checks:

- whether the MCP server is actually connected

- whether the server has been disabled

- whether a policy is blocking the request

- whether the resource is within an allowed size limit

**Why**

This gives Claude Code a controlled way to pull in resources exposed by MCP servers, but keeps it scoped tightly to `ui://` resources rather than opening up arbitrary resource reading, and the added checks stop it from reading from servers that are disabled, blocked, disconnected, or from resources that are too large.

- Area: MCP
- Names: `mcp_read_resource`, `ui://`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### Selected model can now be synced to the organization's server-side default

Claude Code can now push your chosen model to your organization's shared server-side default

**Unclear.** The finding does not say who can trigger this sync (e.g. only admins) or when exactly it fires relative to changing your model.

**What**

Claude Code can now save the model you pick as the default for your whole organization, not just for yourself. It does this by sending an update to the server (a PATCH request to `/api/organizations/:orgUUID/model_selector_state/${scope}`) so the choice is remembered centrally instead of only on your machine.

This only happens under specific conditions:

- the setting being changed is the `primary` scope (your main model choice, not a secondary one)

- the model is currently `served` (actively available for use)

- the change applies at the account level

- the model is not `opusplan` or `opusplan[1m]`, since those special combined modes can't be represented as a single server-side default

**Why**

This lets a model choice made by one person carry over as the shared default for others in the organization, instead of staying local to that one user. The `opusplan` exclusion matters to know about: picking one of those modes will change what you see locally but won't update the organization's default.

- Area: Models
- Names: `/model`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### Self-hosted runner: release now waits for post-turn settling before releasing a session

Self-hosted runner sessions now wait for post-turn settling before being released

**What**

On a self-hosted runner, a session whose turn just finished is no longer released right away if it is still in a "post-turn settling" state. Release is now held until the finished turn has been reported to the server, bounded by a timeout set by `SELF_HOSTED_RUNNER_POST_TURN_SETTLE_MS`.

**Why**

This avoids releasing a session before the server has confirmed the turn actually completed, reducing the chance of the session being reused or reported inconsistently.

- Area: Self-Hosted Runner
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### Three new hidden CLI settings-edit commands for the VS Code extension

Three new hidden CLI commands let the VS Code extension edit skill, sandbox, and Chrome settings

**What**

Three new hidden `claude` subcommands were added, alongside the existing `edit-permission-rules` and `edit-memory-settings`:

- `edit-skill-overrides` reads a JSON edit from standard input (the terminal's input stream) and applies it through `runSkillOverrideEdit`. It validates a skill's `state` field against `on`, `name-only`, `user-invocable-only`, or `off`.

- `edit-sandbox-settings` reads a JSON edit and applies it through `runSandboxSettingsEdit`. A sandbox is an isolated environment Claude Code can run commands in; this validates the sandbox `mode` against `auto-allow`, `regular`, or `disabled`, plus the `allowUnsandboxedCommands` and `excludeCommand` fields.

- `edit-chrome-settings` reads a JSON edit and applies it through `runChromeSettingsEdit`, toggling `claudeInChromeDefaultEnabled`.

These are not meant to be typed by hand; they exist so the VS Code extension can update settings programmatically. All five edit commands, old and new, now refuse to run and return a fixed refusal message when the `CLAUDE_CODE_CHILD_SESSION` environment variable is set, which marks a subprocess Claude Code spawned itself (for example via a Bash or hook command).

**Why**

This extends the settings-editing mechanism the VS Code extension already used for permissions and memory to also cover skills, sandbox behavior, and Chrome integration, and the child-session check prevents these commands from being triggered accidentally from within a nested Claude Code process.

- Area: VSCode Extension
- Names: `edit-permission-rules`, `edit-memory-settings`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### allowManagedHooksOnly now also scopes plugin hooks

allowManagedHooksOnly setting now also restricts which plugin hooks can run

**What**

The managed-settings option `allowManagedHooksOnly` ("Run only the [hooks](/docs/en/hooks) your organization deploys") now covers plugin hooks too. When turned on, only hooks defined directly in managed settings, or hooks belonging to plugins that managed settings explicitly enable, are allowed to run. Hooks from plugins a user installed on their own are excluded, while Claude Code's own built-in features are exempt from this restriction.

**Why**

This lets organizations lock down which hooks can execute more completely, closing a gap where a user-installed plugin's hooks could previously run even with `allowManagedHooksOnly` enabled.

- Area: Hooks
- Names: `allowManagedHooksOnly`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### Custom system prompt updates now apply only after compaction (unless systemPromptSnapshot:false)

SDK custom system prompt updates now apply after the next compaction, not the next turn

**What**

For Claude Code SDK sessions that replace the system prompt via MCP, updating that custom system prompt no longer takes effect immediately. Previously the new prompt text applied starting from the next turn. Now the session keeps using its already-recorded system prompt, and the new text is only sent after the next compaction (the point where Claude Code condenses the conversation history to save space). Setting `systemPromptSnapshot: false` restores the old behavior, applying the new prompt from the next turn.

**Why**

This changes when SDK users should expect a system prompt update to actually reach the model, so anyone relying on immediate effect needs to either wait for compaction or set `systemPromptSnapshot: false`.

- Area: SDK
- Names: `systemPromptSnapshot`
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### 'ask seat' remote-tools wait gated by new env var and renamed flag

Remote tool-approval waiting can now be overridden with a CLAUDE_CODE_REMOTE_TOOLS_ASK_SEATS env var

**Unclear.** Nothing has been read about the `tengu_unified_waterfall` gate for this account, beyond its default of true.

**What**

Claude Code decides whether tool calls should wait on an "ask seat" (a unit of remote approval capacity) using a check that now first reads the `CLAUDE_CODE_REMOTE_TOOLS_ASK_SEATS` environment variable as an override. If that variable isn't set, it falls back to a gate named `tengu_unified_waterfall`, which defaults to true.

**Why**

This gives an explicit environment-variable override for controlling remote tool-approval waiting, useful for configurations that need to force the behavior on or off regardless of the default.

- Flag `tengu_unified_waterfall`: Not enough to say (read for one account on one subscription tier against v2.1.280; this account: no value returned, anonymous baseline: no value returned, compiled default: on) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Remote Tools
- Tier: Use it now
- Useful: 2/5
- Signal: 2/5

### Plugin `$.session.messages` and `$.session.usage` now accept an agentId/as parameter

Plugin session.messages and session.send can now target a specific agent via an agentId/as parameter

**What**

The plugin host operations `$.session.messages` and `$.session.send` now accept an optional `{agentId, as}` argument, where `as` must be `"api"` if it's given at all. Passing this lets a caller scope the call to a particular agent within a session, instead of always operating on the whole session.

**Why**

This lets plugins and SDK integrations work with the messages or output of one specific agent rather than the entire session, which matters when a session involves multiple agents.

- Area: Plugins
- Names: `agentId`
- Tier: Use it now
- Useful: 2/5
- Signal: 2/5

### Max-effort reminder now shown as a warning when a CLI env var/flag is set

Max-effort reminder in the model panel turns into a warning-colored message when a specific env var or flag is set

**Unclear.** Whether the `tengu_proud_clover` gate is switched on for any account is unread, so it's unclear how widely this behavior is actually active.

**What**

When the model's effort level is set to `max`, Claude Code shows a reminder in the model panel. That reminder now appears in warning color (instead of its previous subtler color) when the `CLAUDE_CODE_MAX_EFFORT_REMINDER` environment variable is set.

**Why**

Making the reminder more visually prominent helps users notice they've left the model running at maximum effort, which can mean slower or more expensive responses.

- Flag `tengu_proud_clover`: Not enough to say (read for one account on one subscription tier against v2.1.280; this account: no value returned, anonymous baseline: no value returned, compiled default: off) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Effort
- Names: `CLAUDE_CODE_MAX_EFFORT_REMINDER`
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### CLAUDE_CODE_PLUGIN_DIR_WATCH now overrides fully instead of only disabling

CLAUDE_CODE_PLUGIN_DIR_WATCH now fully overrides whether plugin directory watching is enabled, not just disables it

**What**

Previously, the `CLAUDE_CODE_PLUGIN_DIR_WATCH` environment variable was combined with an internal condition using AND logic, so it could only turn plugin directory watching off, never force it on. Now, when the variable is set, it stands alone and fully decides whether watching is enabled; the internal condition is only used as a fallback when the variable isn't set.

**Why**

This means setting `CLAUDE_CODE_PLUGIN_DIR_WATCH` can now enable plugin directory watching even in cases where the internal check would have kept it off, not just disable it.

- Area: Plugins
- Names: `CLAUDE_CODE_PLUGIN_DIR_WATCH`
- Tier: Use it now
- Useful: 2/5
- Signal: 1/5

### Home/End keys added to a select list, but existing keymap unclear if reachable everywhere

Home and End keys were added to jump to the first or last item in settings/list menus

**Unclear.** Whether these Home/End bindings are wired up in every menu that uses this keymap, or only some of them, isn't clear from the evidence.

**What**

The keymap used for navigating settings and list menus gained two new bindings: `home` jumps to the first item in the list and `end` jumps to the last, alongside the existing j/k and ctrl+p/ctrl+n navigation keys.

**Why**

This gives a quicker way to reach the top or bottom of a long list of items instead of holding down a navigation key repeatedly.

- Area: Terminal UI
- Names: `Home`, `End`
- Tier: Use it now
- Useful: 2/5
- Signal: 1/5

### Home/End keys added to select lists

Home and End now jump to the first or last option in selection lists

**What**

Lists that let you pick from a set of options now support two new keyboard shortcuts:

- `Home` jumps straight to the first option

- `End` jumps straight to the last option

Previously these lists could only be navigated one item at a time.

**Why**

This saves repeated key presses when scrolling through a long list of options, letting you reach either end instantly instead of stepping through every item in between.

- Area: Terminal UI
- Names: `Home`, `End`
- Tier: Use it now
- Useful: 2/5
- Signal: 1/5

### Memory-paused remedy mapping added

Claude Code now maps a paused-memory state to a specific 'memory_paused' remedy internally

**Unclear.** It is unclear what user-visible effect the 'memory_paused' remedy produces.

**What**

A new internal helper function now recognizes when the reason for a memory-related issue is `'paused'`, and maps it to a remedy labeled `memory_paused`. This ties to the `/pause-memory` command, which is used to pause Claude Code's memory feature.

**Why**

This is internal plumbing that lets Claude Code respond appropriately when memory has been paused, rather than treating it as a generic error. It should make behavior around paused memory more consistent, though the finding does not describe exactly what the remedy causes to happen on screen.

- Area: Memory
- Names: `/pause-memory`
- Tier: Use it now
- Useful: 2/5
- Signal: 1/5

### New Settings-menu keybindings: Home/End

Settings menu now supports Home and End keys to jump to the first or last item

**What**

In the Settings menu, pressing `Home` now jumps selection to the first item and `End` jumps to the last item, alongside the existing up/down arrow, `j`/`k`, and `ctrl+p`/`ctrl+n` navigation.

**Why**

This makes it faster to jump to the top or bottom of a long settings list instead of scrolling through every item.

- Area: Terminal UI
- Names: `Home`, `End`
- Tier: Use it now
- Useful: 2/5
- Signal: 1/5

### Self-hosted runner: session-scoped git config for lifecycle hooks

Self-hosted runner sessions now get their own git config so lifecycle hooks use separate signing and protocol rules from the main checkout

**What**

When `--configure-git` is used to let the runner set up git, session setup now writes a separate, session-scoped git configuration specifically for git commands run by lifecycle hooks (scripts that run automatically at points in a session's life), stored under a `hooks` subdirectory. This includes:

- `core.hooksPath`, pinned for the session

- The gpg and ssh programs used for commit signing

- `GIT_ALLOW_PROTOCOL`, controlling which network protocols git is allowed to use

This configuration is kept separate from the git setup used for the main repository checkout.

**Why**

Giving lifecycle hooks their own pinned git configuration, rather than sharing whatever the main checkout uses, means hook scripts get consistent, session-scoped signing and protocol restrictions regardless of what the checkout's git setup looks like. This matters for self-hosted runner setups using `--configure-git`, where SSH commit signing requires Git 2.34 or later.

- Area: Self-Hosted Runner
- Tier: Use it now
- Useful: 2/5
- Signal: 1/5

### Settings/artifacts list gains select:first and select:last keybindings

Settings and artifacts lists now support jumping to the first or last item with select:first and select:last

**What**

The list navigation used in Claude Code's settings and artifacts screens now supports two new keybinding actions, `select:first` and `select:last`, which jump straight to the top or bottom of the list, in addition to the existing previous/next navigation.

**Why**

This makes it faster to reach the ends of a long settings or artifacts list without stepping through every item.

- Area: Terminal UI
- Names: `select:first`, `select:last`
- Tier: Use it now
- Useful: 2/5
- Signal: 1/5

### disableAllHooks setting description clarified to scope hooks only

disableAllHooks setting now explains it only turns off custom hooks and statusLine, not Claude Code's built-in features

**What**

The description for the `disableAllHooks` policy setting has been expanded to spell out exactly what it covers: hooks defined in settings files, hooks added by installed plugins, and `statusLine` execution. It now explicitly states that features built into Claude Code are not hooks in this sense and keep working, since each of those has its own separate switch.

**Why**

This clears up potential confusion about the scope of `disableAllHooks`, making clear it's a switch for custom/plugin hooks and the status line specifically, not a master switch for every Claude Code feature.

- Area: Settings
- Names: `disableAllHooks`
- Tier: Use it now
- Useful: 2/5
- Signal: 1/5

## New Features

### New DeviceReenrollDialog lazy-loaded UI flow

Claude Code adds a new DeviceReenrollDialog for handling expired or invalidated device credentials

**Unclear.** It's not confirmed what triggers this dialog or exactly what re-enrollment flow it walks the user through, since only the component's existence and loading pattern are evidenced.

**What**

A new dialog component called `DeviceReenrollDialog` has been added, loaded lazily (meaning its code is only downloaded and run when it's actually needed, rather than at startup) using the same pattern as other login and session dialogs like `RemoteHomeSettingsDialog` and `SyncOfferCheck`.

**Why**

The naming and pattern suggest this dialog prompts a user to re-register their device when its existing credentials have expired or become invalid, though the finding does not describe when it actually appears or what a user sees in it.

- Area: Device Enrollment
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

## Improvements

### Remote tool calls now get late-outcome corrections told back to the model

Claude Code now follows up on remote tool calls it had given up on and tells the model what really happened

**What**

Some tool calls run on a remote or background machine rather than locally, and Claude Code can lose track of them if that machine stops responding in time. Previously such a call would just be abandoned. Now a new tracker keeps a record of these given-up-on calls and periodically checks back with the remote host to see what became of them.

If the host eventually answers, Claude Code injects a "Correction:" message into the conversation telling the model the real outcome, for example that the call:

- was actually still running on the remote machine

- ended with its state unknown because that machine stopped answering

This is tracked internally through a telemetry event called `tengu_remote_tool_targets`, which now records stages like `given_up`, `late_outcome`, `given_up_expired`, and `correction_emitted`.

**Why**

Without this, the model could keep acting on the wrong assumption that an abandoned remote tool call simply failed or vanished, when it may have finished or kept running elsewhere. Getting a late correction lets the model adjust its understanding of what actually happened instead of working from stale information.

- Area: Remote Tools
- Tier: You'll notice
- Useful: 3/5
- Signal: 3/5

### Teammate messages are now flagged verified/forged/unverifiable

Messages from teammates are now checked and marked verified, forged, or unverifiable

**What**

Claude Code now checks each message from a teammate (another Claude Code instance working alongside you, such as in a shared pane) against who it claims to be from, and marks it as:

- `verified` — the message ID matches what the claimed sender actually wrote

- `forged` — the sender claim doesn't check out

- `unverifiable` — there's no way to confirm the claimed sender is a legitimate in-process or leader-pane teammate

When a message marked `forged` is packaged up and sent into the conversation, its envelope now includes a `verified="false"` attribute next to the teammate's ID.

**Why**

This lets Claude Code and, ultimately, the model itself distinguish trustworthy teammate messages from ones whose origin can't be confirmed, guarding against a message being falsely attributed to a teammate.

- Area: Teammates
- Tier: You'll notice
- Useful: 3/5
- Signal: 3/5

### New auto mode failure/blocking messages tied to a safety verdict system

Auto mode now has messages for when it can't get a safety verdict and gives up or blocks an action

**Unclear.** The finding does not say what triggers a missing safety verdict or what user-facing experience (e.g. UI, logs) surfaces these messages.

**What**

Claude Code's 'auto mode' has two new failure messages tied to a safety verdict system, which checks whether an action is safe before auto mode proceeds:

- One message appears when auto mode stops after repeatedly responding without ever producing a safety verdict, marking it as unavailable ('automode-unavailable') and recording this as the reason an agent got blocked.

- The other message appears when auto mode is unable to evaluate an action at all, so it blocks the action rather than allow something unchecked.

**Why**

These messages make it clear to the user when auto mode has stopped working or blocked something because it couldn't confirm an action was safe, rather than failing silently or without explanation.

- Area: Auto Mode
- Tier: You'll notice
- Useful: 3/5
- Signal: 3/5

### New abort reason: permission-stop

New 'permission-stop' abort reason lets Claude Code cleanly cancel work when a permission prompt is stopped

**What**

Claude Code has a set of recognized reasons for aborting or interrupting in-progress work (alongside existing ones like `interrupt`, `turn-abort`, and `refusal-fallback-edit`). A new reason, `permission-stop`, has been added, with its own error mapping and several places in the code now treating it distinctly from a plain user interrupt.

- Aborting with `permission-stop` does not surface an error to the user, the same as a plain `interrupt` does not.

- Deciding what happens after a task or agent stops now has a separate code path for `permission-stop`, apart from the existing `interrupt` handling.

- `permission-stop` is now reported to telemetry under the label `turn_teardown`.

**Why**

This gives Claude Code a way to cancel in-flight work specifically because a permission prompt was stopped or cancelled, without treating it as a generic interrupt or showing an unnecessary error.

- Flag `tengu_fizzy_grove`: Not enough to say (read for one account on one subscription tier against v2.1.280; this account: no value returned, anonymous baseline: no value returned, compiled default: off) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Sessions
- Tier: You'll notice
- Useful: 3/5
- Signal: 3/5

### Control requests can now jump the upload queue

Certain control requests can now jump ahead of the normal upload queue

**Unclear.** Whether this behavior is active for a given reader cannot be determined here: the `tengu_valiant_rain` flag controlling it (servedCallRequestsJumpQueue) was read as on for both this site's account and the anonymous baseline, but that reading was not taken under this release.

**What**

In the client component that uploads session events, certain `control_request` and `control_cancel_request` events can now be pulled into an "urgent" queue and sent immediately, ahead of the normal batch of queued events. Which request IDs have been sent this way is tracked in a bounded set so they aren't sent twice.

**Why**

This lets time-sensitive control messages reach the server faster instead of waiting behind whatever else is queued for upload.

- Flag `tengu_valiant_rain`: Off by default, switched on for this account (read for one account on one subscription tier against v2.1.280; this account: on, anonymous baseline: on, compiled default: off) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Telemetry
- Tier: Under the hood
- Useful: 2/5
- Signal: 3/5

### Rewind/fork snapshot restore now detects worktree changes since the snapshot was read

Rewind/fork restore now refuses to apply a snapshot if worktree files changed since it was taken

**What**

Rewind and fork let you restore a project's files to an earlier saved snapshot. The restore logic now compares the snapshot's recorded file states against the current state of the working files (the worktree) before applying it. If any tracked file, or its file metadata, changed after the snapshot was taken, the restore is refused with a "not applied" result and reason `worktree_changed`, instead of applying a now-stale snapshot on top of newer changes.

**Why**

This prevents rewind or fork from silently overwriting file changes made after a snapshot was captured, which could otherwise cause quiet data loss.

- Area: Sessions
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### Attached-machine tool guidance now supports PowerShell, not just Bash

Guidance shown for machines attached to a session now covers PowerShell, not just Bash

**What**

When another machine is attached to a Claude Code session, Claude Code shows internal guidance describing how to run commands remotely on it. This guidance now recognizes PowerShell (Microsoft's command-line shell, run as `pwsh`) as an option alongside Bash, and adjusts its wording depending on which shell or shells the attached machine actually supports. For PowerShell specifically, it points to commands like `Get-Content` (read a file), `Select-String` (search text), and `Set-Content` (write a file) as the equivalents of familiar Bash tools.

Separately, the guidance now also describes a 'coordinator' framing for cases where the session can spawn Task workers (sub-agents that handle pieces of a job).

**Why**

This makes remote execution guidance accurate for Windows machines running PowerShell, rather than assuming Bash is always available on an attached machine.

- Area: Remote Control
- Names: `pwsh`
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### Cloud commits not yet fast-forwarded into linked worktrees

Claude Code now tells you when cloud commits haven't been fast-forwarded into a linked local folder

**What**

When you work with a cloud session that's linked to a local working folder (a "worktree"), Claude Code can now show a specific status message explaining that commits made in the cloud session have not been fast-forwarded (merged forward) into your local working tree yet. Those commits stay in the cloud session's own history for now.

Your files on disk are still kept up to date even while this message shows.

**Why**

This makes it clearer why your local git history might not yet show commits you can see in a linked cloud session, even though the actual file contents match.

- Area: Cloud Sessions
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### Dir-sync capture gets a 'kept_here / file_store_full' outcome

Cloud session directory sync now has a 'kept here' fallback when there are too many or too large pending changes

**Unclear.** What practically happens to the session or its files once this 'kept_here' fallback triggers is not described beyond the label.

**What**

For cloud and "teleport" sessions (which sync your working directory to run elsewhere), the directory-sync system now has a new outcome: `kept_here` with reason `file_store_full`. This triggers when a pending snapshot of changes has 200 or more changed files, or exceeds a byte-size limit, rather than the system always trying to ship the changes or failing outright.

**Why**

This gives large or heavily-changed directories a graceful fallback instead of a hard failure when there's too much to sync at once, though the finding doesn't specify what happens to those changes once they're "kept here."

- Area: Directory Sync
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### Cloud/teleport session creation adds a device re-enrollment confirmation step

Creating a cloud session now asks for confirmation before re-enrolling your device

**What**

When creating a cloud or "teleport" session interactively, Claude Code now shows a confirmation prompt asking whether you want to re-register (re-enroll) your device, rather than doing so silently. This confirmation step runs unless the session creation was already cancelled.

**Why**

This gives users a chance to confirm before their device is re-enrolled during cloud session setup, rather than it happening without notice.

- Area: Device Enrollment
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### Context-usage metadata reporting reworked to reduce flicker/inaccuracy

Context-usage reporting now waits briefly for a real token count instead of always estimating

**What**

The reporting of context-window usage (how much of the model's available context has been used) has been rewritten around a new shared component that tracks both measured and estimated token counts. It adds a `reportAtTurnEnd` step that, at the end of a turn, waits briefly for a real measured token count before reporting; if that wait times out, it falls back to an estimate instead.

**Why**

Previously reported usage numbers could flicker between estimated and measured values or be briefly inaccurate. Waiting for a real count when possible, with a timeout fallback, should make usage indicators (such as a status bar) more stable and accurate without introducing a noticeable delay.

- Area: Context Usage
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### MCP tool-search reminder now checks a needs-auth condition

Claude Code now flags MCP tools that need authentication when reminding about tool search

**What**

MCP (Model Context Protocol, the standard Claude Code uses to connect to external tool servers) tool entries are now checked for a 'needs-auth' status. A new helper filters down to tools that need authentication and haven't already been handled, and surfaces an `mcp_needs_auth` signal listing the affected server names when any are found.

**Why**

This lets Claude Code notice and surface MCP servers that require authentication before their tools can be used, rather than silently leaving them unusable.

- Area: MCP
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### Settings validation now warns about invalid values instead of silently misbehaving

Claude Code now warns when a settings.json value fails validation instead of silently ignoring it

**What**

A new validation pass checks settings values and flags keys whose configured value doesn't pass validation. It also distinguishes between a setting that "counts as off" versus one that "counts as unset" as a result of the invalid value, and suggests fixing it through `/config` or deleting the key entirely.

**Why**

Previously an invalid setting value could silently misbehave with no indication of the cause. Now you get a clear warning and a concrete way to fix it.

- Area: Settings
- Names: `/config`
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### New early-upload ('created_empty') recovery path for cloud/remote-control sessions when dir sync can't seed files

Cloud sessions can now upload a first-time project snapshot when directory sync isn't ready yet

**What**

When a cloud or remote-control session is created before its usual git-based directory sync can start, Claude Code now builds and uploads a 'first upload' bundle of the local project directory directly, instead of leaving the session without files. This path:

- Falls back to cloning the project from GitHub if needed

- Reports clear refusal reasons when it can't proceed, including an unborn branch, a shallow or partial local clone, an oversized history, timeouts, or files withheld because they're covered by Read rules, sandbox read-deny settings, or look like credentials

- Archives the session and shows a clear message, such as "File sync was switched off while the session was being created," if the upload can't be completed in time

A new environment variable, `CLAUDE_CODE_DIR_SYNC_ENGINE=none`, lets a machine disable directory sync entirely.

**Why**

Previously, a cloud session created before directory sync was ready could end up with no files and no clear explanation. This gives users an actual snapshot of their project in that situation, or, if that's not possible, a specific reason why instead of a silent failure.

- Area: Cloud Sessions
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### Opus 5.5 model reference appears in the model picker UI

The model picker now applies its special styling to "Opus 5.5" instead of "Fable 5.1"

**Unclear.** The finding does not say whether Opus 5.5 is an available or announced model, only that its name now appears in this styling code.

**What**

The model picker's description formatting, which applies special styling and strikes through a promotional price for one particular model, now targets "Opus 5.5" instead of "Fable 5.1", matching a new model ID, `claude-opus-5-5`, that appears in the system prompt.

**Why**

This is a UI update reflecting a new model reference, `Opus 5.5`, showing up in Claude Code's model picker.

- Area: Models
- Names: `claude-opus-5-5`
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### Cloud/teleport bundle upload blocked for HIPAA organizations

Cloud sessions can no longer upload a local working tree for HIPAA-regulated organizations

**What**

Starting a cloud or teleport session (running Claude Code on a remote machine) by uploading a bundle of your local working tree is now blocked for organizations under a HIPAA compliance policy. Instead of proceeding, Claude Code tells the user that uploaded-copy sessions aren't available for HIPAA-regulated organizations and to start the session from a GitHub repository source instead.

**Why**

This prevents HIPAA-regulated organizations from starting cloud sessions in a way that may not meet their compliance requirements, steering them toward starting from a GitHub repository instead.

- Area: Compliance
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### Device re-enrollment flow when a device key conflict is detected

Claude Code can now re-register a device when its saved key conflicts with a stored one

**What**

Claude Code links a local computer (a "device") to your account by storing a device key. Previously, if that registration failed because a different key was already stored for the device, there was no way to recover. Now Claude Code detects this key conflict and asks you to confirm re-registering the device. If you confirm, it retires the old stored key (retrying that removal a bounded number of times if needed) and then re-binds the device with a new key.

**Why**

This fixes a dead end: a device whose stored key had gotten out of sync with the account could previously fail to register with no recovery path. A `tengu_device_reenroll` telemetry event records whether you confirmed the re-enrollment, so this new flow can be tracked.

- Area: Device Enrollment
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### Cloud/remote-session file sync gets cryptographic tamper verification

Cloud and remote-session file sync now cryptographically verifies that synced git data hasn't been tampered with

**What**

Claude Code adds a large set of new functions that verify git commits, trees, and objects built for syncing files during cloud or remote sessions read back as exactly what their content hashes claim. If they don't match, sync now reports a distinct "tampered" status instead of silently proceeding. Before uploading working-tree state, this process also builds a scratch index and tree that filters out uncommitted files that look like credentials, such as `.env`, `.npmrc`, `.pem` files, SSH keys, and AWS, Azure, GnuPG, or Kubernetes config files.

**Why**

This protects cloud and remote sessions from syncing corrupted or tampered file data, and reduces the risk of accidentally uploading sensitive credential files that hadn't been committed.

- Area: Cloud Sessions
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### Write tool now refuses to write through a symlink, pointing at the real target

The Write tool now refuses outright to write through a symlink, pointing to the real target path instead

**What**

When a path Claude wants to write to resolves through a symbolic link (a file that points to another location), the Write tool now refuses the write outright with a message telling the user to write to the link's actual target path instead. Previously this either followed the link silently or asked for permission.

**Why**

This prevents writes from being silently redirected through a symlink to an unexpected location, and makes the real destination explicit instead.

- Area: File Editing
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### Read/write permission messages now say when a path resolves outside the working directory via a symlink

Permission prompts for reads/writes now say when a path escapes the working directory through a symlink

**What**

When Claude Code asks permission to read or write a file, it now checks where the path actually points after following any symlinks (shortcuts that redirect to another location). If that real location falls outside the allowed working directories, the permission prompt now says the path 'resolves through a symlink to' the outside location, instead of just naming the original path. If the symlink chain can't be resolved at all, the request is denied outright rather than asked about.

**Why**

This makes it clearer when a file that looks like it's inside your project actually points somewhere else, so you can make an informed decision before granting access.

- Area: Permissions
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### Settings/mode dialogs now require a second Escape press to close, with on-screen prompt

Settings dialogs now need Escape pressed twice to close, with an on-screen hint

**What**

Several settings dialogs, including the mode picker, sandbox settings, and the cloud-session confirmation panel, no longer close on a single press of Escape. Instead they show a "Press [key] again to close" (or "cancel") prompt, and require pressing the key a second time to actually dismiss the panel.

**Why**

This prevents accidentally closing these panels with a single stray Escape press, at the cost of needing an extra keypress to close them intentionally.

- Area: Dialogs
- Names: `Escape`
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### New 'safeguards flagged' messaging tailored to Opus 5.5

Opus 5.5 gets its own tailored explanation when a message is flagged by safeguards

**What**

When a message is flagged by Anthropic's safety systems and the model in use is claude-opus-5-5, Claude Code now shows tailored explanatory text instead of the older generic message. The new text has separate wording for cyber-related, biological, and general "frontier model" categories, and notes that this may be the first time a user encounters such a flag on an Opus model.

**Why**

This gives users flagged on Opus 5.5 a clearer, more specific explanation of why their message was refused or answered by a fallback model, rather than a generic notice.

- Area: Permissions
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### Bash tool enforces a hard sandbox requirement for remote/SDK-issued calls

Bash/PowerShell now refuses remote-issued commands if a fully confining sandbox can't be confirmed

**What**

When a command is sent to the `Bash` (or PowerShell) tool remotely and it's marked as requiring a sandbox (a restricted environment that limits what a command can touch), Claude Code now checks that a fully confining sandbox is actually available before running it. If it can't confirm one, it refuses to run the command at all, rather than running it unconfined.

**Why**

This closes a gap where a remote or SDK-issued command marked as needing sandboxing could previously run without real confinement if a sandbox wasn't actually in place. Now it fails safely instead of silently executing with fewer protections than expected.

- Area: Sandbox
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### Cloud /diff dialog now shows committed changes ahead of the merge-base together with uncommitted ones

The cloud /diff dialog now shows committed changes ahead of the merge-base alongside uncommitted ones

**What**

The `/diff` view (the panel showing changed files and their edited sections, or hunks) has changed how it works in Claude Code's cloud environment. Previously, when you were on a branch with commits already made beyond the session's base branch (or the default branch), `/diff` only showed uncommitted working-tree changes compared to HEAD. Now it merges both kinds of changes into a single view: committed changes ahead of the base branch are shown together with uncommitted changes, with the uncommitted rows listed first.

**Why**

This means `/diff` in the cloud gives a fuller picture of everything that's changed in a session, not just what hasn't been committed yet, so you no longer need to check committed history separately to see the full scope of edits.

- Area: Cloud Diff
- Names: `/diff`
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### New cheaper cost table for claude-opus-5-5

A new, cheaper token-cost tier now applies to the claude-opus-5-5 model id

**What**

Claude Code now returns a separate, cheaper set of token costs for the model id `claude-opus-5-5`, distinct from the pricing used for `claude-opus-4-8` and `claude-opus-5`. The new tier covers input tokens, output tokens, prompt cache writes (both standard and 1-hour cache writes), and prompt cache reads.

**Why**

If your account uses `claude-opus-5-5`, cost tracking and any cost-based logic in Claude Code will reflect these lower rates rather than the rates applied to the other Opus model ids.

- Area: Pricing
- Names: `claude-opus-5-5`
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### New "computer removed from devices" re-enrollment prompt

A new prompt appears if your computer's device registration was revoked on claude.ai, letting you re-register or continue cloud-only

**What**

Claude Code can now detect when a computer's registration with Anthropic's cloud agent system has been revoked from claude.ai (the message reads "This computer was removed from your devices"). When this happens, a new interactive prompt appears offering two choices:

- register the computer again

- continue for this session using cloud-only mode instead

**Why**

This gives you a clear way to recover when a computer loses its device registration, instead of leaving cloud-agent features silently broken. You can either restore full functionality by re-enrolling or keep working in cloud-only mode without interruption.

- Area: Device Enrollment
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### Memory sync now caps mass deletion of synced files

Claude Code now refuses to bulk-delete synced memory files past a threshold and asks you to wait for sync to catch up

**What**

Claude Code's memory files (notes it keeps in sync across sessions) are now protected from mass deletion. A new check, internally called `massDeleteHoldExposure`, watches for cases where too many synced memory files would be removed or found missing at the same time. When that threshold is crossed, the deletion is blocked and all the affected files are restored, with a message telling you to wait about a minute for sync to catch up before trying again.

**Why**

This guards against losing a large batch of memory files at once, whether from a sync hiccup or an unintended bulk operation. If you hit the refusal message, it means the safeguard kicked in rather than something being broken; waiting briefly and retrying should resolve it.

- Area: Memory
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### New 'first upload' bundling path for teleporting to cloud sessions, plus a notice when repo settings try to control it

Teleporting to a cloud session can now seed it from a 'first upload' instead of a full bundle, and repos can no longer control bundle seeding via committed settings

**Unclear.** Whether the 'first upload' path actually makes teleporting faster or otherwise changes the user-visible experience beyond the outcome handling isn't stated.

**What**

Starting a cloud session ("teleporting to remote") now has a new fast path that can seed the new session from an initial "first upload" of files, before falling back to the older full bundle-and-clone process if needed. This includes a `created_empty` outcome for when the session starts with nothing to upload, with its own handling for that case.

Separately, if a repository's committed `.claude/settings` files try to set keys related to bundle seeding, Claude Code now shows a notice that these are ignored. Bundle seeding is treated as a setting that belongs to the machine owner, not something a repository can control.

**Why**

The new upload path is meant to make opening a cloud session faster in the common case. The settings notice prevents a shared repository configuration from silently overriding how a given machine seeds its own cloud sessions, and tells the user clearly when that's happening.

- Area: Cloud Sessions
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### Cloud/remote sessions (teleport) can now seed from a 'first upload' of the local checkout when there's no git remote

Remote sessions can now seed from a first upload of your local files when there's no git remote

**What**

When starting a cloud or remote session (teleport) for a project that has no GitHub remote and no bundle, Claude Code can now seed the session from a 'first upload' of your local working directory instead. The created session records this as its source, and Claude Code now tracks how many bytes were uploaded, how long it took, and whether the upload was 'detached' (not tied to a specific commit).

- The 'no repository detected' warning now only appears if there is neither a bundle nor this first-upload path available.

**Why**

This lets remote sessions start from your actual local files even when there's no git remote to sync from, instead of just warning that no repository was found.

- Area: Cloud Sessions
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### Linked git worktrees can now be uploaded for cloud/teleport sessions

Cloud/teleport session uploads now support git linked worktrees

**What**

When Claude Code uploads a git bundle to seed a cloud or "teleport" session, it now explicitly handles linked git worktrees (a working directory checked out separately from the main repository copy). This includes:

- correctly locating the private admin directory for a linked worktree

- withholding credential files from the upload (`neverReadFor`)

- recording new telemetry, including a `linked_worktree` field

**Why**

Before this, starting a cloud or teleport session from a linked worktree likely didn't work correctly or safely; this makes that path explicit and keeps credentials out of the uploaded bundle.

- Area: Git Worktrees
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### Large rework of cloud/background session git-checkout snapshotting with new tamper-detection

Cloud session git snapshotting reworked with new checks that detect tampering and refuse to continue

**What**

The pipeline that builds file-sync snapshots of your working tree for cloud/background sessions has been substantially reworked. It now explicitly detects and refuses to proceed in several situations:

- a symlink planted inside the git directory

- the object store starting to borrow from another repository's objects (via `objects/info/alternates`) partway through a session

- the git directory having moved or been replaced

- files that are covered by read-deny or sandbox rules, or that are "named like a credential under another spelling"

Each case produces a specific explanation telling the user to start a new cloud session.

**Why**

This closes off ways a working tree could be tampered with or could leak protected files during a cloud session, and gives users a clear signal to restart the session when something looks wrong instead of silently continuing with a compromised snapshot.

- Area: Cloud Sessions
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### SearchPlugins gets a more assertive, proactive prompt variant

SearchPlugins now proactively searches your org's plugin catalog for work-related tasks, not just when a plugin is named

**What**

The `SearchPlugins` tool has a new, more assertive prompt. Previously the model needed the user to name a plugin to search for one; now it is told to search the organization's claude.ai plugin catalog on its own whenever a task depends on the team's own process, systems, or data and nothing already available covers it. Example triggers listed include requests like "ship this to staging", "review this contract against our playbook", and "which deals close this week?"

The prompt also tells the model not to search for one-off questions, and not to search again after the user has already ignored a suggested plugin.

**Why**

This means Claude Code may now suggest or reach for an organization's own plugins more readily during a task, without waiting to be asked by name, while avoiding repeated or unwanted suggestions once one has been declined.

- Area: Plugins
- Names: `SearchPlugins`
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### New 'created_empty' cloud-session container-race path with a 90s ceiling

Cloud sessions can now start instantly with an empty container while files sync in the background, up to a 90-second limit

**Unclear.** It's unclear what triggers the `created_empty` path versus the normal path, and the exact ceiling value isn't confirmed for this release.

**What**

When creating a remote or "teleport" cloud session, Claude Code can now take a `created_empty` path: it starts the session right away with an empty container instead of waiting for files to be copied in, then races a background process that seeds the container with your git files against a time limit.

- If the background seeding finishes in time, the session proceeds as normal, just reporting that it's ready (and recording directory-sync telemetry) later than before.

- If the seeding times out or fails, Claude Code discards the pending first file upload rather than leaving it in a stuck state.

**Why**

This lets a cloud session start responding sooner instead of blocking on the container being fully populated first, while still falling back cleanly if the background file sync doesn't finish in time.

- Area: Cloud Sessions
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### New safety cap blocks bulk `rm` of synced memory files from Bash

Claude Code now blocks Bash `rm` commands that would delete too many synced memory files at once

**What**

The Bash tool's input check now scans `rm` commands before they run. It looks at the literal file targets named in the command and asks the session's memory-sync system whether running it would delete more synced memory files at once than a set limit allows. If it would, the command is refused with an explanatory error instead of being executed.

Memory sync already holds off on removing files when too many synced files go missing at the same time, and restores them; this check stops a single `rm` command from tripping that threshold in the first place.

**Why**

This guards against an `rm` command (run directly, or written by Claude) accidentally wiping out a large batch of synced memory files in one shot, which previously could go through and then rely on the sync system's recovery step after the fact.

- Area: Memory
- Names: `rm`
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### Remote-tool protocol mismatch message now points to an alternate serving host

Remote-tool version mismatch errors can now suggest another attached machine that can run the tool

**What**

When two Claude Code installations don't agree on the protocol version for a remote tool (a tool served from another attached machine rather than run locally), Claude Code shows an error. That error can now name a different attached machine that can serve the same tool, instead of only telling you to remove the host targeting field.

**Why**

This gives a more useful next step when a version mismatch blocks a remote tool call: rather than just clearing the host setting, you may be pointed at another machine that can actually run the tool.

- Area: Remote Tools
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### Artifact database writes can now carry a request_id for safer retries

Artifact database writes can now include a request_id so retries after a failure aren't duplicated

**What**

When Claude Code writes to the artifact database (both single and batch writes), it can now attach a `request_id` to the request so the server can recognize if the same request was already received, for example after a retry. If the server says it doesn't support the `request_id` field, Claude Code removes it and retries once, then remembers that refusal for a cooldown period so it doesn't keep sending a field the server will reject.

**Why**

This makes retried artifact writes safer by letting the server tell duplicate requests apart from new ones, while avoiding wasted retries against servers that don't support the feature.

- Area: Artifacts
- Names: `request_id`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Compaction record now carries explicit usage stats

Compaction records now include detailed token usage stats, not just before/after totals

**What**

When Claude Code compacts a conversation (summarizing it to free up context space), the record it produces now includes a `usage` field with detailed token usage statistics, taken from the compaction call's own usage data. This is in addition to the existing `tokensBefore` and `tokensAfter` fields. The same addition applies to the result object produced by automatic (reactive) compaction.

**Why**

This gives more detailed visibility into token usage during compaction, beyond the simple before-and-after totals that were already recorded.

- Area: Compaction
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### System prompt now tells Claude when the user is on a cloud session viewed only in the Claude app

Claude now knows when a user is viewing a cloud session only through the Claude app and limits which files it presents as openable

**What**

When a session is a cloud session (one running remotely) being followed through the Claude phone or desktop app, Claude Code now tells the model this directly. In that situation, the user can only open files that live inside the main working directory, or in the scratchpad and memory directories if the session has them. Claude is instructed not to present other file paths as things the user can open.

**Why**

This keeps Claude from pointing users at files they have no way to actually open from the Claude app, avoiding confusing dead-end references during a followed cloud session.

- Area: Cloud Sessions
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### New safety-monitor cancellation message for tool calls

New message explains when a safety monitor cancels a tool call mid-turn

**What**

Claude Code now shows a specific message when a tool call is cancelled partway through by a safety monitor: "A safety monitor blocked this turn, so this tool call was cancelled. If it had already started, some of its effects may have happened." A new helper also detects this specific type of API error.

**Why**

This gives users and Claude a clear, specific explanation when a safety monitor interrupts a tool call, including the important warning that some effects of the cancelled call may already have taken place.

- Area: Permissions
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### MCP claude.ai-proxy discover projection now 'remembers' a legacy peer across dials

Claude Code now skips re-checking an MCP server it already found to be a legacy peer

**What**

For `claudeai-proxy` MCP (Model Context Protocol, a way Claude Code connects to external tools) servers, Claude Code now remembers when an earlier connection attempt found the other side to be a legacy (older, pre-modern) peer. Once that happens for a given connector, later connection attempts skip the server-discovery round trip entirely instead of re-checking the cached server list each time. A new log line and negotiation-mode outcome, `remembered_legacy`, records when this shortcut is taken.

**Why**

This avoids redundant network round trips to a server already known not to support the modern discovery protocol, which should make repeated connects to that server faster.

- Area: MCP
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### Model effort-level resolution changed for userSettings source

Model effort level from user settings alone is no longer always honored automatically

**Unclear.** What the new model check specifically verifies, and which configurations are affected in practice, is not stated in the evidence.

**What**

When Claude Code works out the effective `effortLevel` (a model's effort setting) for a model, a value coming only from the `userSettings` source is now only used if either another, non-`userSettings` source also matched for that model, or a new internal check for the model passes. Previously, any `effortLevel` found in `userSettings` was used directly.

**Why**

This tightens when a user-settings-only effort level actually takes effect, which changes which effort level a model ends up using in some configurations.

- Area: Elsewhere
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### Private git-directory sync gets tamper detection

Claude Code now detects tampering with a working tree's private git directory and refuses to run

**What**

Claude Code has a new subsystem that builds and reuses a private, admin-only git directory for a working tree. It now detects when a tree's `.git` directory has been moved, replaced, turned into a symlink, or points at object stores it doesn't own, and refuses to run git commands against that tree when this kind of tampering is found.

**Why**

This protects against git operations running against a working tree whose git metadata has been unexpectedly altered or swapped out, which could otherwise lead to operating on the wrong data without warning.

- Area: Git Sync
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### Plugin side-panel 'ask' state now tracked per-panel with width-aware placement

Plugin side panels now track their asked/dismissed state individually and adjust to terminal width

**What**

Claude Code now tracks, per plugin side panel, whether the user has already been asked about it or has dismissed it (via new `pluginPanes.asked` state). Placement of a panel is also gated on how wide the terminal window is: panels that don't fit below a size threshold are marked as "not placed" and show a message explaining that they'll open once the terminal is widened or the user reopens them.

**Why**

This keeps plugin panels from prompting repeatedly once dismissed and avoids trying to cram a side panel into a terminal window that's too narrow to show it properly.

- Area: Elsewhere
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### Cloud session sync: new 'file store full' failure reason

Cloud session sync now reports a specific 'file store full' error when the upload lane fills up

**What**

When syncing a cloud or background session's files, Claude Code now recognizes a `lane_full` response from the server (shown internally as `file_store_full`) and displays a clear message telling you the session's cloud file store is full, explaining that Claude will keep working on your machine directly. This joins other existing sync failure reasons like `refused`, `too_large`, and `withdrawn`, and falls back to local-only operation the same way those do.

**Why**

This gives a clearer, specific explanation when a cloud session can't sync because its upload capacity is full, instead of a generic failure, while still letting work continue locally.

- Area: Cloud Sync
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### Exit-confirmation dialog gains an 'exit detaches to caller' mode

The exit-confirmation dialog gains a mode where exiting detaches instead of ending the session

**Unclear.** The exact wording or visual change to the dialog copy is not stated, only that the flag changes behavior.

**What**

The dialog shown at the bottom of the screen when exiting or interrupting Claude Code now accepts an `exitDetachesToCaller` flag. This changes its behavior for sessions that were launched by another session, such as a teammate or caller session, so that exiting detaches from that parent instead of terminating.

**Why**

This avoids accidentally terminating a sub-session that another session depends on; exiting it now hands control back to the caller instead of ending it outright.

- Area: Session Management
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### Background command 'failed' status no longer distinguishes non-zero exit code

Background command status now marks 'failed' based only on presence of a result, not on a non-zero exit code

**Unclear.** The finding does not say what visible effect this has, such as whether commands that previously showed as failed now show as succeeded or vice versa.

**What**

The logic that marks a background command or task entry as `failed` has changed. Previously it checked whether the command produced a result and whether that result's exit code was non-zero. Now it only checks whether a result exists at all, without looking at the exit code.

**Why**

This changes when background commands are reported as failed versus succeeded, since a non-zero exit code alone no longer determines the failed state.

- Area: Background Tasks
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### New UI hint referencing claude.ai projects

New hint text points users to ask Claude to work in a folder from their claude.ai projects

**Unclear.** The finding does not confirm exactly where or in what flow this hint is shown, only that it is likely tied to remote-control or mobile connection hints.

**What**

A new piece of interface text has been added: "Or ask Claude to work in this folder from your projects on claude.ai". It appears to be shown alongside hints about connecting remote control or the mobile app.

**Why**

This surfaces claude.ai projects as another way to point Claude at a specific folder, likely as part of onboarding or connection prompts.

- Area: Remote Control
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### New "created empty, never filled" state for cloud-session folder sync

Cloud session folder sync now reports when a session was created empty and never got its first upload

**What**

When attaching to a cloud session for directory sync, Claude Code can now detect a session that was created empty on the server and never received its first upload of files. Instead of silently treating this as if there were no files, it now reports a specific stopped reason and suggests starting a new cloud session from the folder.

**Why**

This makes a previously confusing, silent failure into a clear, actionable message, so an empty never-synced session doesn't look like missing or lost data.

- Area: Cloud Sync
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### More SDK control messages explicitly rejected in cloud-hosted sessions

More SDK control requests are now explicitly rejected when running in a cloud-hosted session

**What**

Several SDK control messages now return an explicit "not available in a cloud-hosted session" rejection when called from a cloud-hosted session, matching the pattern already used for `get_memory_dialog`:

- `get_skills_dialog`

- `get_status`

- `export_conversation`

- `get_chrome_dialog`

- `get_chrome_browsers`

- `select_chrome_browser`

- `get_sandbox_dialog`

- `mcp_read_resource` (a remote-control action)

**Why**

These features depend on things only available in a local session, like a local Chrome browser or sandbox. Rejecting them explicitly in a cloud-hosted session gives host applications a clear, immediate answer instead of an unclear failure or a request that hangs.

- Area: SDK
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### Team inbox messages get provenance-checked and marked "forged" if sender is spoofed

Teammate inbox messages are now checked for spoofed senders and flagged as "forged" to the model

**What

- Area: Teammates
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### Peer/plugin chat messages now show sender's plugin name

Chat messages sent through a plugin now show which plugin sent them

**What**

When a message in the conversation transcript came from another session or teammate via a plugin, the sender's name line now shows a dim " plugin" label next to it, so it's clear the message was relayed through a plugin rather than typed directly. The display also distinguishes unverified senders from verified ones.

**Why**

This makes it clear at a glance where a message actually came from, so plugin-relayed or cross-session messages aren't mistaken for messages typed directly by a trusted party.

- Area: Messaging
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### New error strings for linking a project session or a Claude app to a 'computer' (tool host)

Claude Code adds new error messages for when a project session or app can't link to a computer (tool host)

**Unclear.** The finding lists the project-session rule explicitly but only names the other categories (machine credentials, routine/reminder-owning sessions, Cowork tasks, agent-owned sessions) without stating their specific refusal conditions.

**What**

Claude Code can link a session to a "computer" (a connected tool host that carries out actions). This release adds a batch of new error messages that explain when that linking is refused, covering:

- project sessions, where a project can only use a computer if the project runs on one of the project owner's own cloud environments

- sessions authenticated with machine credentials

- sessions that own a routine or reminder

- Cowork tasks

- sessions owned by an agent

Under the hood, a new function checks the local identity and session before it signs a request to connect, and another pulls the work and environment identifiers out of the host's description so they can be bound into that signed request.

**Why**

These messages make it clearer why a given session is or isn't allowed to link to a computer, instead of failing without explanation. The added checks also mean the connection request itself carries proof of which work and environment it belongs to, tightening up how these links are verified.

- Area: Device Linking
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### Forged/injected teammate messages are now flagged unverified in the swarm transcript format

Claude Code now marks forged or injected teammate messages as unverified in swarm transcripts

**Unclear.** The finding does not say how a message's provenance comes to be judged 'forged' in practice.

**What**

In Claude Code's swarm mode, where multiple Claude instances (teammates) work together and exchange messages, the transcript format now tracks whether a message's origin can be trusted. A teammate message can be tagged `verified="false"` when its provenance is judged 'forged' (meaning it looks like it came from a teammate but its origin is suspect).

When a message is marked this way:

- its content is no longer scanned for mentions or tool names

- the sender's name is shown with an `(unverified)` label next to it

**Why**

This makes it easier to spot a message that was injected or spoofed to look like it came from a legitimate teammate, rather than having it silently treated the same as a genuine message.

- Area: Teammates
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### Cloud session creation can now wait for a freshly-created empty container to be 'armed' before reporting success

Creating a cloud session from an empty container can now wait for it to be "armed" before reporting success

**What**

When Claude Code starts a cloud or remote session from a freshly-created, empty container, it can now wait for a seed/arming decision to resolve, or for a time limit to pass, before reporting the session as successfully created. If creation ultimately fails, the first upload to that container is discarded.

**Why**

This should prevent Claude Code from reporting a cloud session as ready before it's actually properly set up, reducing the chance of working with a half-initialized session.

- Area: Cloud Sessions
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### Fast-forwarding from a linked worktree now explicitly refused, not silently unsupported

Fast-forwarding a branch from a linked git working tree is now explicitly refused with a clear reason

**What**

Claude Code's directory-sync fast-forward path now explicitly checks whether the checkout is a linked working tree (a working directory sharing its git history with another checkout). If so, it returns a "waiting" result with the reason `linked_worktree` and a message stating that fast-forwarding a branch from a linked working tree isn't supported yet, instead of falling through to generic git-error handling.

**Why**

This gives a clearer, more specific explanation when fast-forwarding isn't possible from a linked working tree, rather than an unhelpful generic error.

- Area: Directory Sync
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### Project-thread resume now also considers 'parked' thread sessions

Project-thread resume now also checks a new set of parked thread sessions, not just live ones

**What**

The logic that decides whether to resume a project thread (a persistent conversation thread tied to a project) now checks two things instead of one: the existing set of live project thread session IDs, and a new `parkedProjectThreadSessionIds` set, which has its own persisted-at timestamp. Claude Code will offer to resume if either set is populated.

**Why**

This means a project thread that was "parked" rather than actively live can still be found and resumed, rather than only threads currently marked as live.

- Area: Sessions
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### Auto-approve-on-accept rule generalized beyond a single hardcoded tool

Auto-approving a suggested permission rule after acceptance now works for any tool, not just one hardcoded tool

**What**

When Claude Code suggests a freeform permission rule and you accept it, it can turn that into an always-allow rule going forward. Previously this logic only worked for one specific hardcoded tool and skipped MCP (Model Context Protocol, a way of connecting external tools) tools entirely. It now instead asks the actual tool whether it supports this via a `suppressesAllPermissionUpdates()` check, and builds the new rule using that tool's real name.

**Why**

This means the always-allow-after-accept behavior can now apply to more tools, including ones beyond the single tool it used to be limited to, as long as the tool supports it.

- Area: Permissions
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### Cloud code-review failure guidance now varies by failure reason

Failure messages for cloud /code-review runs now give tailored guidance based on the specific failure reason

**What**

When a cloud `/code-review` run (the deep, cloud-based `ultra` review) fails, Claude Code no longer always tells you to retry with `/code-review ultra` or fall back to a local review. The message now branches on the specific reason for failure, such as `session_archived` or `session_not_found`, and gives guidance tailored to that cause. The retry/local-fallback advice is now only shown for a subset of failure causes.

**Why**

This gives more accurate next steps when a cloud review fails, instead of always pointing you toward retrying or switching to local review even when that isn't the right fix for the actual problem.

- Area: Code Review
- Names: `/code-review ultra`
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### Teammate sender display can show an 'unverified' qualifier

Teammate messages can now show an 'unverified' label next to the sender's name

**What**

When a message from a teammate or agent is displayed, Claude Code can now add a small "unverified" qualifier next to the sender's display name, shown whenever that sender is flagged as unverified. The sender's name itself is now pulled dynamically instead of from a static value.

**Why**

This gives readers a visible signal when a message's sender identity hasn't been verified, helping distinguish confirmed teammates from unverified ones in shared or multi-agent conversations.

- Area: Teammates
- Names: `unverified`
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### Git snapshot/checkpoint now tolerates a mid-merge conflicted index

Git checkpoint snapshots no longer fail outright when the index has an unresolved merge conflict

**What**

Claude Code periodically takes git snapshots (checkpoints) of your working directory so changes can be reviewed or rolled back. Previously, if your git index had unmerged entries (files still in a mid-merge conflicted state), this snapshotting would fail. Now the snapshot code detects unmerged entries, checks their committed blob and tree data, and reconstructs the index information needed to still take a snapshot, unless the caller has explicitly said unmerged state isn't allowed.

**Why**

This means checkpoints keep working even while you're in the middle of resolving a git merge conflict, instead of silently failing to capture your state.

- Area: Git Checkpoints
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### Auto-mode safety-check failures now split into hard vs transient, with a retry cap

Claude Code now tells apart hard vs transient safety-check failures in auto mode and caps retries

**What**

When Claude Code runs a safety check automatically and the check fails, it now sorts the failure into one of two kinds:

- A hard failure, where retrying will not help, including two new causes: `server_call_unavailable_refused` and `server_call_unavailable_input_too_long`.

- A transient failure, where the tool may retry once, waiting a bit longer each time it tries again.

If a transient failure keeps coming back with no verdict after repeated retries, the turn is stopped instead of retrying forever.

**Why**

This keeps Claude Code from endlessly retrying a safety check that was never going to succeed, while still giving genuinely temporary failures a chance to clear up on their own.

- Area: Auto Mode
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### Cross-host tool routing error messages for teammate mode

Cross-machine tool routing gets clearer errors for unknown, unserved, or incompatible hosts in teammate mode

**What**

A new function routes a tool call to whichever connected machine actually provides that tool, when working in teammate mode across multiple machines. It distinguishes three failure cases: `unknown_host` (the target machine isn't recognized), `not_served` (the tool isn't offered by that machine), and `incompatible` (the tool can't run there). When routing fails, it lists which other connected machines could serve the tool instead.

**Why**

This gives more specific feedback when a tool call can't reach the right machine, and points toward alternative machines that could actually run it, instead of failing with a vague error.

- Area: Multi-Machine
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### Bash tool now reports a 'sandbox_violation' remedy on tool results

Bash tool results now flag a sandbox_violation remedy when a sandboxed command's stderr shows a sandbox violation

**What**

When a Bash command runs inside a sandbox (an isolated environment that restricts what a command can do, such as file or network access) and the sandbox notes that the command tried to do something it blocked, the tool result now includes an extra field: `remedy: { kind: "sandbox_violation" }`. This only appears when the command actually finished running rather than being interrupted.

**Why**

This surfaces sandbox restriction problems directly in the tool result instead of leaving them buried in stderr text, making it easier to notice when a command failed because of sandboxing rather than a genuine error in the command itself.

- Area: Sandbox
- Names: `sandbox_violation`
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### Swarm inbox now verifies message provenance before treating a message as a shutdown/plan-approval control frame

Swarm's inbox now checks a message's origin before letting it trigger a shutdown or plan approval

**What**

In Claude Code's in-process swarm runner (called Me), each agent has a mailbox it polls for incoming messages. That inbox now checks where a message actually came from before treating it as a control message: it's marked verified, unverifiable, or forged. Messages that are flagged as forged can no longer trigger a `shutdown_request` (a message telling an agent to stop) or a `plan_approval_response` (a message approving or rejecting a pending plan) — they're skipped instead of acted on. A new bit of internal bookkeeping, `consumedUnmarked`, keeps track of these filtered-out messages so they aren't re-processed later.

**Why**

Without this check, a message that merely claimed to be a shutdown or plan-approval instruction could apparently make an agent stop working or treat a plan as approved, regardless of whether it really came from a trusted source. Verifying provenance first closes off that route, so only genuinely authorized messages can shut an agent down or approve its plan.

- Area: Swarm
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### Git tamper-detection hardened: character-device paths, split-index copying, and a curated git env-var allowlist

Claude Code hardened its git repo-tampering checks: device-file detection, split-index copying, and a curated env-var allowlist

**Unclear.** The finding does not fully specify what triggers refuse-vs-guard behavior for character-device paths, nor the exact cap on split-index files copied.

**What**

Claude Code's internal checks for tampered or unusual git repositories have been strengthened in several ways:

- Paths containing a 'character device' (a special kind of filesystem entry, not a normal file or folder) are now specifically detected and refused or guarded against during repo verification.

- Worktree config (settings tied to a secondary git worktree) can now be treated as a recognized 'extension' instead of always being refused, controlled by a new `perWorktreeConfig` option that defaults to "refuse".

- Git's split-index files (named `sharedindex.*`) are now copied into Claude Code's sandboxed internal git copy, up to a capped number of files, so operations relying on a split index continue to work.

- When Claude Code runs git commands in its hardened mode, it now passes through a curated list of allowed `GIT_*`, proxy, and SSH-related environment variables, instead of stripping all environment variables.

**Why**

These changes make Claude Code's git safety checks more precise: instead of broadly refusing or stripping things that look unusual, it now recognizes and correctly handles more legitimate git setups (like repos using split indexes, worktrees, or environment-based proxy/SSH configuration) while still guarding against tampered paths involving device files.

- Area: Git Integration
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### Directory sync refuses to run git if .git changed underneath it

Directory sync now refuses to run git if .git moved or git itself sits in a writable path

**What**

Directory sync now performs an upfront check before running any git operation: if the working tree's `.git` location has changed since it was last read, the operation is refused immediately with reason `git_dir`. A second new refusal, `git_in_reach`, fires when the git executable itself is located inside a path that a session bound to a linked worktree could write to.

**Why**

These checks stop git operations from running against a `.git` directory that has moved unexpectedly, or using a git binary that could have been tampered with from within a writable worktree.

- Area: Directory Sync
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Remote tool calls now queue behind a per-host "ask seat" limit

Remote permission requests to a host now queue if too many are already waiting on that host

**What**

When Claude Code needs your permission to run a tool on a remote host, that request is now subject to a per-host limit on how many requests can be waiting for an answer at the same time. Once the limit is reached, new requests wait in line and show a status message instead of all firing at once.

The limit is configurable per host through a new `limits.pending_asks_max` setting in that host's description.

**Why**

This stops a remote host from being flooded with a burst of permission prompts at once, which could make it hard to see or respond to any single request. Waiting requests now queue in an orderly way instead of piling up simultaneously.

- Area: Remote Tools
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### Rate-limit/overage info gained monthly and channel-scoped overage tracking, plus a 'grace' state

Rate-limit status data now includes monthly and channel overage utilization plus a grace-period flag

**Unclear.** The finding does not say whether or when this new data is actually surfaced to users in `/usage` output.

**What**

The internal data used for `/usage`-style rate-limit reporting has grown three new fields:

- `overagePeriodMonthly.utilization` — how much of a monthly overage allowance has been used

- `overagePeriodChannel.utilization` — how much of a channel-scoped overage allowance has been used

- `rateLimitGraceActive` — a flag marking whether a grace period is currently active

These sit alongside the overage fields that already existed in this data shape.

**Why**

This gives Claude Code more detail to draw on when reporting usage and rate limits, including tracking overage separately by month and by channel, and recognizing when an account is in a grace period rather than fully rate-limited.

- Area: Usage & Limits
- Names: `/usage`
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### Side questions now fill in placeholder results for tool calls still running in the main conversation

Side questions now get placeholder results for tool calls still running in the main conversation

**What**

When a side question (a forked-off exchange that branches from the current conversation) copies context from a conversation whose current turn hasn't finished yet, any tool calls in that latest turn without a result yet are filled in with a placeholder result explaining that the call is still in progress in the main conversation, whether it's running, awaiting approval, or queued.

**Why**

This keeps the forked conversation context well-formed even when it's copied mid-turn, avoiding broken or dangling tool calls that have no result attached.

- Area: Elsewhere
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### MCP elicitation requests now rate-limited and size-capped

MCP elicitation requests from connected servers are now rate-limited and size-capped

**What**

An MCP server (a connected tool provider that extends Claude Code) can send an 'elicitation' request, which asks the user for input mid-task. The handler that answers these requests now enforces per-connection limits:

- a maximum number of outstanding elicitations at once

- a maximum number admitted per minute

- a maximum size for the serialized request, measured with a new size estimator

Requests that exceed any of these limits are refused or cancelled instead of being processed.

**Why**

This prevents a misbehaving or overly chatty MCP server from flooding you with input requests or sending oversized ones.

- Area: MCP
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### Sandbox now re-initializes automatically when the sandboxing setting is toggled mid-session

Claude Code now re-initializes the sandbox automatically if its setting changes mid-session

**What**

Claude Code can run tools inside a sandbox, a restricted environment that limits what commands can access. Previously, if the setting controlling whether sandboxing is enabled changed while a session was running, the sandbox would not pick up that change. Now Claude Code watches for that setting to flip and automatically re-initializes the sandbox when it does. If the re-initialization fails, an error is logged.

**Why**

This keeps the sandbox in sync with the current setting instead of continuing to run under a stale configuration for the rest of the session.

- Area: Sandbox
- Tier: You'll notice
- Useful: 3/5
- Signal: 1/5

### New device-binding error messages for Claude account registration

New error messages explain device-binding failures, including concrete steps to re-register a removed device

**What**

Claude Code ties a login to the specific device it was set up on. When that binding fails, the error messages shown now cover more specific cases: the target device being unsupported, the target device requiring an account, and an invalid target device ID. The existing message for a revoked device (one removed from the account on claude.ai) now gives concrete steps to fix it: run `claude --cloud` without `-p` from a project folder and choose "Yes" when asked, instead of just saying the machine can't re-register.

**Why**

This turns a dead-end error into an actionable one, so someone whose device was removed from their account knows the exact command to re-register it instead of being stuck.

- Area: Auth
- Names: `claude --cloud`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### New 'pasted' variant for invisible-character removal message

New message variant reports invisible characters removed specifically from pasted text

**What**

Claude Code can strip invisible characters (characters that don't display but are present in text) and shows a "Removed N invisible character(s)" notice when it does. That notice now has a new "pasted" variant specifically for characters removed from pasted content, distinct from the existing "review" case, whose key name (previously fixed) is now configurable and defaults to "Enter".

**Why**

This lets the notice say more precisely that invisible characters were stripped from something just pasted, rather than using generic wording for every case.

- Area: Input Handling
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Filesystem/git access error message rewritten as a structured reason

Claude Code now shows a clearer error when git can't read the project directory to prepare an upload

**What**

When Claude Code's filesystem/git access layer fails to read the current project directory, it used to fail internally with an unhelpful message ('held directory is closed'). It now returns a structured error with a clear message: git could not read the project directory or prepare its upload, with details in the debug log, and a suggestion to run `git status` in that directory.

**Why**

This gives a concrete, actionable message when git operations fail, instead of an internal-sounding error that gave no hint about what to check or do next.

- Area: Git Integration
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Vertex setup screen can now be exited with Ctrl+C/D

The Vertex setup confirmation screen can now be exited with Ctrl+C or Ctrl+D

**What**

The confirmation screen shown at the end of Vertex AI setup now supports exiting with Ctrl+C or Ctrl+D, matching the behavior other setup screens already have.

**Why**

This lets users back out of the Vertex setup flow at that final step using the standard exit keys instead of getting stuck without a way out.

- Area: Elsewhere
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Git-sync now explains more precisely why previously-staged changes were dropped

Git-sync now gives a more specific reason when your earlier staged changes are no longer there

**What**

When Claude Code's git-sync feature finds that changes it had previously staged are no longer in the index, it now explains more precisely why. The message now distinguishes between three cases:

- the file is gone entirely

- the file's contents have changed since, in which case Claude is told to re-read it

- the contents are unchanged

Previously the message always said the file contents were unchanged, even when that wasn't true.

**Why**

A more accurate explanation helps Claude respond correctly when its staged work disappears: it knows whether to re-read a changed file before continuing, rather than assuming nothing had changed.

- Area: Git Sync
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### New refusal-guidance text for irrecoverable artifact read errors

Claude Code now tells the model not to retry an artifact read when the failure is unrecoverable

**What**

When an artifact (a file-like object Claude Code can read) fails to load with one of several specific error codes — the agent wasn't added, the agent doesn't own it, access needs to be requested, or the artifact is gone — Claude Code now shows a fixed instruction telling the model not to retry the read, and instead to tell the user the artifact couldn't be read and continue without it.

**Why**

This stops Claude from repeatedly retrying a read that can never succeed, and ensures the user is informed promptly instead of the model silently looping.

- Area: Artifacts
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### /model default-set now optimistically updates local state before server confirmation

Setting a default model with /model now updates the local picker before the server confirms

**What**

When setting a default model with `/model`, Claude Code now updates its local state optimistically as soon as the save request is sent, in parallel with waiting for the server to confirm the change, rather than waiting for confirmation before updating what's shown locally.

**Why**

This makes the model picker feel more responsive when switching your default model, since the interface updates immediately instead of waiting on a round trip to the server.

- Area: Models
- Names: `/model`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Hook-timeout message now names the timed-out command

Hook timeout warnings now show which specific command timed out

**What**

When a hook (a custom script Claude Code runs automatically at certain points) takes too long and times out, the warning message shown in the transcript now includes the specific command that was running, in brackets, before saying it timed out. Previously the message only named the hook, not the command it ran.

**Why**

This makes it much easier to identify and fix the exact command that's causing a timeout, especially if a hook runs several commands.

- Area: Hooks
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Plugin directory watcher switches from mtime to ctime for change detection

Plugin directory watcher now detects changes via file ctime instead of mtime, with new debounce tuning

**What**

Claude Code watches your plugin directory for new or changed plugin manifests so it can pick them up automatically. That watcher now compares each file's ctime (the time its metadata last changed) instead of its mtime (the time its content last changed) to decide whether something changed. It also gained explicit controls for how often it rescans and for coalescing rapid bursts of changes so they don't trigger repeated rescans.

**Why**

Using ctime instead of mtime can catch changes that don't update a file's modification time, such as permission or metadata changes, making plugin detection more reliable. The new debounce tuning helps avoid unnecessary repeated rescans when several files change in quick succession.

- Area: Plugins
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Self-hosted runner --configure-git now detects and preserves an operator's existing git hooksPath

Self-hosted runner setup now detects an existing git hooksPath instead of overwriting it

**Unclear.** The finding does not say what happens after the existing hooksPath is detected, e.g. whether setup then skips, merges, or errors instead of overwriting.

**What**

The self-hosted runner's command-line tool has a `--configure-git` step that installs its own git hooks (scripts git runs automatically on certain actions, like committing). Previously this step would install its shim without checking for existing configuration. Now it first checks whether the repository already has a `hooksPath` set up by the operator, and if one exists, it reports that existing path back instead of silently overwriting it.

**Why**

This prevents the runner setup from clobbering an operator's own git hooks configuration, so custom hooks already in place keep working after `--configure-git` runs.

- Area: Self-Hosted Runner
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Built-in diff panel carries over the old panel's open/closed preference

The new plugin-based diff panel now inherits your old diff sidebar's open/closed setting

**What**

When Claude Code's newer plugin-panel diff sidebar is available, it now checks whether your prior built-in diff sidebar was set to open or closed (the `diffSidebarOpen` setting) and opens in that same state, logging a message noting the preference was carried over.

**Why**

This means switching to the new plugin-based diff panel won't reset a preference you'd already set for whether the diff view stays open, so the panel behaves the way you're used to without extra reconfiguration.

- Area: Elsewhere
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Managed-settings disable reason for workflows now covers enableWorkflows: false

Workflows can now also be disabled via 'enableWorkflows: false' set above your own settings

**What**

Dynamic workflows (Claude Code's feature for running multi-step orchestrations) can be turned off in several ways. The documented list of causes now explicitly includes `enableWorkflows: false` being set by a settings layer above your own (such as an organization or managed policy), in addition to the existing `disableWorkflows` setting and the `CLAUDE_CODE_DISABLE_WORKFLOWS` environment variable.

**Why**

This clarifies that an admin-level `enableWorkflows: false` is now a recognized, explained reason workflows might be unavailable to you, rather than appearing unexplained.

- Area: Elsewhere
- Names: `enableWorkflows`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Ctrl+C now also cancels an in-progress voice recording

Ctrl+C now cancels an in-progress voice recording, matching Escape

**What**

While recording or processing voice input, pressing Ctrl+C now cancels it, the same as pressing Escape already did.

**Why**

This gives an additional, commonly-reached-for way to back out of voice input, matching the interrupt shortcut people already use elsewhere.

- Area: Elsewhere
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### OAuth/Vertex/Bedrock setup wizards support Ctrl+C/Ctrl+D exit

Vertex AI and Amazon Bedrock setup wizards can now be exited with Ctrl+C or Ctrl+D

**What**

The multi-step setup wizard used for both Vertex AI and Amazon Bedrock onboarding now supports an `exitOnCtrlCD` option, which lets a user leave the wizard by pressing Ctrl+C or Ctrl+D.

**Why**

This gives people a standard, expected way to back out of the Vertex AI or Bedrock setup flow partway through, instead of being stuck without a clear exit.

- Area: Elsewhere
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### File-sync-paused message gets a new variant for brand-new cloud sessions

A new message explains file sync pausing for cloud sessions that haven't synced any files yet

**What**

When file sync is paused for a cloud session (shown as an emergency-switch notice from Anthropic), there is now a distinct message for sessions that have no local project files synced at all yet. It explains that messages are kept on the local machine until sync is turned back on.

**Why**

This gives a clearer, more accurate explanation for brand-new cloud sessions that haven't synced anything, rather than showing generic pause wording that wouldn't quite fit that situation.

- Area: Cloud Sync
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### New withheld-file reason: file linked from Claude Code configuration

Files withheld from cloud sessions can now be explained as linked from your Claude Code configuration

**What**

When Claude Code withholds a file from being uploaded to a cloud session, for example because it looks like it might contain credentials, the explanation for why can now say the file is "linked from your Claude Code configuration." This gives that specific case its own explanation rather than lumping it into a generic reason.

**Why**

This makes it clearer to someone why a particular file wasn't sent to a cloud session, pointing them to the actual cause instead of a vague catch-all message.

- Area: Cloud Sessions
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### New deny message for a 'Publishing' feature blocked by Read permission

Denied 'Publishing' actions now get a specific explanation about the Read permission check

**What**

When a 'Publishing' action is denied because it needs a Read permission check first, Claude Code now shows a specific message: it explains that publishing reads file contents and requires that check, and tells the user to retry the publish so approval can be requested, instead of a generic denial message.

**Why**

This makes it clearer why a publish action was blocked and tells the user exactly what to do to get past it, rather than leaving them with an unexplained denial.

- Area: Permissions
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Clearer message for unreadable large saved-output files on a remote host

Clearer explanation given to Claude when a large tool output is saved to a file it can't read on a remote host

**What**

When a tool's output is too large and gets saved to a file on a remote host instead of being sent back directly, the message shown to Claude has been reworded. It used to say to 'read it there'; it now explicitly says the file cannot be read from here, and suggests re-running the command remotely with `head`, `tail`, or `grep` if that's safe.

**Why**

The old wording could be read as implying Claude could still read the file somehow. The new wording is more explicit about the limitation and gives concrete commands to work around it.

- Area: Remote Tools
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Directory/folder sync now includes unmerged (conflicted) files in its snapshot

Folder sync now also picks up unmerged (conflicted) files, not just modified and deleted ones

**What**

The git-based directory sync feature now runs a separate `git ls-files --unmerged` query and includes those paths (files with unresolved merge conflicts) in the set of files considered for syncing, in addition to the existing modified and deleted file listing.

**Why**

Without this, files with unresolved conflicts could be missed from the sync snapshot, leaving the synced copy out of step with a repository that's mid-conflict.

- Area: Directory Sync
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Rate-limit prompt hand-back now restores IDE selection state

Handing a prompt back after a rate-limit pause now restores the IDE's text selection

**What**

When Claude Code hands a prompt back to the user, such as after a rate-limit pause where a pre-filled prompt was consumed, it now also restores the IDE's selection state via a new `restoreIdeSelectionConsumedBy` call wired into the hand-back flow.

**Why**

This prevents the editor's text selection from staying in whatever state it was left in during an auto-continue rate-limit pause, restoring it once the prompt is handed back to the user.

- Area: IDE Integration
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Directory-sync consent now double-checks the working root matches the session's directory

Directory sync now checks the git root actually matches the session's directory before granting consent

**What**

Before granting consent to sync a directory, Claude Code now double-checks that the git root found by walking up from that path is the same directory the session's sync engine is actually anchored to. If it's not, consent is treated as withdrawn and a warning is logged.

**Why**

This guards against directory sync operating against the wrong project if the expected `.git` directory has moved or doesn't match what the session was set up for, rather than silently syncing an unintended location.

- Area: Directory Sync
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Design tool auth failures now redirect to design login instead of a generic error

Design tool login failures now trigger a specific redirect to /design login instead of a generic error

**What**

When Claude Code's `/design` tool (a skill for drafting UI mockups and screen flows) can't verify your credentials because you need to log in, it used to throw a generic `design_tool_auth_failed` error. Now, when the failure reason is `needs_design_login`, it throws a specific `design_needs_authorization` error (tied to the `claude_design` provider), which lets the interface point you directly at the `/design login` command instead of showing a generic failure.

**Why**

This makes it clearer what went wrong and what to do about it: instead of a generic auth error, you're told specifically to run `/design login` to fix the problem.

- Area: Artifacts
- Names: `/design`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Login-remedy hints surfaced on relogin/auth failures for inbox reads and cloud subagent launches

Login errors now come with a suggested fix instead of just an error message

**What**

When reading a peer's inbox message fails because the session needs to log in again, or when launching a remote/cloud subagent (a delegated Claude Code task running elsewhere) fails because of a missing access token or an authentication rejection, the response now includes a `remedy` describing what's wrong (for example, `auth_expired` or `auth_overridden`), built from the current login and credentials state, instead of just a plain error string.

**Why**

This gives a more specific reason when a login-related failure happens, making it easier to understand what needs to be fixed, such as logging in again.

- Area: Auth
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Git snapshot engine detects tampered/misconfigured .gitattributes more precisely

Claude Code's git snapshot engine now detects more specific kinds of tampered or misconfigured .gitattributes files

**What**

When Claude Code takes a snapshot of a remote directory for git syncing, it checks the `.gitattributes` file (which controls how git treats certain files) for problems. Previously it only rejected such files with a generic message about setting or unsetting filter attributes. It can now distinguish:

- files that set or unset filter attributes

- files that define macros

- files that quote patterns

- files where an object referenced by a committed `.gitattributes` doesn't match its expected id, flagged specifically as "tampered"

**Why**

This gives Claude Code a more precise way to detect misconfigured or tampered `.gitattributes` files during git sync, rather than lumping every case into one generic rejection.

- Area: Git Sync
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### New 'Auto mode check unavailable' UI state for the auto-mode server classifier

Claude Code's UI now shows an "Auto mode check unavailable" message with a retry countdown when auto mode can't get a verdict

**What**

Claude Code's retry-status display gained a new state for when the server-side classifier behind "auto mode" repeatedly returns no usable result. In this state, the UI shows "Auto mode check unavailable" along with a countdown ("next try in … attempt X/Y") and a hint that pressing escape will interrupt.

**Why**

This gives users a clear explanation and a visible countdown when Claude Code can't get an auto-mode verdict from the server, instead of leaving the wait unexplained.

- Area: Auto Mode
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### New per-field unavailability message, used for run_in_background

New unavailability message explains why a background-running task field can't be used in some environments

**What**

An internal helper that used to only show a "Checking GitHub CLI installation..." spinner has been turned into a general message generator producing lines like "{field} is not available on {target}." It has a special case for `run_in_background`: when it's unavailable, the message explains that the calling session has no way to poll a background task there, and suggests running it in the foreground or in the session's own environment instead.

**Why**

This gives a clearer explanation when a particular option, such as running a command in the background, can't be used in the current environment, instead of a generic error.

- Area: Background Tasks
- Names: `run_in_background`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### New file-sync error messages for corruption, rewritten history, and a full file store

New error messages explain file-sync failures from data corruption, rewritten history, or a full file store

**What**

Claude Code adds new user-facing error messages for file sync in cloud sessions, covering: a git object that "fails its checksum" (data corruption), history that was rewritten partway through a session, and a cloud session's file store being full. There's also a separate recovery message shown once the full-store condition clears.

**Why**

These give clearer, more specific explanations when file sync runs into trouble, instead of a generic failure message, and let a reader know when a full file store has been resolved and syncing can continue.

- Area: Cloud Sync
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### IDE selection can now be 'consumed' and restored per prompt

IDE text selections attached to a prompt can now be restored if that prompt is edited and resent

**What**

Claude Code can attach your current text selection from the IDE to a prompt you send. The UI now tracks this more carefully: when a prompt is sent, its attached selection is 'consumed' (taken out of the pending state), and if that specific prompt is later restored, such as through undo or editing and resubmitting it, the selection is put back with it.

**Why**

This keeps the IDE selection correctly tied to the prompt it belonged to, so editing and resending a prompt doesn't lose or misplace the selection you had attached.

- Area: IDE Integration
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Read tool's staleness check is now async and reads the file's actual mtime from disk

The Read tool's check for whether a file changed since it was last read now looks at the file's real modification time on disk

**What**

Before re-reading a file, Claude Code checks whether the file has changed since it was last read. This check used to compare timestamps kept in memory; it's now an asynchronous check that looks up the file's actual last-modified time from disk before comparing.

**Why**

Reading the real file timestamp instead of relying on a stored value makes this staleness check more accurate, reducing the chance of missing an external edit to a file.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### PR/diff pane now checks file checkpointing before auto-opening

The PR/diff pane now checks whether file checkpointing is on before auto-opening

**What**

The session diff pane (also shown for pull requests) can automatically open once changes cross a certain threshold. Before doing so, it now calls `isCheckpointing()`, which looks at your settings and the `CLAUDE_CODE_DISABLE_FILE_CHECKPOINTING` environment variable, and skips auto-opening if checkpointing is turned off.

**Why**

This keeps the diff pane's auto-open behavior consistent with whether file checkpointing, the feature that lets you use `/rewind` to restore prior code changes, is actually enabled, avoiding a pane that opens based on checkpoint data that isn't being tracked.

- Area: Elsewhere
- Names: `CLAUDE_CODE_DISABLE_FILE_CHECKPOINTING`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Much more detailed refusal messages for uploading/capturing an untrustworthy git checkout

Remote session handoff now explains exactly why an untrustworthy git checkout is refused

**What**

When Claude Code hands a working copy of your repository off to a remote session (for example through bridge/remote control features that upload or capture your checkout), it now gives a specific, worded explanation when it refuses to do so because the checkout looks untrustworthy. Cases include:

- the `.git` entry being a symbolic link (which the session could re-point elsewhere)

- the `.git` entry being a hard link

- use of "reftable" storage for git references

- objects borrowed from another repository

- a nested repository inside the checkout

- worktree-specific config

- git config injected via environment variables

Each case now gets a plain-language sentence explaining why the session refuses to proceed and what to do instead, such as starting from an ordinary clone.

**Why**

Previously a refusal in these situations likely gave little or no explanation. Now users get a concrete reason and a suggested fix, making it easier to understand why a handoff was blocked and how to get past it.

- Area: Git Sync
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Runner sessions can now apply git commit-signing config

Background and cloud runner sessions can now apply git commit-signing configuration

**What**

When setting up a background or cloud runner session, Claude Code now builds git commit-signing configuration and applies it as git config settings passed into the checkout process, alongside the GitHub and git configuration it already wires up.

**Why**

This lets background and cloud sessions produce commits with proper signing configuration applied, rather than checking out without it.

- Area: Git Integration
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### New refusal message for tool calls skipped because another call in the same batch was denied

Claude Code now shows a distinct message when a tool call is skipped because a check denied a different call in the same batch

**What**

When Claude Code sends several tool calls together as one batch, a permission check can deny one of them. Previously, the other calls in that batch that never got to run showed the same generic message used when a turn simply ended early. Now those skipped calls get their own message, explaining that the call was stopped because a check denied a sibling call in the same batch, that nothing about this call itself was refused, that it had no effect, and that it can be re-run if it's still needed.

**Why**

This makes it clearer why a particular tool call didn't run: the call itself wasn't the problem, another call in the same batch was blocked and that stopped the rest from executing. Knowing that lets you distinguish a denied action from one that simply never got a chance to run, and tells you it's safe to retry.

- Area: Permissions
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### New auto mode 'recent denials' panel component

Auto mode's denial history now shows in a dedicated panel with a placeholder when empty

**What**

The list of commands that Claude Code's auto mode (a mode that automatically approves or denies actions based on a classifier) has recently denied now has its own panel component. When there are no recent denials, it shows a placeholder message: "No recent denials. Commands denied by the auto mode classifier will appear here." When there are denials, it renders the list with proper keyboard focus and state handling.

**Why**

This makes it easier to see, at a glance, what auto mode has been blocking, and gives clear feedback instead of a blank list when nothing has been denied yet.

- Area: Auto Mode
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Diskless sessions get a synthetic task-output root and disable shell entirely

Diskless sessions now use a synthetic output path and can't run shell commands at all

**What**

When a session runs in 'diskless' mode (without a real disk to write to), background task output now goes to a synthetic placeholder path, `/nonexistent/claude-code-diskless`. Separately, any attempt to run a shell command in a diskless session now fails immediately with the reason `diskless_no_shell` instead of attempting to execute it.

**Why**

This makes it explicit and immediate that shell commands can't run without a disk, rather than letting a command attempt fail in a confusing way partway through.

- Area: Elsewhere
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Default diff base for git-worker "standing" sync changed from "auto" to "branch-point"

Directory-sync's git worker now diffs against the branch point by default instead of an automatic mode

**What**

The directory-sync git worker's "standing" check, which computes diffs for workspace/session syncing, now explicitly requests the "branch-point" diff mode. Previously it used the "auto" mode by default.

**Why**

This changes what baseline is used when computing diff hunks for directory sync, comparing against the branch point rather than letting the mode be chosen automatically.

Gate state

Nothing has been read yet about whether `tengu_dir_sync_git_worker_standing` is switched on.

- Area: Directory Sync
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Structured error objects with a code+description now get a dedicated short summary

Error messages with a code and description now show a short, dedicated summary instead of a scanned-out file path or command

**What**

Claude Code shows short summaries for errors in places like tool call results. There is internal logic that picks what text to use for that summary. Now, when an error is a structured object containing both a `code` field and a non-empty `description` field, the summary is built directly from that `description` (cleaned up and cut off at 60 characters). Previously such errors would instead be handled by logic that scans for fields like `command`, `file_path`, or `path` to build a summary.

**Why**

This means errors that carry a proper `code` and `description` now get a summary that reflects the actual error description, rather than one accidentally built from an unrelated field like a file path or command string.

- Area: Error Handling
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Memory MCP tool errors get a larger truncation cap plus a rewrite hint

Errors from the memory tool now allow more text before truncating and tell Claude to re-read the file before rewriting it

**What**

The built-in `memory` MCP server (Claude Code's system for writing and reading notes that persist across turns, using actions like `memory_read`, `memory_list`, `memory_write`, `memory_str_replace`, `memory_append`, and `memory_delete`) now has a higher limit on how many characters an error message from these actions can contain before it gets cut off. When an error is still long enough to be truncated, Claude Code now appends a note instructing the model to call `memory_read` again on the affected file before attempting to rewrite it.

**Why**

This reduces the chance that Claude acts on an incomplete error message when a memory operation fails, and steers it to refresh its view of the file's current contents before making further edits, lowering the risk of overwriting or corrupting saved memory.

- Area: Memory
- Names: `memory_read`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Multi-machine tool-output truncation notice

Claude now gets told when a teammate's tool output was truncated and the full output only exists on their machine

**What**

When working across multiple machines with a teammate, if a tool call run on another machine produces output that gets truncated (cut short), Claude Code now builds a specific message explaining this: the output was truncated on the remote machine, and the full output only exists there. It suggests re-running the command on that machine with `head`, `tail`, or `grep` if that's safe.

**Why**

Without this notice, Claude might assume it has the complete output when it doesn't. This makes the limitation explicit and points toward a way to retrieve the missing data from the machine that actually has it.

- Area: Multi-Machine
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### bridge:projects reply-mount now retries its MCP dial with backoff

Cloud project-thread MCP connections now retry with backoff instead of giving up after one failure

**What**

The `bridge:projects` feature, which mounts an MCP (Model Context Protocol) server for a cloud 'project thread' reply, now retries its connection attempt on failure using a backoff schedule (waiting longer between each successive retry) instead of giving up after a single failed attempt. It logs a message when retries are exhausted, and reports separate telemetry while a connection is still retrying versus when it has failed for good.

**Why**

A single transient failure no longer permanently breaks the connection; the mount now has a chance to recover on its own. When retries do run out, the mount stays as-is until the underlying binding changes, and the new logging makes that state easier to diagnose.

- Area: Cloud Sessions
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### read_file Windows path-spoofing check now reports specific spelling categories

read_file's Windows path safety check now names exactly which spelling trick it caught, with seven distinct categories

**What**

Before touching the filesystem, the `read_file` tool checks incoming Windows file paths for suspicious spellings that could be used to sneak past path restrictions. Previously this check returned one generic reason when it rejected a path. It now distinguishes seven specific tricks, each with its own rejection message:

- NT device namespace paths

- a colon appearing past the drive-letter position

- tilde-plus-digit short filenames (the old 8.3-style short name format)

- device-path prefixes

- trailing dots or whitespace

- DOS device-name suffixes

- runs of dots within a path segment

- UNC or WebDAV-like path forms

**Why**

More specific rejection messages make it easier to understand exactly why a given Windows path was blocked, rather than getting the same generic warning for every kind of suspicious spelling.

- Area: Elsewhere
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Permission checks now handle unresolved symlink chains explicitly

Permission checks now explicitly deny paths whose symlink chain can't be resolved

**What**

The core function that decides whether Claude Code is allowed to read or write a file now takes a richer object describing how a path was resolved, including a set of alternate spellings and an `unresolved` flag. When a path's chain of symlinks (shortcuts that point to another location) can't be fully resolved, the permission check now denies the operation with a dedicated message and reason, instead of silently falling through. This case also respects the `blockReadsOutsideWorkingDirectories` setting and restricted-mode circuit breakers.

**Why**

An unresolved symlink chain was previously handled implicitly, which could lead to unclear or inconsistent behavior. Denying it explicitly, with a clear reason, closes a gap where an ambiguous path might otherwise have been treated too permissively.

- Area: Permissions
- Names: `blockReadsOutsideWorkingDirectories`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Write permission checks now detect symlink-mediated escapes 'carried out'

Write permission checks now catch symlinks that would redirect a write outside the intended folder

**What**

A new check runs after a write operation is otherwise allowed or denied, to detect cases where a symlink (a shortcut that points to another location) would actually cause the write to land outside the folder it was supposed to stay in. When this is detected, the write is blocked with a dedicated safety-check reason and message.

**Why**

This closes a gap where a symlink could be used to redirect a write to an unintended location even after the initial permission check passed, adding another layer of protection against writes escaping their intended directory.

- Area: Permissions
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Skills settings dialog: search input and focus handling reworked

The /skills settings dialog's search box gets proper focus handling so keyboard shortcuts don't fire while typing

**What**

The search box in the `/skills` settings dialog now has dedicated focus and blur tracking, using a real reference to the underlying input element. The list-selection and 'no changes' accept/back actions now check whether the search box itself is focused before acting on a keypress. The keyboard shortcuts for accepting a selection, declining confirmation, and sorting by token count are now always active, rather than only active based on a separate local focus-tracking flag.

**Why**

This should make keyboard behavior in the `/skills` dialog more reliable, so shortcuts like accepting a selection or sorting by token count work consistently and don't get confused by whether the search box happens to have focus.

- Area: Skills
- Names: `/skills`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Cloud file-sync failure message distinguishes 'no files at all' from 'stale files'

Cloud session file-sync error now says whether no files synced at all or the copy is just stale

**What**

When Claude Code runs a cloud session (a session running on Anthropic's infrastructure rather than your own machine) and a file repeatedly fails to upload into it, the error message now tells you which of two situations you're in:

- the cloud session has none of your files at all, in which case it offers to start a new cloud session

- the cloud session has an out-of-date or incomplete copy of your files

**Why**

Previously a sync failure gave you the same message regardless of cause, leaving you to guess whether the fix was to retry or to start over. Knowing which case applies makes it clearer what to do next, and the offer to start a fresh cloud session covers the case where syncing has nothing to build on.

- Area: Cloud Sync
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Attach-remote now seeds and restores rate-limit info across session detach/reattach

Detaching and reattaching a remote session now carries rate-limit info across the switch

**What**

When a session is detached and later resumed through the attach-remote flow, Claude Code now carries rate-limit information along with it. At the start of a session it reads the current `limits`, `limitsObserved`, and `limitsEpoch` state, and when the session is torn down it re-applies that state if the limits changed, or resets it if the epoch moved on.

Resumed sessions also now seed a new `seedRateLimitInfos` field from the prior session's state, alongside the existing `seedActiveGoal` and `seedAutocompactState` fields that already carried other session state across a resume.

**Why**

This keeps rate-limit tracking consistent when a session is detached and reattached, instead of losing or resetting that information across the switch.

- Area: Rate Limits
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### New 'floor_gone' refusal reason for git-checkpoint capture

Checkpoint capture now refuses with a clear message when the commits it was based on are gone from history

**Unclear.** The finding does not say what the exact user-facing message text is or what happens after the refusal.

**What**

Claude Code can save checkpoints of a session's work, which are captured and uploaded based on the git commits present at the time. If those original commits later get rewritten or removed from the checkout's history (for example by a rebase or history rewrite), a new capture attempt now refuses to proceed. This refusal has its own internal reason code, `floor_gone`, and shows a dedicated message explaining what happened.

**Why**

Previously this situation could presumably fail in a less clear way. Now, if you rewrite git history after Claude Code has uploaded checkpoints based on it, you'll get an understandable explanation instead of a confusing failure when the tool tries to capture further changes.

- Area: Git Checkpoints
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Artifact publish now refuses declarations that silently reset db rules or user scopes

Publishing an artifact capability now gets refused if it would silently wipe out existing db rules or user scopes

**What**

When publishing capabilities for an artifact, Claude Code now checks whether a `db` (database) or `user` block is being resent without the `rules` or `scopes` that were previously stored for it. If so, the publish is refused with a message explaining that the stored rules or scopes would be reset to their defaults, which are open access.

**Why**

This prevents accidentally opening up access by silently dropping existing security rules or scopes during a republish, catching what would otherwise be a dangerous, invisible change.

- Area: Artifacts
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Path-outside-boundary denial messages now include the resolved landing path

Permission-denial messages for paths that escape an allowed folder now show where the path actually ends up

**What**

When a file path resolves, via a symlink or `..` traversal, to somewhere outside a folder Claude Code is allowed to access, the denial message and the blocked path it reports now show the actual resolved landing location rather than the original path string as typed. The permission-denial builder also now checks for an unresolved-path case first.

**Why**

This makes it clearer why a permission was denied, since the reader can see exactly where a seemingly-safe path actually pointed, rather than just the path they entered.

- Area: Permissions
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Wizard dialogs gain a Ctrl+C/D exit confirmation instead of instant close

Wizard dialogs now require a second Ctrl+C or Ctrl+D press to cancel, instead of closing immediately

**What**

Step-by-step wizard dialogs in Claude Code now require pressing Ctrl+C or Ctrl+D twice to cancel, showing a "Press [key] again to cancel" prompt after the first press, instead of closing immediately. This is controlled by a new `exitOnCtrlCD` option; when it's not set, the double-press confirmation applies.

**Why**

This prevents accidentally closing a multi-step wizard with a single stray keypress, giving a chance to back out of the cancellation.

- Area: Elsewhere
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Login screen now distinguishes cancel from exit on double-escape and supports a fresh-picker callback

Login screen's double-Escape prompt now says 'cancel' or 'exit' depending on context, and supports a fresh account picker

**What**

The login dialog now shows different text when you press Escape a second time, depending on the situation: it says "cancel" while a fresh account picker is showing, and "exit" otherwise, replacing a flat "Press Esc again to exit" message. The dialog also gained a new `onFreshPickerChange` callback prop to support this.

**Why**

This makes the double-Escape confirmation text more accurate to what actually happens, since canceling an account picker and exiting the login flow entirely aren't the same action.

- Area: Elsewhere
- Names: `Esc`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Tool output truncation now appends an explanatory note

Truncated tool output can now include an explanatory note about why it was cut short

**Unclear.** The finding does not say which tools supply a truncationNote or what the note's wording looks like in practice.

**What**

When a tool's output is too long and gets cut short (truncated), Claude Code can now attach a `truncationNote`: a short explanatory message added after the shortened content, separated from it by a blank line. The note only appears when truncation actually happened and a note was provided.

**Why**

This gives a clearer signal when output has been shortened, instead of leaving the reader to guess why the content stops abruptly or seems incomplete.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### New refusal message for secrets/credentials committed mid-upload

Claude Code now refuses uploads when a secret or credential was committed partway through preparing them

**Unclear.** The finding doesn't specify which upload feature or command this applies to, or how the detection is triggered.

**What**

If Claude Code detects that a file containing secrets or credentials was committed while it was preparing an upload, it now shows a clear refusal message explaining the problem instead of proceeding. The message tells you to amend or reset the commit or commits that added the file, and it specifically warns that deleting the file in a later commit is not enough to fix the problem, since the secret would still exist in the commit history.

**Why**

This helps prevent secrets and credentials from ending up in a commit history that gets uploaded, even if a fix attempt only removes the file in a newer commit. It pushes users toward properly rewriting the offending commits rather than leaving exposed data reachable through git history.

- Area: Permissions
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Agent-proxy CA trust stores now support rotating to a second certificate

Claude Code's agent-proxy can now roll over to a second trusted certificate without breaking connections

**Unclear.** The finding only names one seeding-failure event as evidence; it doesn't confirm how the retry or second-certificate detection behave beyond what's described here.

**What**

Claude Code routes some traffic through an internal agent-proxy, and that proxy needs its network certificate (a credential that lets other software verify it's talking to the real proxy) trusted by the operating system, Java, and NSS (the certificate library used by tools like Firefox). The installers that set up this trust were reworked so they can now handle a second certificate alongside the first, rather than assuming there is only ever one.

- The Java trust-store installer (which uses `keytool`) and the NSS trust-store installer (which uses `certutil`) now detect and import a second CA certificate.

- If seeding the Java trust store with `keytool` fails, it now retries once after a pause instead of giving up immediately.

- The installers now record whether they found an 'old_layout' store, meaning one that still only holds a single certificate.

**Why**

This lets Claude Code rotate to a new certificate for the agent-proxy without users suddenly losing trust in it, since both the old and new certificates can be recognized during the transition. The added retry on `keytool` seeding also makes the Java trust-store setup less likely to fail on a transient error.

- Area: Permissions
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### New directory-sync-lag notice for cloud/remote git environments

Cloud and remote sessions now get a warning when their git working directory hasn't caught up with your latest local upload

**What**

When you're working in a cloud or remote session, Claude Code keeps that session's git working directory (the folder holding your checked-out files) synced with the changes you upload from your local machine. If that sync falls behind, a new notice now appears telling you the current turn is running against stale files, since your newer local changes haven't arrived yet. Claude Code keeps retrying the upload on every turn until it succeeds.

**Why**

Without this notice, a lagging sync would be invisible, and Claude Code could act on outdated files without you realizing it. Now you know when a response may not reflect your latest local edits.

- Area: Cloud Sync
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Parked/stopped background-agent notification made passive and deferred

Notifications about interrupted background agents are now delayed and non-intrusive instead of popping up immediately

**What**

When a background agent (a Claude Code task running separately from your main session) gets stopped or parked mid-task, Claude Code used to notify you about it right away. Now that notification is queued as passive and given `next` priority, meaning it waits to be shown rather than interrupting you immediately.

Alongside this, the internal loop that lists background agents now skips any agent already marked as done before it counts or parks them, avoiding redundant processing of agents that have already finished.

**Why**

This makes background-agent notifications less disruptive: instead of an interrupted or parked agent immediately grabbing your attention, you'll see the notice surfaced at a calmer point. It also avoids Claude Code re-processing agents that are already finished, which keeps the agent-listing logic cleaner.

- Area: Elsewhere
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Working-tree upload refusal gains three new integrity checks

Git upload safety scanner adds checks for same-bytes, hardlinked, and unexamined files

**What**

The safety scanner that Claude Code runs before uploading a working tree already refused uploads containing 'forged' paths or 'alias' (8.3 short-name) paths. It now also refuses uploads in three more cases:

- a 'same-bytes' entry: a file in the index that is byte-for-byte identical to a file meant to stay local, placed there by something other than the upload process itself

- a 'hardlinked' changed file: a file that is a second hard link to something outside the tracked tree

- an 'unexamined' file: a path that could not be safely inspected

**Why**

These checks close off ways a local-only file's contents could end up uploaded indirectly, either by being duplicated under a different name, linked from outside the tree, or slipping past inspection.

- Area: Permissions
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### code-sign now supports lifecycle-hook processes, not just spawned child sessions

Code-signing now also recognizes lifecycle-hook processes, not just spawned sessions

**What**

Claude Code's code-signing helper, which previously identified eligible processes by reading `CLAUDE_CODE_REMOTE_SESSION_ID`, `CLAUDE_CODE_SESSION_ACCESS_TOKEN`, and `ANTHROPIC_BASE_URL`, now also accepts `CLAUDE_RUNNER_SESSION_ID` and `CLAUDE_RUNNER_API_BASE_URL`, the environment variables used by lifecycle hooks (scripts that run automatically at points in a session's life). When it finds a `CLAUDE_RUNNER_SESSION_ID` prefixed with `session_`, it converts that prefix to `cse_` to match the expected format.

**Why**

This widens which processes are eligible for code signing to include lifecycle-hook processes, not just spawned child sessions.

- Area: Permissions
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Remote-agent session polling now backs off and fails distinctly after repeated 404s

Remote agent polling now gives up with a distinct 'session not found' error after repeated 404s instead of timing out

**What**

When Claude Code polls a remote agent task for its status, it now tracks how many times in a row the server responds with a 404 (not-found) error. If a review-mode task keeps hitting 404s past a threshold, polling now stops and fails with a new reason, `session_not_found`, instead of the existing `poll_timeout_after_api_error` reason.

**Why**

This gives a clearer, more specific failure signal when a remote session genuinely can't be found on the server, rather than lumping it together with a generic timeout-after-error condition.

- Area: Elsewhere
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Merge-conflict backup file patterns generalized

Claude Code now recognizes more merge-conflict backup file variants like .BACKUP_*, .BASE_*, .LOCAL_*, and .REMOTE_*

**Unclear.** The finding doesn't say which specific feature (file watching, search exclusion, or something else) consumes these patterns.

**What**

Claude Code builds a wider set of file-name patterns for recognizing backup and merge-conflict copies of a file. Besides plain `.orig` files, it now matches variants such as `.BACKUP_*`, `.BASE_*`, `.LOCAL_*`, and `.REMOTE_*`, including versions with dot or hash prefixes. These patterns work like wildcards (a `*` stands in for any text), letting one rule match many similarly-named files.

This appears to feed into something that watches files or excludes files from search, though it's not stated exactly which feature uses the new patterns.

**Why**

Tools like Git and various merge utilities create these backup-style files when resolving conflicts, and they aren't meant to be treated as real source files. Recognizing more of these naming patterns means Claude Code is less likely to get confused by or needlessly surface leftover conflict artifacts.

- Area: File Handling
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### dirSync 'borrowed_objects' checkouts get a real confirmation check instead of a blanket refusal

Claude Code now confirms 'borrowed_objects' git directory syncs instead of always refusing them

**What**

When Claude Code's directory sync feature (`dirSync`) detects a git checkout that uses `borrowed_objects` (a shared or replaced object store), it no longer automatically refuses to run git commands there. Instead, it now runs a confirmation check (via a helper that inspects the directory's common git directory) to determine whether the borrowed or replaced object store is actually in use. Only if that check confirms the condition does Claude Code settle on a refusal; otherwise the state is left unread and retryable rather than rejected outright.

Previously `borrowed_objects` was lumped together with other conditions like `old_git`, `reftable`, and `temp_root`, all of which triggered an immediate, settled refusal with no further checking.

**Why**

This avoids blocking git operations in directories that merely look like they might use borrowed objects but don't actually confirm as such, reducing unnecessary refusals while still protecting against genuine borrowed or replaced object store situations.

- Area: Directory Sync
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### 'Tools have updated definitions' notice for deferred tool schema changes

New notice distinguishes tools with replaced definitions from newly added tools

**What**

When a set of tools' definitions changes partway through a session (a 'deferred tools delta'), Claude Code now tells apart tools that were newly added from tools whose schema (definition of what inputs they accept) was replaced. Replaced tools now produce their own distinct notice: "The following tools have updated definitions, which replace the earlier ones from here on."

**Why**

This makes it clearer when an existing tool's behavior changed mid-session versus a new tool simply becoming available.

- Area: Tool Listing
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Default filename generator for conversation export

Exported conversation text files now get a default filename based on the conversation

**Unclear.** Two slightly different filename formats appear in the evidence (slug-based vs. title-based), so the exact naming scheme isn't fully settled.

**What**

When exporting a conversation as text, Claude Code now builds a default filename automatically. If a slug (short identifier) can be derived from a user message, the filename is `<timestamp>-<slug>.txt`; otherwise it falls back to `conversation-<timestamp>.txt`. The export function now returns both the text and this `default_filename`.

**Why**

This gives exported conversations a sensible, identifiable filename automatically instead of leaving the user to name the file themselves.

- Area: Elsewhere
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### New fallback legacy-bundle path for device-bound sessions on unsupported layouts

Device-bound session uploads fall back to a legacy bundling method on unsupported layouts

**What**

When the primary, hardened method of capturing a git bundle for a device-bound session fails specifically with an `unsupported_layout` error, Claude Code now retries using a legacy capture method instead of simply failing. The retry pins the index file so it can't change mid-upload.

**Why**

This makes bundle uploads more resilient on repository layouts the primary hardened path doesn't support, so cloud/teleport sessions can still be seeded instead of failing outright.

- Area: Device Binding
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Git integrity check surfaces tampered object detection

Git integrity checks now detect and report tampered objects with a count

**What**

When Claude Code checks the health of a git repository, it can now recognize a specific kind of failure: objects that appear to have been tampered with. This is reported as a distinct `tampered_objects` cause, along with a count of how many objects were flagged, rather than being lumped in with generic git errors.

**Why**

Separating this out makes it clearer, when a repository check fails, whether the problem is ordinary git trouble or something more concerning like altered objects, and gives a concrete count to act on.

- Area: Git Integration
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Token usage now attached to conversation messages and compaction records

Token usage data is now attached to conversation messages and compaction records

**What**

When Claude Code builds conversation messages and records for compaction (the process that summarizes older conversation history to save space), it now includes a `usage` field whenever that data is available. This carries token usage information alongside the message or compaction record itself.

**Why**

Attaching usage data directly to messages and compaction records means token consumption can be tracked more precisely at the point it happens, rather than being inferred separately.

- Area: Compaction
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Post-session hook now runs with refreshed commit-signing git config

The post-session hook now runs with freshly refreshed git commit-signing config, falling back to unsigned git if the refresh fails

**What**

When Claude Code finishes a session it can run a post-session hook (a script that fires automatically at a set point). Before running that hook, Claude Code now refreshes the session's git configuration for commit signing (the settings that let git cryptographically sign commits) so any git commands the hook runs use up-to-date signing settings.

If that refresh fails for some reason, Claude Code falls back to running the hook's git commands with commit signing turned off, and logs the reason for the fallback.

**Why**

This avoids a hook's git commands failing or using stale signing configuration. If the signing setup can't be refreshed, the fallback keeps the hook running rather than blocking it, at the cost of the commit not being signed, with the reason recorded for troubleshooting.

- Area: Hooks
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### New 'ask_seat' waiting/sending status messages for multi-host permission queues

Claude Code now shows status messages while a permission request waits to be sent to another host in a multi-host setup

**Unclear.** The evidence only shows the waiting-message text; exact wording of the sending status and what triggers 'seats' in practice aren't detailed.

**What**

When Claude Code is working across multiple hosts or "seats" and a tool call needs permission from the user, requests to a given remote host are now sent one at a time. Two new status messages tell you what's happening while a request is queued:

- a message shown while an earlier permission request to that same host still hasn't been answered

- a message shown while the current request is actively being sent

**Why**

In setups where multiple permission requests could reach the same remote host at once, it wasn't clear whether a pending request was stuck, waiting on something else, or actually in progress. These messages make the queueing visible so you know your request is being handled in order rather than lost or hung.

- Area: Multi-Machine
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Artifacts tool now explains org-policy fetch failures in detail

Artifacts tool failures now explain the specific reason it couldn't reach your organization's policy setting

**What**

When Claude Code can't use the Artifacts tool because it failed to fetch your organization's policy setting for it, it now tells you specifically why instead of just saying access was denied. It can now report:

- a parse failure reading the response

- a network error

- a timeout

- an authentication failure (distinguishing a 401 "unauthorized" from a 403 "forbidden")

- a spurious "304 not modified" response

- a request failure such as a 404, 407, 429, or 5xx server error

The message names the host it tried to reach and suggests possible causes like a proxy, VPN, or web filter.

**Why**

This makes it much easier to diagnose why Artifacts isn't available, especially in corporate networks where a proxy or firewall is often the real culprit, instead of just seeing a generic "not allowed" message.

- Area: Artifacts
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Same policy-diagnostic treatment extended to marketplace-blocked-by-policy

Plugin marketplace 'blocked by policy' errors now get the same detailed diagnostic as Artifacts

**What**

When a plugin marketplace is blocked because Claude Code couldn't fetch your organization's policy (a `marketplace-blocked-by-policy` error), it now shows the same detailed diagnostic used elsewhere for policy-fetch failures, naming the host and specific error cause, instead of always showing a generic "blocked by enterprise policy" or "not in the allowed marketplace list" message.

**Why**

This gives a clearer, more actionable explanation when a plugin marketplace can't be reached, rather than a one-size-fits-all denial message.

- Area: Plugins
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### SuggestPluginInstall card gets a trigger field and follow-through instruction

Plugin-install card now records why it was shown and tells Claude to keep working afterward

**What**

The inline card that suggests installing a plugin (shown by the `SuggestPluginInstall` tool) now asks Claude to set a `trigger` field to either `proactive` (Claude brought it up on its own from task context) or `user_asked` (the user asked for it). Claude is now also explicitly instructed to continue the task after showing the card rather than stopping, with a worked example: if the user says "ship this to staging" and a deploy plugin is found, Claude should still proceed with the task.

**Why**

This keeps Claude from getting stuck after surfacing a plugin suggestion, and records why the suggestion was made for later use.

- Area: Plugins
- Names: `SuggestPluginInstall`
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Team-lead permission approvals now filter out forged mailbox messages

Team-lead permission approvals now discard forged messages from teammates

**What**

In a multi-agent team session, when a pending permission request is resolved by a message from the team lead, that incoming message is now checked by a forgery classifier before being accepted as the real decision. Messages tagged as "forged" are discarded rather than acted on.

**Why**

This prevents a spoofed or malicious message from impersonating the team lead to approve or deny a permission request in a team session.

- Area: Teammates
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Cloud review failure reasons expanded

Cloud code review shows more specific messages when a review can't finish

**What**

Cloud (asynchronous) code review now reports three additional failure states with their own specific messages, instead of a generic failure:

- the review session was archived before it finished

- the session couldn't be found, for example due to an account or organization mismatch

- the review was stopped remotely

**Why**

This makes it clearer why a cloud code review didn't produce results, rather than leaving the cause unexplained.

- Area: Code Review
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Plugin file-watch debouncer now aware of active turns and adds a 'burst' tier

Plugin file-change notifications now wait for the current turn to finish instead of firing mid-turn, and gain a new 'burst' debounce tier

**What**

Claude Code watches plugin files for changes and shows a reload notice when they change. This watcher now knows whether a turn (one round of Claude responding) is currently running: changes detected during a turn are held and only flushed once the turn ends, instead of firing immediately. A new 'burst' debounce tier has also been added alongside the existing 'storm' and per-change debounce levels, which control how changes are batched together.

**Why**

Holding notifications until a turn finishes avoids interrupting an in-progress response with a plugin reload notice, and the added debounce tier gives finer control over how bursts of file changes are batched.

- Area: Plugins
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Hooks-module skip reasons now surface to the plugin author via a notification channel, not just debug logs

Plugins are now notified directly when their hooks module is skipped, not just via a debug log line

**What**

When a plugin's hooks module (the file defining its custom hooks) is skipped — because of the `CLAUDE_CODE_ENABLE_FUNCTION_HOOKS` gate, `disableAllHooks`, `--bare` mode, or `allowManagedHooksOnly` — Claude Code already logged the reason to a debug log. Now it also delivers that reason directly to the owning plugin, through a new notification path, deduplicated so the same message isn't repeated.

**Why**

This makes it easier for a plugin author to find out why their hooks aren't loading without having to dig through debug logs.

- Area: Hooks
- Names: `CLAUDE_CODE_ENABLE_FUNCTION_HOOKS`, `--bare`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Directory sync adds a specific message for a full file store on the client machine

Directory sync shows a specific message when the client's file store is full, explaining file sync will end after the next message

**What**

If a directory-sync upload gets stuck because the file store on your machine is full, Claude Code now shows a message specific to that situation: it explains that nothing on the machine can fix the problem, and that after your next message, file syncing will stop for the rest of the session and commands will instead run directly on the files on that machine. Previously this case used the same generic message as other situations where files are held back until cleared locally.

**Why**

This gives a clearer, more actionable explanation when a full file store is blocking sync, instead of a generic message that wouldn't help since clearing space on the machine isn't something the user can be told to do from within the session.

- Area: Directory Sync
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Cross-machine tool routing gets explicit reconnect-wait messaging

Cross-machine tool routing now explains clearly when it's waiting for a machine to reconnect versus giving up

**What**

When a tool call needs to run on another machine (for example through Remote Control or cloud sessions) and that machine hasn't reconnected yet after its cloud worker was replaced, Claude Code now shows specific text explaining what's happening. There are distinct messages for:

- the machine attached earlier but hasn't reconnected yet

- the machine did not reconnect and the wait timed out

- no machine at all currently serves the requested tool

**Why**

This replaces vague or missing feedback with a clear explanation of why a cross-machine tool call is stuck or was refused.

- Area: Multi-Machine
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Tool call waits a bounded time for a machine to reconnect before failing

Cross-machine tool calls now wait a bounded time for the target machine to reconnect instead of failing right away

**What**

When a tool call is routed to a machine that hasn't announced itself yet, Claude Code now computes a wait time (`reconnectWaitMs`) and shows a status message like 'Waiting up to N s for X to reconnect…' instead of failing the call immediately.

**Why**

This gives a machine a chance to reconnect before a cross-machine tool call is treated as failed, reducing spurious failures from brief disconnects.

- Area: Multi-Machine
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Legacy global config values validated before use (remoteControlAtStartup, autoUploadSessions)

Legacy remoteControlAtStartup and autoUploadSessions settings in ~/.claude.json are now validated before use

**What**

When Claude Code reads the legacy `remoteControlAtStartup` and `autoUploadSessions` settings from `~/.claude.json`, it now checks each value against a schema before using it. If a value is invalid, it's dropped (treated as off or unset) and a one-time warning is logged for that key, rather than the raw value being trusted as-is.

**Why**

This stops a corrupted or malformed value in a legacy config file from silently causing unexpected behavior, and tells you when that happens instead of failing quietly.

- Area: Settings
- Names: `remoteControlAtStartup`, `autoUploadSessions`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### File sync warns distinctly when local storage capacity is exhausted ('lane_full')

File sync now shows a distinct warning when local storage runs out of room

**What**

The directory-sync layer has a new failure reason, `lane_full`, with its own message telling you that file sync has run out of room, instead of the generic 'checkout cannot be carried' message. Claude Code will check once more before stopping.

**Why**

This makes it clear when a sync failure is caused by running out of local storage space, rather than leaving you with a generic, less useful error.

- Area: Directory Sync
- Names: `lane_full`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### New per-agent 'sharesCwd' flag drives a model-facing worktree warning on async launch

Async-launched subagents now get an internal warning when another write-capable agent is already using the same folder

**What**

When launching a subagent (a separate Claude instance handling part of a task) asynchronously, the system now tracks an internal `sharesCwd` flag. If a subagent that can write files is launched into a working directory (folder) where another write-capable agent is already running, the launch result includes a note warning that another such agent is already active there, and suggesting the `isolation: "worktree"` option, which gives the agent its own isolated copy of the code to work in.

**Why**

This is a model-facing signal, meant to help Claude itself notice and avoid conflicts when two agents might write to the same files at once, rather than something a user configures directly.

- Area: Agent Tool
- Names: `worktree`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### The main system prompt was rewritten

The main system prompt was rewritten, including new guidance to default to the latest, most capable Claude models

**What**

The main system prompt Claude Code sends was rewritten. The new text seen in this release includes the line: "When building AI applications, default to the latest and most capable Claude models." This appears across the CLI and SDK-CLI system prompt variants for both signed-in and anonymous accounts, in the arm quoted here.

**Why**

This steers Claude toward recommending newer, more capable Claude models by default when it is helping build AI applications, rather than defaulting to older ones.

- Area: System Prompt
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Background sessions now drop and report invalid environment variables

Background sessions now reject invalid environment variables instead of silently passing them through

**What**

When Claude Code hands environment variables to a background or "spare" session, it now checks each one: variables with invalid names, non-string values, or NUL bytes in the value are dropped rather than passed through. A warning is logged naming which keys were dropped, noting that "programs it starts will not see it," and the drop is recorded in telemetry by category.

**Why**

This prevents malformed environment variables from silently breaking or misbehaving in background sessions, and makes it clear in the logs when and why a variable didn't make it through.

- Area: Sessions
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Keybinding hint bar now groups paired actions into a single combined hint

Keybinding hint bars now merge paired shortcuts like select-previous/next into one combined hint

**What**

The dimmed hint text that Claude Code shows under menus and dialogs, listing available keyboard shortcuts, now groups certain paired actions into a single combined hint instead of listing them separately. The pairs affected are select previous/next, confirm previous/next, and tabs next/previous; each now shows both key combinations together in one entry. Separately, the underlying logic that figures out which part of the screen a keypress applies to can now fall back to a nested chain of scopes when nothing nearby defines one directly.

**Why**

This makes the hint bar more compact and easier to scan by showing related shortcuts as one entry rather than two.

- Area: Terminal UI
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Teammate name reservation expanded to include 'user' and 'system'

Teammate names "user" and "system" are now reserved alongside "main" and "team-lead"

**What**

When setting up a team of Claude Code teammates, certain names are reserved because they'd collide with special recipients. The error shown when a teammate's name conflicts with a reserved name now lists "user" and "system" as reserved, in addition to the existing "main" and "team-lead" (in any capitalization).

**Why**

This stops a teammate from being named something that would be ambiguous with the built-in "user" or "system" recipients.

- Area: Teammates
- Names: `user`, `system`
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Agent tool result now appends extra text when subagent shares cwd

Agent tool results now note when a launched subagent shares the caller's working directory

**What**

When a subagent launched via the Agent tool finishes, the message reporting its result now appends extra text in cases where that subagent shared the same working directory (`cwd`) as the agent that launched it.

**Why**

This gives more context in the tool result about the relationship between a subagent and its caller when they operated in the same directory.

- Area: Agent Tool
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Database-write hint text clarifies why a file read is refused

Error message for blocked artifact database file reads now suggests passing the document inline in data instead

**What**

When a database write for an artifact tries to read a document's contents directly from a file, Claude Code still refuses this, but the explanation shown now tells you what to do instead: pass the document inline in `data`.

**Why**

This makes the refusal actionable instead of just a dead end. Rather than having to guess a workaround, you're told directly how to supply the document content so the write can go through.

- Area: Artifacts
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Reserved and spoofed marketplace names are now rejected

Plugin marketplaces can no longer be named to impersonate the reserved Anthropic directory name

**What**

When adding or reconciling a plugin marketplace, Claude Code now checks its name against the reserved name `anthropic-plugin-directory`, and also checks for spoofed variants that use lookalike characters or normalization tricks (via NFKC normalization and stripping of zero-width characters). Marketplaces that match or spoof a reserved name are refused with an explicit error.

**Why**

This prevents a malicious plugin marketplace from disguising itself as the official Anthropic plugin directory using visually similar names, protecting users from being tricked into trusting a fake marketplace.

- Area: Plugins
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### REPL activity no longer counted in conversation transcript summaries

Collapsed transcript summaries no longer count REPL (code execution) activity, only searches and file reads

**What**

When Claude Code decides whether to collapse a stretch of transcript into a summarized entry, and what that summary reports, it no longer takes REPL (read-eval-print loop, i.e. code execution) activity into account. Only search count and read count now factor into the decision and the resulting summary.

**Why**

This changes what causes a transcript to be summarized and what a collapsed summary mentions, so REPL activity alone will no longer trigger or appear in these condensed summaries.

- Area: Transcript
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### remoteToolsAnnounce oversize warning message reworded

Warning about oversized MCP tool announcements now describes the effect more accurately

**What**

When a machine's list of MCP tools it wants to announce is too large for a worker to read, Claude Code logs a warning. The trailing part of that warning changed wording, from saying the tools "stay on the device bridge" to saying "they are not offered to this worker."

**Why**

The new wording more accurately describes what actually happens to those tools: they simply aren't made available to that worker, rather than being held somewhere for later use.

- Area: Remote Tools
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### --bare and --safe-mode flag descriptions clarify plugin/hook scope

Help text for --bare and --safe-mode now clarifies they only affect plugins and settings-defined hooks, not built-in features

**What**

The command-line help text for two startup flags was clarified:

- `--bare` now explains that it only skips hooks (custom scripts that run automatically at certain points) defined in your settings or added by installed plugins; features built into Claude Code itself keep working.

- `--safe-mode` now states that built-in tools and plugins both continue to work while safe mode disables other customizations.

- The list of things `--safe-mode` disables now says "installed plugins" instead of just "plugins", to be more precise about scope.

**Why**

These flags are meant for stripping down or troubleshooting your setup, and the clearer wording makes it easier to know exactly what still runs versus what gets turned off, without needing to test it by trial and error.

- Area: CLI
- Names: `--bare`, `--safe-mode`
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Repository-too-large upload error message reworded

Error message for repos too large to upload was reworded

**What**

The error message shown when a repository is too large to bundle or upload for a remote session was changed to new wording: "the repository is over the size limit for an upload."

**Why**

This just changes the phrasing of an existing error; the size limit and underlying behavior aren't described as changing.

- Area: Sessions
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### OPENSSL_CONF added to sanitized/stripped environment variables

OPENSSL_CONF is now stripped from subprocess environments like other security-sensitive variables

**What**

When Claude Code spawns subprocesses, it strips certain environment variables for security, such as `LD_PRELOAD`, `LD_AUDIT`, `DYLD_INSERT_LIBRARIES`, and `NLSPATH`. `OPENSSL_CONF` has now been added to this list.

**Why**

`OPENSSL_CONF` can point to a custom OpenSSL configuration file, which could be abused to alter how cryptographic operations behave in a spawned process. Stripping it closes off that avenue.

- Area: Permissions
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Doctor/diagnostic output now redacts gateway, Bedrock and proxy URLs

Diagnostic output now hides the actual Gateway, Bedrock, and proxy URLs behind redaction

**What**

The connection info shown in diagnostic output (such as `/doctor`) now runs the Gateway URL, the Bedrock (Mantle) base URL, and the proxy value through a redaction step before displaying them, instead of showing the raw configured URL.

**Why**

This keeps potentially sensitive connection URLs out of diagnostic output that might be shared or screenshotted for troubleshooting.

- Area: Diagnostics
- Names: `/doctor`
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### AWS access-key redaction pattern broadened

AWS access-key redaction in logs now covers more key-ID prefixes, not just AKIA and ASIA

**What**

The pattern used to scrub AWS access keys from transcripts and logs previously matched only keys starting with `AKIA` or `ASIA`. It now also matches `ABIA`, `ACCA`, and the STS pattern `A3T[A-Z0-9]`, each followed by 16 alphanumeric characters, replacing matches with `<token>`.

**Why**

AWS issues credentials under several different prefixes; broadening the pattern reduces the chance that a real AWS credential of one of these other types leaks into a transcript or log unredacted.

- Area: Permissions
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Cloud session "uploading folder" status text removed

Cloud session setup no longer shows folder-specific wording during the upload step

**What**

When Claude Code sets up a cloud sandbox session (an isolated remote environment it can work in), it shows status text for each setup step: checking, bundling, uploading, and creating. The upload step used to show folder-specific wording like "Uploading/Uploaded this folder" when uploading a plain local folder; it now shows the same generic repository-upload text used in other cases.

**Why**

This simplifies the status messages shown during cloud session setup, at the cost of the more specific "this folder" wording previously shown for local folder uploads.

- Area: Cloud Sessions
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### "Press ... again to exit" changed to "cancel" in one UI branch

One keybinding hint now says "press ... again to cancel" instead of "to exit"

**Unclear.** The finding does not say which specific component or pending action this hint appears in.

**What**

In one part of the interface that uses a pending state, the hint text shown for a keybinding changed from prompting you to press a key again to exit, to prompting you to press it again to cancel.

**Why**

This makes the hint more accurate for situations where the action being interrupted is a cancel rather than a full exit.

- Area: Elsewhere
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Safe-mode banner clarifies that built-in plugins keep working

Safe-mode messages now clarify that built-in plugins keep working while installed plugins are disabled

**What**

The warning text shown in the plugin-settings screen when safe mode is on has been rewritten. It now says more clearly that:

- Only *installed* plugins are disabled for the session

- Changes made to installed plugins while in safe mode still save, but won't take effect until safe mode is turned off

- Built-in plugins (the ones that ship with Claude Code) are unaffected and keep working

The related message shown when plugin hooks (custom scripts plugins can run at certain points) are skipped during safe mode was reworded the same way, confirming that built-in plugins continue to load and run even in safe mode.

**Why**

Safe mode is meant to temporarily disable plugins you've installed, not the built-in functionality Claude Code ships with. The earlier wording could leave that ambiguous; the new text makes clear which plugins are actually turned off and what happens to unsaved or pending changes, so there's less confusion about what still works while safe mode is active.

- Area: Elsewhere
- Names: `--safe-mode`
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### OpenSSL environment variables now passed through to git subprocesses

OpenSSL environment variables are now passed through to git subprocesses

**What**

When Claude Code runs git commands, it now passes through four OpenSSL-related environment variables — `OPENSSL_CONF`, `OPENSSL_CONF_INCLUDE`, `OPENSSL_MODULES`, and `OPENSSL_ENGINES` — to the git subprocess, the same way it already handled variables like `DEVELOPER_DIR` and `GIT_TEXTDOMAINDIR`.

**Why**

Previously these OpenSSL variables were either dropped or split incorrectly when git commands ran, which could break custom OpenSSL configurations (such as those used for enterprise certificate setups). Passing them through as intended lets such configurations work correctly with git operations.

- Area: Git Integration
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Bash-tool-available note added to shell-selection text

Shell-selection guidance now notes the Bash tool is also available alongside the primary shell

**What**

The text describing the primary shell to use (for example, PowerShell on Windows) now includes an added note that the Bash tool is also available for POSIX scripts, and that each shell takes its own syntax.

**Why**

This clarifies for Claude that it isn't limited to the platform's default shell and can reach for the Bash tool when POSIX-style scripting is more appropriate, reducing confusion about which syntax to use where.

- Area: Elsewhere
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Directory-sync notice distinguishes a full file store from other failures

Directory-sync failure messages now specifically call out a full file store as the cause

**What**

When a shell command's effects can't be synced back because a cloud session's file store is full, the notice now says so explicitly, rather than showing the generic "its Claude Code says" detail text used for other sync failures.

**Why**

This makes it clear when the problem is that storage has run out, rather than leaving the cause unclear behind a generic message.

- Area: Directory Sync
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### request_user_dialog bridge logs and handles 'malformed' results separately

Malformed dialog responses from the client now get their own warning log

**What**

When the `request_user_dialog` bridge feature receives a response from the client that it cannot read ("malformed"), it used to be treated the same as a cancelled dialog, silently falling back to the default answer. It now logs a warning specifically for the unreadable case before falling back, instead of grouping it silently with cancellations.

**Why**

This makes it easier to notice and diagnose cases where a client sent a response Claude Code couldn't parse, rather than having that failure look identical to the user simply cancelling the dialog.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Background job environment entries are now individually logged when dropped

Claude Code now logs a separate warning for each background job environment variable it drops

**What**

When Claude Code runs a background job, it checks the environment variables being passed to it and drops any that fail validation. A new function now logs a separate warning for each dropped variable, naming the variable and the specific reason it was dropped:

- the variable name is invalid

- the variable's value is not a string

- the variable's value contains a NUL character

**Why**

Previously a dropped environment variable would not be called out individually. Logging each one by name and reason makes it easier to spot why a background job is missing an environment variable it was supposed to have.

- Area: Sessions
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Plugin bundle/upload progress skips the upload step when already synced

Plugin publishing skips the redundant upload step when the plugin was already synced

**What**

When publishing a plugin, Claude Code shows a progress list of steps such as 'bundle' and 'upload'. Previously, the 'upload' step was always shown after 'bundle', even if there was nothing new to upload. Now that step is left out when the plugin's content was already uploaded via sync (`uploadedBySync`).

**Why**

This keeps the progress display accurate: it no longer implies an upload is happening when the plugin's files are already synced and there's nothing left to send.

- Area: Plugins
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### New PowerShell-specific error classifiers for command-not-found

Claude Code now recognizes PowerShell's own "command not found" errors

**What**

Claude Code's shell error classifier can now recognize two more ways a "command not found" error can look:

- PowerShell's own wording, such as "is not recognized as the name of a cmdlet" or "internal or external command"

- .NET's `CommandNotFoundException`

**Why**

When Claude Code runs a shell command that fails, it tries to classify the error so it can respond appropriately (for example, recognizing that a program simply isn't installed). Previously this matching was tuned for Unix-style shells; with these additions, the same kind of failure on Windows PowerShell is now caught too.

- Area: PowerShell
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### New hint text for a pending double-press action (likely voice mode cancel/exit)

A new 'press again to cancel/exit' hint appears for a pending double-press action

**Unclear.** The finding suggests this is tied to voice mode cancel/exit but doesn't confirm that scope.

**What**

A status hint area now shows a message like "Press [key] again to cancel" or "Press [key] again to exit" when an action is waiting on a second key press, appearing ahead of the existing search and filter hints.

**Why**

This makes it clearer when Claude Code is waiting for you to confirm an action by pressing the same key again, rather than leaving you unsure whether the first press registered.

- Area: Elsewhere
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Device-revoked session message removed; unified unbound-session message used instead

The specific "device removed from claude.ai" explanation was dropped in favor of a generic unbound-session message

**What**

Claude Code previously showed a specific message when a machine had been removed from your claude.ai devices, explaining that it couldn't register again yet. That message has been removed. Now, that case falls through to the same generic message used for any unbound session: "Start a new session to attach this machine; this one began unbound (no sync-back or local commands)."

**Why**

A reader who sees this message after a device was revoked will get the generic wording rather than an explanation specific to device revocation.

- Area: Device Enrollment
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Symlinks now reported as their own "irregular" file reason

File-access errors now report symlinks specifically as "a link" instead of a generic irregular-file message

**What**

When Claude Code checks whether a file path is usable and finds it isn't a plain file, it now distinguishes symbolic links from other cases. A symlink is now reported with the reason `"a link"` instead of the generic message used for other irregular files.

**Why**

This gives a clearer, more specific explanation when a tool can't use a path because it's a symlink, rather than lumping it in with other unusable file types.

- Area: File Handling
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Status output now masks configured base URLs

Base URLs shown in status/doctor output are now masked instead of shown in full

**Unclear.** The finding does not say exactly how the value is masked (e.g. partially hidden vs. redacted) or how much of the URL remains visible.

**What**

When Claude Code shows configured provider base URLs in its status or doctor output, those values are now passed through a masking function before being displayed. This applies to the base URL entries for Anthropic, Bedrock, Vertex, Foundry, Claude-Platform-on-AWS, and Claude-Platform-on-Google-Cloud. Previously the raw value from the environment was shown as-is.

**Why**

Base URLs can contain account-specific or otherwise sensitive details, so masking them in status/doctor output reduces the chance of exposing that information when sharing screenshots or logs for troubleshooting.

- Area: Diagnostics
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### CLI now prints an explicit stop notice before a generic 'Execution error'

Claude Code now prints a specific stop notice before the generic 'Execution error' message

**Unclear.** The finding does not say what triggers the 'automatic mode unavailable' condition or what 'auto mode' refers to.

**What**

When a command fails with the `error_during_execution` result, the CLI now prints an extra line to stderr (the terminal's error output) before the existing generic 'Execution error' message, if one was recorded. This new line explains that automatic mode is unavailable.

**Why**

Previously a failure in this case only showed the generic 'Execution error' text, giving no clue as to the specific cause. The added notice gives a more specific reason for the stop, making it easier to understand why execution halted.

- Area: CLI
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Debug-log hint message reworded

The dim hint pointing to debug logging now spells out what the debug file explains

**Unclear.** It's not fully clear which specific warning or error message the new fixed suffix string is appended to.

**What**

A dim hint shown alongside some failure and log messages was reworded. It used to give a terse instruction; it now reads more explicitly, telling you to restart with `--debug-file <path>` to write a debug log explaining why something happened. A related fixed suffix string was also added, appearing to point users toward the debug log for more detail when a warning or error message is shown.

**Why**

The clearer wording makes it more obvious that restarting with `--debug-file` produces a log explaining the cause of a problem, rather than just a generic debug dump, which should make it easier to know when and why to reach for it.

- Area: Debugging
- Names: `--debug-file`
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### 'Get the Claude app on your phone' QR dialog now requires a confirm-close (press Esc twice)

The phone-app QR code dialog now needs Esc pressed twice to close instead of once

**What**

The onboarding dialog that shows a QR code for getting the Claude app on your phone now requires pressing Escape twice to close. The first press shows a 'Press Esc again to close' prompt instead of closing the dialog immediately.

**Why**

This prevents the dialog from being dismissed by an accidental single Escape press, requiring a deliberate second press to confirm closing it.

- Area: Terminal UI
- Names: `Esc`
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Sanitization of a spoofable from-plugin attribute in tagged content

Claude Code now strips fake from-plugin attributes from text before checking internal task tags

**What**

Claude Code uses internal tags to track metadata about tasks and subagents (helper AI instances it delegates work to), including attributes like `from`, `from-session`, `hop-chain`, `from-name`, `from-mode`, and `from-plugin`. A new step now strips out any `from-plugin="..."` attribute found in ordinary text before that text is checked against the internal tag format.

**Why**

Without this, content coming from a user or from a tool's output could include a fake `from-plugin` attribute crafted to look like it came from Claude Code's own internal tagging system. Stripping it first closes off that spoofing path, so internal tag matching can't be fooled by attacker-supplied text claiming to originate from a plugin.

- Area: Permissions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact deploy capability_refused errors now aggregate and truncate multiple entries

Capability-refused errors during artifact deploy now get summarized and truncated instead of shown raw

**What**

When an artifact deploy fails with a 422 `capability_refused` error, Claude Code now parses the server's message, which can list multiple `capabilities.*` entries, and keeps only as many as fit within a size limit. If entries are cut off, it appends a note saying how many more aren't shown, and adds a closing instruction to fix each named entry and republish. Previously the raw error message was passed through as-is.

**Why**

This keeps capability-refused error messages readable and actionable even when many entries are refused at once, instead of dumping a potentially huge raw error.

- Area: Artifacts
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Opus 4.8 relabeled from 'Previous Opus version' to 'Legacy'

Opus 4.8 is now labeled 'Legacy' in the model picker instead of 'Previous Opus version'

**What**

In the model picker, the description shown next to Opus 4.8 changed from "Previous Opus version" to "Legacy."

**Why**

This is a wording change only, so what the label communicates about Opus 4.8's status stays the same: it is not the current Opus model.

- Area: Models
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### New 'Checking GitHub CLI installation…' UI state

Claude Code shows a 'Checking GitHub CLI installation…' spinner during a setup step, with a cancel hint

**Unclear.** The finding does not say which settings flow triggers this check or what happens after it completes.

**What**

A settings step that checks whether the GitHub CLI (`gh`) is installed now shows a spinner with the message 'Checking GitHub CLI installation…', along with a hint for how to cancel it.

**Why**

This gives a clearer visual signal while Claude Code checks for `gh` on your system, instead of leaving that step silent, and lets you cancel out of it if needed.

- Area: Elsewhere
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Skills-dir plugin adoption failure message now names the bad manifest file

Skills-directory plugin errors now name the bad manifest file instead of a generic warning

**What**

Claude Code can sync a folder of skills (pre-packaged instructions for a task) and adopt subfolders as plugins. If the sync manifest file in that skills directory can't be read or is not valid, Claude Code now shows a warning naming the actual file instead of a generic error message.

The warning also spells out the consequence: no folder in that directory is adopted as a plugin until the bad file is fixed or removed.

**Why**

Previously a generic message left you guessing which file was the problem. Naming the file makes it much faster to find and fix, or delete, the file that's blocking plugin adoption.

- Area: Plugins
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Daemon log auto-truncates past 10MB

The Claude Code daemon now truncates its log file once it passes 10MB

**What**

The background daemon process that Claude Code runs now checks the size of its log file each time it writes to it. Once the log grows past 10MB, it gets truncated or rotated before Claude Code continues appending new entries.

**Why**

This keeps the daemon's log file from growing without bound, avoiding unnecessary disk usage over long-running sessions.

- Area: Daemon
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Session recovery now repairs malformed stop-hook summaries

Session recovery now repairs malformed stop-hook summaries and other bad system rows

**What**

When Claude Code recovers a session transcript, its summary of repairs now reports two new categories: stop-hook summaries whose fields don't match the shape this build expects, and other malformed system rows. These are counted and reported alongside the existing counts for dropped, wrapped, and cleaned entries.

**Why**

This lets Claude Code fix up more kinds of corrupted transcript data during recovery, and tells you specifically when stop-hook summaries or other system rows needed repair.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Fast-mode picker toggle key changed from Tab to Space

Toggling fast mode on/off in its confirmation dialog now uses the Space key instead of Tab

**What**

In the Fast mode confirmation dialog, the key shown and used to switch fast mode on or off changed from `Tab` to `Space`.

**Why**

The on-screen hint now matches the actual key that toggles the setting, so pressing `Space` in that dialog is the correct way to turn fast mode on or off.

- Area: Models
- Names: `Space`
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Artifact 429 retry now skipped when retry-after exceeds a cap

Artifact upload no longer retries a 429 error if the server's suggested wait time is too long

**Unclear.** The exact threshold value and what happens after the immediate return (e.g. whether the upload is reported as failed) aren't stated.

**What**

When an artifact upload gets rejected with a 429 error ("too many requests"), the server can include a `retry-after` header telling Claude Code how long to wait before trying again. Previously, Claude Code always retried, capping that wait at 30000 milliseconds even if the server asked for longer. Now, a new helper only returns the server's suggested delay if it's under a set threshold; if the server asks for a longer wait, Claude Code gives up and returns immediately instead of retrying.

**Why**

This avoids Claude Code sitting around retrying an upload when the server has signaled it needs a long cooldown, failing faster instead of blocking on a lengthy wait.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Failed staged-file create now attempts async cleanup instead of a bare unlink

Claude Code now retries cleanup of a stuck staged file instead of a single silent delete attempt

**What**

Claude Code stages files temporarily as part of syncing changes. If creating one of these staged files failed for a reason other than the file already existing, the old code just tried to delete the leftover file once and silently ignored any error. Now it calls a new helper that retries checking for and removing the stuck file a few times, and logs what happened along the way.

**Why**

This makes cleanup after a failed staged-file creation more reliable, since a single unlogged attempt could leave a stuck file behind with no record of what went wrong. The retries and logging give a better chance of actually clearing the problem and make it easier to diagnose if it doesn't.

- Area: File Sync
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Provider env state validated against saved job state

Restored background-job provider environment variables are now validated, not just copied

**What**

When Claude Code restores the provider environment settings (`providerEnv`) from a saved background job's `state.json` file, it now runs those values through a validation and sanitization step, rather than copying them through unchanged.

**Why**

Validating restored environment data before reusing it guards against a saved job state being stale, malformed, or unsafe to apply directly.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### 'off' status indicator style changed

The 'off' status badge now shows a circle in a neutral color instead of a red cross

**What**

In a status listing (used for skills or features), the badge shown for an 'off' state changed its look: it used to be a cross glyph in an 'error' (red-style) color, and is now a circle glyph in an 'inactive' color.

**Why**

This makes 'off' read as a neutral, inactive state rather than an error, which better reflects that something being off isn't necessarily a problem.

- Area: UI Components
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### LOCPATH added to sanitized/dangerous env var list

LOCPATH added to the list of environment variables Claude Code strips from subprocesses

**What**

`LOCPATH` has been added to the list of environment variables that Claude Code strips or guards against when launching subprocesses, joining others like `LD_AUDIT`, `GCONV_PATH`, `NLSPATH`, `PSMODULEPATH`, and `DYLD_INSERT_LIBRARIES`.

**Why**

These variables can be used to inject code or alter how programs load libraries or locale data. Stripping `LOCPATH` closes another potential way for a subprocess's behavior to be tampered with via the environment.

- Area: Permissions
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### HEAD updates now create a reflog entry

Updating HEAD via git now always creates a reflog entry

**What**

When Claude Code updates the git `HEAD` reference internally (using `update-ref`), it now passes the `--create-reflog` flag in addition to the existing `--no-deref` flag. A reflog is git's record of where a reference has pointed over time, letting changes be traced or undone.

**Why**

Ensuring a reflog entry exists for these HEAD updates makes it possible to trace or recover from changes Claude Code makes to HEAD, even in repositories where a reflog might not otherwise have been created.

- Area: Git Integration
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Bridge fetch helper retries once after a null result

Bridge fetch helper now retries once after a null result

**What**

A low-level fetch wrapper used internally for things like account and session lookups now retries once, after waiting 2 seconds, if the first attempt returns null. Previously it would return immediately without retrying.

**Why**

This should make account and session lookups more resilient to transient failures that return no result, instead of giving up on the first empty response.

- Area: Sessions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### MCP tool-call errors can now withhold error text from telemetry

Claude Code can now hide MCP tool-call error text from telemetry when the call's arguments were already redacted

**Unclear.** The finding does not say what the redacted placeholder text looks like or exactly which conditions mark an MCP tool call's args as redacted.

**What**

Claude Code connects to external tools through MCP (Model Context Protocol, a standard way for Claude Code to call out to other tools and services). When an MCP tool call fails and its arguments had already been redacted (hidden for privacy), Claude Code can now also withhold the error message itself before it is sent to telemetry, the internal system that records what happened during a session for diagnostics.

This only applies to a specific kind of internal error tied to an MCP tool call whose arguments were flagged for redaction. In that case, the recorded error text is replaced with a redacted placeholder instead of the real message.

**Why**

This closes a gap where sensitive information could still leak out through an error message even after the tool call's arguments had been redacted. Error text sent for diagnostics should not reveal what the redaction was meant to hide.

- Area: MCP
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Refined 'safeguards flagged this message' refusal wording

Safety-refusal message now distinguishes 'your last message' from 'this message'

**What**

When Claude's safety systems flag a message and Claude Code can't respond, the refusal wording now varies: if a specific category detail is available, it says "Claude Code can't respond to your last message with X"; otherwise it says "Claude Code can't respond to this message with X".

**Why**

This makes the refusal message slightly more precise about what triggered it when that detail is known.

- Area: Permissions
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### MCP wait tool now reports a 'mcp_disabled' remedy

Waiting for MCP servers now reports a specific 'mcp_disabled' remedy listing which servers are disabled

**What**

The logic that waits for MCP servers to become ready (logged as `[WaitForMcpServers]`) now returns a `remedy` object with kind `mcp_disabled` and a list of the disabled servers, when applicable. This is in addition to its existing breakdown of ready, connected, failed, and disabled servers.

**Why**

This gives a more actionable signal when MCP servers aren't ready because they're disabled, naming which servers are affected instead of just reporting a general readiness failure.

- Area: MCP
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Auto-compact window slider keybinding changed

Adjusting the auto-compact window now uses Left/Right arrow keys instead of Up/Down

**What**

The keybinding hint shown while adjusting the auto-compact window setting (which controls when conversation history gets automatically compacted) changed from an up/down chord labeled "change" to a left/right chord labeled "adjust".

**Why**

Anyone adjusting the auto-compact window setting should now use the `Left`/`Right` arrow keys instead of `Up`/`Down`.

- Area: Terminal UI
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Transcript repair now also fixes malformed 'system' rows, including stop-hook summaries

Transcript repair now also fixes corrupted 'system' rows, including stop-hook summary rows, and reports counts via telemetry

**What**

Claude Code repairs corrupted rows in a session's transcript when it loads or resumes a session. This repair pass now also covers rows of type `system`, specifically the `stop_hook_summary` subtype used to summarize what a stop hook (a script that runs when Claude finishes responding) did. Fields like `hookCount`, `hookInfos`, `hookErrors`, `hookAdditionalContext`, `preventedContinuation`, `stopReason`, `hookLabel`, and `totalDurationMs` are cleaned and normalized.

Repair activity is now tracked separately as `stopHookSummariesRepaired` and `otherSystemRowsRepaired`, and reported through a new telemetry event.

**Why**

This closes a gap where malformed stop-hook summary rows in a transcript could previously go unrepaired, which could otherwise cause problems loading or resuming a session.

- Area: Transcript
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### MCP RPC content redacted from tracing for memory/dynamic-SDK tools

MCP tool-call content is now redacted before being sent to tracing for the memory server and dynamic SDK-scoped tools

**What**

When Claude Code sends a tracing span for an MCP (Model Context Protocol) tool call, it now checks whether the tool belongs to the memory server or is a dynamic SDK-scoped MCP tool. If so, the captured content is replaced with a redaction placeholder before it's recorded in the trace.

**Why**

This prevents potentially sensitive content from memory-server or dynamic SDK tool calls from being captured in tracing data.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New login-required error message for Remote Control

New error message tells users without a claude.ai login that Remote Control requires signing in

**What**

If someone without a claude.ai subscription or login tries to use Remote Control, Claude Code now shows a specific error: "You must be logged in to use Remote Control. Remote Control is only available with claude.ai subscriptions. Run `claude auth login` to sign in with your claude.ai account."

**Why**

This gives a clear, actionable message instead of a generic failure when Remote Control is used without the required login.

- Area: Remote Control
- Names: `claude auth login`
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Directory-search exclusion text updated to mention cross-host links

Directory search explanation now notes that directories pointing to another host are excluded

**What**

When git can't be found and Claude Code explains why it's searching for writable directories a bound cloud session can use, the explanatory text now also notes that directories that name or lead to another host are excluded from that search.

**Why**

This clarifies for the reader why certain directories won't show up as candidates, avoiding confusion about directories that look reachable but point across hosts.

- Area: Cloud Sessions
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Duplicate hooks file message reworded

Duplicate-hooks-file error message shortened, dropping the auto-load explanation

**What**

The error message shown when a plugin manifest lists the same hooks file more than once was rewritten to be shorter. It no longer explains that `hooks/hooks.json` is loaded automatically.

**Why**

This trims the message to be more concise, though users who relied on the dropped explanation to understand why the duplicate mattered will no longer see it.

- Area: Plugins
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Git-based credential/denied-commit scan now supports multiple excluded refs

The scan for denied or credential-named commits can now exclude multiple git refs at once

**What**

The internal check that looks for denied or credential-named commits used to compare a single `base..target` commit range. It now runs `git rev-list` against a target commit plus a `--not` clause listing multiple excluded refs.

**Why**

This lets the scan exclude several branches or refs at once rather than being limited to one base, making the check more accurate in repositories with more than one relevant baseline.

- Area: Permissions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New credential/secret redaction pattern for tool output

A new, broader redaction pattern hides secret keys and tokens found in tool output

**What**

A new redaction routine scans text for patterns that look like credentials, such as AWS secret keys, bearer tokens, and session tokens, written as either `key=value` or `key: value`, including escaped or quoted forms. Any matching value is replaced with `<token>`.

Placeholder-like values, such as `undefined`, `null`, `none`, `true`, `false`, `bearer`, or `basic`, are left alone rather than redacted, since they aren't actual secrets.

**Why**

This reduces the chance that real credentials get shown or logged when they appear in tool output.

- Area: Permissions
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Schema validation errors truncate long 'expected tags' lists

Validation error messages now truncate long lists of expected type tags instead of dumping them all

**What**

When schema validation rejects a `type` field for not matching any of the expected options (a discriminated union, where the value determines which shape the rest of the data should have), the error message now shortens long lists of expected tags to a placeholder like `<tags.N>` and caps the overall message length, instead of printing every expected tag.

**Why**

This keeps validation error messages readable instead of overwhelming you with a huge list of possible type tags.

- Area: Error Handling
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Doctor/hooks list truncation now uses shared 'N more' component

Doctor's hooks list now shows truncated 'N more' text using the same shared component as other lists

**Unclear.** The finding doesn't confirm the exact wording produced or which other lists share this component.

**What**

When the `/doctor` status display shows a list of hooks (scripts that run automatically at certain points, like before a tool runs) that's too long to fit, it now uses a shared component to render the '...and N more' message, instead of building that text itself. The component is passed `unit: "hook"`, so the truncation message reads in terms of hooks specifically.

**Why**

This is an internal cleanup that makes truncated-list messages consistent across different parts of the doctor/status display, rather than each list formatting its own version of the same text.

- Area: Diagnostics
- Names: `/doctor`
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Confirmation-card UI stops wrapping artifact/frame replace URLs

Confirmation dialogs now keep artifact/frame replacement URLs on one line instead of wrapping them

**What**

In the confirmation card shown before certain actions, lines like `replacing: https://.../artifact/<uuid>` or `.../frame/<id>` are now recognized by a new pattern. When a row's value matches, it is truncated with an ellipsis instead of wrapping across multiple lines.

**Why**

This keeps long artifact and frame URLs readable on a single line in the confirmation UI instead of breaking awkwardly across several lines.

- Area: UI Components
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Effort-level display gate removed (now unconditional)

Effort-level value in the UI is now always shown when present, no longer gated behind internal checks

**What**

The function that extracts a displayable effort-level value (how much reasoning effort a model is set to use) previously only returned that value if two internal gate checks both passed. That requirement has been removed, so the value is now returned whenever it's present.

**Why**

This means the effort-level value, when set, is no longer hidden by conditions that previously could suppress it from being shown.

- Area: Effort
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### New multi-agent permission queueing status strings

New status messages show when a permission request is queued behind another agent's pending request

**What**

Two new status-line messages were added for multi-agent situations: one shown while a permission request is waiting because another agent's permission request hasn't been answered yet, and one shown while a permission request is actively being sent.

**Why**

This gives clearer feedback in multi-agent setups about why a permission prompt hasn't appeared yet, distinguishing a genuine wait from an in-progress send.

- Area: Elsewhere
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### The main system prompt in the agent-claude prompt was rewritten

The agent-claude system prompt was rewritten to reference the Claude 5 family and Haiku 4.5

**What**

The main system prompt used in the agent-claude context was rewritten. The new text states: "The most recent Claude models are the Claude 5 family and Haiku 4.5."

**Why**

This updates the model list Claude is told about in this context, which affects how it answers questions about which Claude models currently exist.

- Area: System Prompt
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Peer address debug string simplified

The Peer address line in the debug info panel no longer tells you to check the --debug log

**Unclear.** The finding does not say what the new unavailable-reason formatting looks like, only that it was simplified.

**What**

The 'Peer address' line shown in a debug/info panel has been simplified. It no longer includes the hint text '(details in the --debug log)', and the way it describes why the address is unavailable has been reworded to be simpler.

**Why**

This is a small display cleanup. If you were used to seeing a pointer toward the `--debug` log next to 'Peer address', you won't see it anymore; the unavailable-reason text itself is just presented more simply now.

- Area: Debugging
- Tier: You'll notice
- Useful: 1/5
- Signal: 0/5

## Bug Fixes

### Proxy auth helper retry detection widened to tunnel/CONNECT errors

Proxy auth helper now also detects 407 errors hidden inside proxy-tunnel/CONNECT failures

**What**

Claude Code's configurable proxy authentication helper (enabled via `CLAUDE_CODE_ENABLE_PROXY_AUTH_HELPER`) kicks in when a proxy responds with an HTTP 407 (authentication required) status. Previously this only checked a single, direct status field. It now uses a new helper that also recognizes 407 errors buried inside a proxy-tunnel error (`ERR_PROXY_TUNNEL`) or wrapped inside other exception types, and extracts the `proxy-authenticate` challenge header from those cases too. The retry decision now goes through an additional gating step before the auth cache is reset and the pending challenge is stored.

**Why**

Some proxies report authentication failures as tunnel/CONNECT errors rather than a plain HTTP response, so this change lets the proxy auth helper catch and retry those cases too, instead of missing them and failing the connection.

- Area: Elsewhere
- Names: `CLAUDE_CODE_ENABLE_PROXY_AUTH_HELPER`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Duplicate/legacy "Allowed <commands>" and memory-saved lines get de-duplicated before rendering

Claude Code now removes duplicate command/path entries before showing 'Allowed' and memory-saved permission summaries

**What**

When Claude Code shows a summary line for a permission retry (an "Allowed " message) or for a memory-saved event (paths remembered for future permission decisions), it now filters the list of commands or paths through a de-duplication step before building the text shown to you. If nothing is left in the list after removing duplicates, Claude Code no longer shows that summary line and falls back to its older, legacy way of rendering the event.

**Why**

This prevents the same command or path from appearing more than once in these summary messages, so the "Allowed" and memory-saved lines you see stay accurate and uncluttered.

- Area: Permissions
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Context usage reporting is now awaited and errors are caught

Context usage reporting is now awaited and its errors are caught before other logic runs

**What**

When Claude Code reports how much of the context window (the space available for the conversation) has been used, it now waits for that report to finish, and wraps it in error handling, before moving on to idle-report and cost-push logic. Previously this report was fired off without waiting for it to complete.

**Why**

This prevents a context-usage report from silently failing or racing with the logic that runs after it, making that sequence more reliable.

- Area: Context Usage
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Rate-limit banner is now cross-checked against the actual limit type before rendering

Claude Code now checks a rate-limit warning's wording against the real limit type before showing it

**What**

When Claude Code hits a usage limit, it shows a banner warning (like "You've hit your session limit"). A new internal check now reads the wording of that message, works out which kind of limit it's talking about (session, weekly, or model-specific), and compares that against the actual limit type reported by the API.

- If the two match, the banner is shown as before.

- If they don't match, the banner is suppressed and not shown.

**Why**

This prevents a mismatched or stale warning banner from being displayed, for example one that talks about a session limit when the real limit that was hit is a weekly or model-specific one. It should make rate-limit banners more trustworthy when they do appear.

- Area: Usage & Limits
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### File-write external-modification guard is now properly awaited and includes an I/O path

The check that guards against editing a file changed on disk is now properly waited for before continuing

**Unclear.** The finding does not say what triggers the new `staged_for_review` remedy or how it changes the user-visible flow beyond appearing in returned state.

**What**

When you use Edit or Write, Claude Code checks whether the file was changed on disk since it was last read, so it doesn't overwrite changes it doesn't know about. That check now runs correctly:

- It only runs when both the file handle and the previously read content are actually available, instead of potentially running with missing data.

- Its result is now properly waited for (`await`ed) before Claude Code moves on, instead of being fired off without waiting for the answer.

- It now also receives a new `ioPath` value as part of its input.

- The status Claude Code returns for a file can now include a `remedy` field of the form `staged_for_review`, showing the file's path when this applies.

**Why**

Previously, the disk-modification check could run without being waited for, meaning Claude Code might proceed with an edit before knowing whether the file had actually changed underneath it. Awaiting it properly closes that gap, making the guard against clobbering externally-modified files more reliable.

- Area: Elsewhere
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Queued message submission now uses the draft's live permission mode

Sending a queued message now uses whatever permission mode is currently active, not the one from when it was queued

**What**

When a message is queued up and then submitted, either through `submitEmpty` or by using `sendQueuedNow` to send it immediately, Claude Code now builds the submission using the draft's current permission mode (or an explicitly passed mode), instead of a mode that was fixed at an earlier point.

**Why**

If the permission mode is changed while a message sits in the queue, the queued send now reflects that updated mode rather than sending under the stale mode it was queued with.

- Area: Message Queue
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Plugin uninstall no longer deletes a data directory shared by a same-named plugin in another scope

Uninstalling a plugin no longer deletes a data directory still used by a same-named plugin elsewhere

**What**

When uninstalling plugins by author, Claude Code now checks whether any of the plugins being removed share a name (case-insensitive) with another plugin that is still installed elsewhere. If so, it skips deleting that plugin's on-disk data directory. Previously, uninstalling always deleted the data directory of every removed plugin, even if another installed plugin with the same name still needed it.

**Why**

This prevents uninstalling one plugin from wiping out data that a same-named plugin in a different scope is still relying on.

- Area: Plugins
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Gateway base URL now resolved from stored gateway auth credentials

Base URL lookup for the gateway provider now returns the stored gateway auth URL instead of nothing

**Unclear.** The finding does not say what previously happened downstream when this lookup returned undefined, so the practical impact of the earlier gap is not stated.

**What**

When Claude Code resolves the base URL to use for the `gateway` provider (a setting for routing requests through a gateway server rather than directly), it now reads that URL from the stored gateway authentication credentials on the machine. Previously this lookup returned nothing for the `gateway` case.

**Why**

Without a URL being returned, requests relying on this lookup for the `gateway` provider had no base URL to use. Pulling the URL from the stored gateway auth state means the correct address is now actually supplied.

- Area: Auth
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Marketplace load-failure reporting now filters which errors are shown as warnings vs blocking

Marketplace load-failure messages now filter which errors surface as warnings versus blocking errors

**What**

When Claude Code fails to load plugin marketplaces, the function that builds the failure message now runs the list of errors through a filter before deciding whether to show it as a warning or a blocking error. If filtering removes every error but some raw errors still exist, it now falls back to showing a generic warning listing each error, instead of returning nothing.

**Why**

This avoids marketplace load failures going unreported: a filtered-out error is no longer treated as if there were nothing to say, so a warning still appears when something actually failed.

- Area: Plugins
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### 'gateway' provider type now correctly maps to thirdParty

The 'gateway' provider/auth type is now correctly classified as thirdParty instead of being unclassified

**What**

Internal logic that classifies which kind of provider or authentication setup is in use previously had a gap: the 'gateway' case fell through without being classified, returning nothing. It now correctly groups with foundry, anthropicAws, and anthropicGoogleCloud under the 'thirdParty' category.

**Why**

Any code that branches on this classification (such as feature gating or provider-specific behavior) now handles gateway setups consistently with other third-party providers instead of silently falling through unclassified.

- Area: Auth
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Marketplace load failure now reports the actual caught error

Plugin marketplace load failures now show the actual error instead of an unrelated one

**What**

When loading a plugin marketplace fails, Claude Code shows a 'Failed to load marketplaces' message. The code building that message was previously referencing the wrong variable, so it didn't actually reflect the error that occurred. It now uses the real caught exception.

**Why**

The error message shown to users (and logged) now actually describes what went wrong when a marketplace fails to load, making the failure easier to diagnose.

- Area: Plugins
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Daemon startup now validates and drops malformed environment variables

Claude Code now validates environment variables before handing them to a spawned daemon process

**What**

When Claude Code starts a background daemon process, it now checks each environment variable it is about to pass in. Entries with invalid names, values that aren't strings, or values containing NUL characters are rejected and dropped, and the dropped entries are logged. Previously the whole environment object was assigned to the daemon without this check.

**Why**

This prevents malformed environment data from being silently passed into a spawned process, which could otherwise cause the daemon to fail to start or behave unpredictably.

- Area: Daemon
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### MCP discovery skip-check now compares normalized paths

MCP discovery's skip check now normalizes file paths before comparing them

**What**

When Claude Code decides whether to skip discovery for an MCP server (a connector that gives it access to external tools or data), it now runs the candidate file paths through a normalization step before checking them against the known set, instead of comparing the raw path strings directly.

**Why**

Comparing raw strings could miss matches when the same path is written differently (for example with different slashes or casing), causing discovery to run again unnecessarily. Normalizing first makes the skip check more reliable.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### "Files changed on the user's machine" notice guards against null updatedInPlace

The 'files changed on disk' notice no longer misfires when the changed-file count is null

**What**

The message that tells Claude when files changed on disk while it was working now treats a `null` value for the count of files updated in place as "nothing to report," the same as zero or a negative number, instead of only handling zero and negative cases.

**Why**

This prevents the "files changed on the user's machine" notice from being shown or mishandled when the underlying count is missing rather than a real number.

- Area: File Sync
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Path-candidate generator now handles Emacs-style '.#' lock-file prefixes

File path resolution now recognizes Emacs-style '.#' lock-file name prefixes

**What**

When Claude Code builds alternate candidate paths for a file reference, it now also tries stripping a leading `.#` prefix from the file name, in addition to its existing dot-stripping logic. This prefix is used by Emacs to mark lock files.

**Why**

This lets Claude Code correctly resolve a file reference even when the actual file on disk is an Emacs lock-file variant of the intended name.

- Area: File Handling
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Plugin updates refuse oversized or non-regular .gcs-sha version files

Plugin updates now skip reading version files that are symlinks/special files or over 1MB

**What**

When Claude Code checks the official plugin marketplace for updates, it reads a small `.gcs-sha` file to find the plugin's new version. If that file turns out to be a symlink, a folder, or some other special file, or if it's larger than 1MB, Claude Code now refuses to read it and skips the update, showing an explicit message instead.

**Why**

This prevents a malformed or unexpected `.gcs-sha` file from being read as plain version text, avoiding a possible source of errors or unsafe file handling during plugin updates.

- Area: Plugins
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### mcpAutoDiscovered policy flag now also disables the 'Claude Test' feature availability check

The 'Claude Test' builtin feature now also respects the mcpAutoDiscovered managed-policy flag

**What**

The availability check for a builtin "Claude Test" plugin module was changed so it now also requires the managed-policy flag `mcpAutoDiscovered` to not be disabled, in addition to its previous check. This brings it in line with other MCP-related code paths that already short-circuit on the same flag.

**Why**

Organizations that disable automatic MCP discovery via managed policy will now have this feature's availability check honor that same setting consistently with other MCP-related features.

- Area: MCP
- Names: `mcpAutoDiscovered`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### tengu_init telemetry bug fix: three fields were reading from an unrelated/undefined variable

Fixed a telemetry bug where three session-start fields were pulled from the wrong variable

**What**

In the `tengu_init` telemetry event sent when a Claude Code session starts, three fields were being read from the wrong source. `lockfile_family`, `private_registry_host_class`, and `os_locked_toolchain` had been pulling their values from a variable that didn't match the one the rest of the payload used, so they weren't reflecting the same data as everything else in the event. The code now reads all three fields from the correct, consistent source.

**Why**

This is an internal telemetry fix, not a user-facing feature. It means these three fields in session-start data should now report accurate values instead of coming from an unrelated variable.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Bash exit-code error classification now parses the command's shell AST for trailing list operators

Claude Code now parses a bash command's structure to avoid misreporting exit codes as errors

**What**

When Claude Code runs a shell command, it checks the exit code to decide whether the command failed. A new helper now actually parses the structure of the bash command (its abstract syntax tree, a breakdown of how the command is built from pieces like `&&` and `;`) to handle cases where the last part of a command list ends with an operator like `&&`.

**Why**

This prevents certain commands from being wrongly flagged as failed just because of how they were chained together with `&&` or similar operators, so the error reporting you see for Bash tool calls should be more accurate.

- Area: Bash Tool
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### claude edit-hook refuses to run when spawned inside a Claude Code session

The 'claude edit-hook' command now refuses to run from inside another Claude Code session

**What**

The `claude edit-hook` command, used internally by the VS Code extension to apply a single JSON-formatted edit read from standard input, now checks the `CLAUDE_CODE_CHILD_SESSION` environment variable. If that variable is set, meaning the command was spawned by Claude Code itself rather than run directly, it logs a telemetry event and returns a refusal message instead of reading and applying the edit.

**Why**

This stops `claude edit-hook` from being triggered accidentally from within a nested Claude Code process, which could otherwise apply unintended edits.

- Area: VSCode Extension
- Names: `CLAUDE_CODE_CHILD_SESSION`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Async hook completion notices now show the correct hook event name

Async hook completion toasts now show the correct hook event name and render independently

**What**

Hooks are custom scripts Claude Code can run automatically at certain events. When an async (background) hook finishes, the toast notice ('Async hook X completed' or 'N async X hooks completed') now reads the event name from that specific notification instead of a shared value, and each notice is now keyed by its event name.

**Why**

Previously, if multiple async hooks completed around the same time, their notices could end up showing the wrong event name or interfering with each other. Now each notice displays the correct name and multiple notices can appear independently at once.

- Area: Hooks
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Lock-file detection now recognizes Emacs-style dot-hash lock files

File-edit lock detection now also recognizes Emacs-style '.#filename' lock files

**What**

Claude Code checks for lock or swap files that some editors create while a file is open, to avoid conflicting edits. It now also recognizes the Emacs lock-file naming pattern, `.#filename`, in addition to the patterns it already checked.

**Why**

This lets Claude Code detect when a file is currently open in Emacs, the same way it already detects this for other editors, and avoid conflicting with it.

- Area: File Handling
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Proxy URL check strips credentials before hostname comparison

Proxy no_proxy hostname checks now ignore any username/password embedded in the URL

**What**

When Claude Code checks a URL's hostname against your `no_proxy` (or `honorNoProxy`) settings to decide whether to bypass a proxy, it now clears any username and password from the URL first, before comparing hostnames.

**Why**

Credentials embedded in a URL (like `user:pass@host`) could otherwise interfere with matching the hostname against your no-proxy list. Stripping them first makes the comparison rely only on the actual host, so proxy bypass rules behave consistently regardless of whether a URL carries login details.

- Area: Elsewhere
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### New git helper reads non-UTF8 file paths separately when diffing/listing index state

Claude Code now handles file paths with non-UTF8 characters separately when checking git status for changes

**What**

Claude Code has a new internal helper for checking which files have changed in a git repository, using `git diff-files` and `git ls-files -s -v` under the hood. File paths that contain the Unicode replacement character (�), meaning they couldn't be read as normal UTF-8 text, are now pulled out and sent to git in their own separate request instead of being batched together with normal paths.

**Why**

File paths with unusual encodings can otherwise get garbled or mishandled when batched with normal paths, so splitting them out keeps git status checks accurate even when a repository has files with non-standard-encoded names.

- Area: Git Integration
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Teammate mailbox lock cache is now cleared alongside inbox clearing

Clearing a teammate's mailbox now also clears its cached lock state

**What**

When a teammate's mailbox (used for messages between Claude Code sessions working together) is cleared, the internal lock cache entry for that mailbox is now also cleared, both when the clear succeeds and when it fails because the mailbox file is already gone.

**Why**

This stops stale lock state from lingering after a mailbox file has been removed, which could otherwise cause confusion the next time that mailbox is accessed.

- Area: Teammates
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Windows/macOS-aware checks added to the git-write-path safety guard

Git-write safety check gains Windows and macOS-specific handling and a new path check

**What**

The internal check that reopens a file to verify it's still what git expects before writing to it now behaves differently by platform: on Windows it uses a plain file stat and open instead of the no-follow-symlink flag, and on macOS it uses a platform-specific no-follow flag. It also now checks upfront that the path being verified is actually one that git writes to, refusing with a "not a path git writes" error otherwise.

**Why**

This makes the safety check that guards against symlink tricks during git writes work correctly across Windows, macOS, and Linux, and adds a guard against running the check on paths git wouldn't be writing to in the first place.

- Area: Git Integration
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Dead toolDecisions re-initialization removed from hook ask-floor path

A leftover reset of tool decisions was removed from the hook ask-floor permission path

**Unclear.** Whether this reset was truly inert or had some subtle effect before removal is not confirmed by the evidence.

**What**

In the internal logic that handles permission decisions from hooks (scripts that can intercept and approve or block tool actions), a line that cleared out `toolDecisions` (a record of what has already been allowed or denied) was removed from the path that re-surfaces a hook's 'ask' decision.

**Why**

The finding indicates this reset was dead code that no longer had any effect, so removing it is a cleanup rather than a behavior change for users.

- Area: Permissions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Plugin autoupdate error logging bug fixed

Fixed a bug where plugin autoupdate failures logged the wrong error variable

**What**

When Claude Code's plugin autoupdate process failed, the error-handling code was logging an unrelated outer variable instead of the actual error that was caught, both in the log message and in how the error was classified. This has been fixed so the real caught error is now logged and classified correctly.

**Why**

This makes plugin autoupdate failure logs actually reflect the real error, making it possible to properly diagnose autoupdate problems instead of seeing misleading information.

- Area: Plugins
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Bug fix in a help-screen pagination loop

Fixed a bug that broke the paginated key-hint list on a help screen

**What**

A loop that builds the paginated list of key hints (the short reminders of available keyboard shortcuts) was broken: it referenced variables that were never defined and used a broken counter that didn't advance correctly. It now correctly steps through the hint list two at a time and adds each pair to the display.

**Why**

This fixes the pagination logic behind a help screen's key-hint list, so the hints display correctly instead of failing due to the undefined references and broken counter.

- Area: Elsewhere
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Bug fix: 'unpublished commits re-created' message sliced the wrong array

Fixed a bug where the 'commits re-created' message used the wrong value to build its list

**What**

When Claude Code re-creates unpublished commits on top of your current HEAD and reports the new commit-id mappings, the message was mistakenly slicing the commit count (a plain number) instead of the actual list of commits. This has been fixed to slice the commits array as intended.

**Why**

The previous bug would have caused this message to throw an error or show garbled output instead of a proper list of the re-created commit mappings.

- Area: Git Checkpoints
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New "hooks module did not load" error path

Claude Code logs a clearer "hooks module did not load" error with the specific reason when a hooks module fails to load

**What**

When a hooks module (a script that plugs custom automation into Claude Code's tool calls) fails to load, Claude Code now builds and logs an error message reading "hooks module did not load" along with the specific reason for the failure. The failure can also be passed along to a callback function so other code can react to it.

**Why**

This makes it easier to see why a hooks module failed to load instead of the failure happening silently or without a clear reason attached.

- Area: Hooks
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### MCP server removal now also clears the auth-cache entry

Removing an MCP server now also clears its cached OAuth authentication entry

**What**

Running `mcp remove` to remove an MCP (Model Context Protocol) server now also clears that server's entry from the authentication cache, via a new `removeMcpAuthCacheEntry` step, before the existing token and config cleanup runs.

**Why**

Previously a removed server's cached OAuth credentials could linger behind. Clearing the cache entry on removal avoids a stale authentication record hanging around after the server itself is gone.

- Area: MCP
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Windows path-normalization now expands ~ before checking trailing separators

Windows path normalization now expands a leading ~ before deciding whether to add a trailing separator

**What**

The helper that decides whether to add a trailing separator to a Windows file path now first expands a leading `~` (representing the home directory) by resolving it, before running its usual directory and UNC (network path) checks.

**Why**

This makes home-relative paths (like `~\Documents`) get normalized the same way as absolute paths, avoiding inconsistent handling of a common shorthand for the user's home folder.

- Area: Windows
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### ui.close hook chain now fires plugin-ask dismissal even with no handlers

Closing a plugin UI panel now also dismisses any pending 'ask' prompt for it, even with no close handlers set up

**What**

When a person (rather than an automated hook chain) closes a plugin's UI panel, and that plugin has no `ui.close` handlers registered to run, Claude Code now also calls a cleanup function that dismisses any pending 'ask' record tied to that plugin's panel, instead of just closing the panel and leaving the pending ask behind.

**Why**

This prevents a plugin's pending 'ask' prompt from being left dangling after its panel is closed, ensuring the plugin's state stays consistent even when it hasn't defined its own close-handling logic.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Marketplace-add flow: 'no marketplaces available' now shows the raw error when nothing else is available

Failed plugin marketplace additions now show just the raw error when no other marketplaces exist

**What**

When adding a plugin marketplace fails and there are no other marketplaces already available, Claude Code now shows only the raw failure message. Previously it would always append "Showing available marketplaces." even when there were none to show.

**Why**

This avoids a misleading message that referenced available marketplaces when none actually existed to show.

- Area: Plugins
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### worker_epoch parse bug fixed in RegisterWorker

Fixed a bug where the daemon read a worker's epoch number from the wrong place, producing garbage values

**Unclear.** The finding doesn't say what worker_epoch is used for downstream, so the practical impact of the garbage value is inferred only generally.

**What**

When the Claude Code daemon (a background process) registers a worker, it reads back a value called `worker_epoch` from the response. This code was pulling that value from the wrong variable, so it was parsing a value that didn't actually hold the epoch number. This has been fixed so `worker_epoch` is now read from the correct response object.

**Why**

Before this fix, `worker_epoch` would have come out as `NaN` or some other garbage value instead of the real number, since the code was reading it from the wrong place. That could confuse any logic that depends on tracking a worker's epoch correctly.

- Area: Daemon
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Team memory count display bug fix

Fixed a bug that could hide or mislabel the team memory count display

**What**

A display bug in the text that shows how many team memories exist (the "{n} team memory" or "{n} team memories" line) has been fixed. The underlying code was reading the count from the wrong variable, one left over from an outer scope rather than the value actually passed in. Because of this mix-up, the count could be reported as missing (null) even when a valid, but falsy-looking, value like zero was passed in.

**Why**

This fixes cases where the team memory count could fail to display correctly due to the wrong value being read internally. Team memory counts should now render consistently.

- Area: Teammates
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Fix: environment-tool detection (`ho`) now checks its own argument instead of an outer variable

Fixed a bug where checking for ripgrep/bwrap/socat ignored the actual tool list passed in

**What**

A helper function that checks whether tools like ripgrep, bwrap, and socat are available was reading from an outer variable instead of the list it was actually given as an argument, so the check could ignore the real input. It now correctly inspects the argument it receives.

**Why**

This fixes the detection so it reflects the actual tools being checked rather than stale or unrelated data, making environment-tool detection reliable.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### File-write byte-limit tracking now releases its lock in a finally block

File-write size-limit check now always releases its lock, even on error

**What**

The internal helper that enforces a limit on how many bytes can be written to a file now releases its lock in a `finally` block, so the release happens even if the size check throws an error or returns early.

**Why**

This prevents the lock from being left held if something goes wrong during the check, which could otherwise block further file writes.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### PowerShell tool auto-inclusion now restricted to Windows

PowerShell tool is now only auto-added to the tool list on Windows

**What**

A fallback that builds the default list of available tools used to always include a PowerShell-related tool. Now it only adds that tool when Claude Code detects it is running on Windows.

**Why**

PowerShell isn't relevant on non-Windows systems, so this keeps the default tool list from offering a tool that wouldn't apply there.

- Area: PowerShell
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Plugin hooks manifest dedup warning for hooks/hooks.json

Claude Code now warns instead of double-loading a plugin's hooks.json if it's also listed explicitly

**What**

Plugins can define hooks (scripts that run automatically at certain points, like before or after a tool runs) two ways: by placing a `hooks/hooks.json` file in the plugin, which loads automatically, or by listing a hooks file explicitly in the plugin's manifest. If a plugin's manifest explicitly points to its own `hooks/hooks.json`, Claude Code used to load that file twice. Now it detects this case and logs a message instead of loading it a second time.

**Why**

This avoids duplicate hook registration for plugin authors who explicitly list their default hooks file out of habit or clarity, so the same hook doesn't fire twice for a single event.

- Area: Plugins
- Names: `hooks/hooks.json`
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Arithmetic bug fixed in a budget-allocation loop

Fixed a bug where a per-turn budget calculation updated the wrong variables

**Unclear.** The finding doesn't say what user-facing feature or limit this budget allocation controls.

**What**

A piece of internal logic that figures out how much of a per-turn budget to allocate had a bug: after computing the amount to allocate (called `ee`, the smaller of the remaining budget `K[v] - O[v]` and a total `G`), the code was updating unrelated variables (`We[lo]` and `Wu`) instead of the running totals it was supposed to update (`O[v]` and `G`). This has been corrected so the running totals now actually reflect the computed amount.

**Why**

Because the running totals weren't being updated correctly, this budget-tracking logic could drift from the real state over time. The fix makes the allocation math track correctly against what it's actually supposed to be limiting.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Marketplace git probes (ls-remote) no longer force-disable the credential helper

Marketplace git ls-remote checks no longer force-disable the credential helper and ignore stdin

**Unclear.** The finding does not say why the credential helper was removed or what practical effect the `stdin: "ignore"` change has.

**What**

When Claude Code checks a plugin marketplace's git repository with `ls-remote` (a lightweight git command used to refresh or validate a marketplace clone without fully downloading it), it used to add `-c credential.helper=` to the command. That option told git not to use any stored credentials for the check. This has been removed, so the check no longer disables git's credential helper.

Along with this, the git call now passes `stdin: "ignore"`, meaning it does not read from standard input while running.

**Why**

Without the credential helper disabled, these marketplace probes can now use whatever git credentials are already configured on the machine, which may be needed for private or authenticated marketplace repositories that previously would have failed the check.

- Area: Plugins
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Tool wrapper object now preserves extra mcpInfo fields

Tool descriptors built from MCP info no longer drop unlisted fields

**What**

When Claude Code builds an internal tool descriptor from an MCP server's tool info (MCP is the Model Context Protocol, used to connect external tools), it now carries over all of the original fields before setting `name`, `underlyingV1ToolName`, and the other explicitly listed properties, instead of dropping any fields that weren't explicitly named.

**Why**

This prevents information attached to an MCP tool from being silently discarded when Claude Code wraps it internally, which matters if other code later expects those extra fields to be present.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### CLAUDE_CODE_REPL environment variable now preserved/restored across settings changes

CLAUDE_CODE_REPL environment variable is now preserved across settings changes

**What**

When Claude Code reconciles settings after the environment changes, it now explicitly reads the `CLAUDE_CODE_REPL` environment variable beforehand and restores it (either re-setting or unsetting it) after clearing authentication caches. Previously this step only cleared the caches without preserving this variable's value.

**Why**

This prevents `CLAUDE_CODE_REPL` from being lost or reset unintentionally when settings are reconciled, keeping REPL-related behavior consistent across such changes.

- Area: Settings
- Names: `CLAUDE_CODE_REPL`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### File index rebuild now guards against a stale cwd

File index rebuild now bails out if the working directory has changed

**What**

The helper that rebuilds Claude Code's tracked-file index now takes an explicit current working directory argument. If that directory doesn't match the one the index was last normalized against, the rebuild stops early, before doing any signature comparison or actual rebuild work.

**Why**

This guards against rebuilding the file index using a stale or mismatched working directory, which should prevent incorrect or wasted rebuild work when the working directory has changed.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Last-assistant-requestId lookup now skips API error messages

Request-ID tracking now skips failed API error messages when finding the last assistant reply

**What**

The internal helper that looks up the most recent assistant message's `requestId` now skips over messages flagged as API error messages, only considering genuine assistant replies.

**Why**

Previously a failed API call could leave behind a message that got picked up as the "last" assistant message, poisoning `requestId` tracking used elsewhere. Excluding error messages avoids that.

- Area: Messaging
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Tab key no longer navigates in a pane/search component

The Tab key no longer moves focus in a pane/search component, it just blocks the default browser action

**Unclear.** The finding does not say what, if anything, Tab does now besides preventing default, or which specific pane/search UI this affects.

**What**

In a component that handles tabs, MCP clients, and search, pressing the `Tab` key used to move focus the same way `Left`/`Right` arrow keys do. Now `Tab` only prevents its default browser behavior and no longer triggers that navigation.

**Why**

This stops `Tab` from being treated as an extra pair of arrow keys in this component, which likely avoids surprising focus jumps for anyone using `Tab` for its usual purpose nearby.

- Area: Terminal UI
- Names: `Tab`
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### claude-in-chrome tool calls now surface errors instead of silently returning undefined

claude-in-chrome tool calls now throw a clear error on failure instead of silently returning nothing

**What**

When a claude-in-chrome MCP tool call fails, the code that unwraps its response now checks for an error flag and throws a proper error containing the tool's error text (or a generic " failed" message), instead of just returning undefined.

**Why**

Previously a failed claude-in-chrome tool call could silently return nothing, making the failure hard to notice or diagnose. Now it surfaces as an explicit error with useful detail.

- Area: Claude in Chrome
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Regression fix in memoized regionKids lookup

Fixed a bug where a region-lookup cache referenced an undefined variable

**What**

A memoization map (a cache keyed by lookup results so the same computation isn't repeated) had been built using an out-of-scope variable, `W.regionKids` and `W.id`. It now correctly uses the loop variable, `te.regionKids` and `te.id`.

**Why**

The old code referenced a variable that wasn't actually in scope for that lookup, which could produce incorrect or broken results. This fix makes the cache use the correct data.

- Area: UI Components
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### The Bash tool description in the reminder-hook-pretool-block prompt lost text

The Bash tool description shown in the reminder-hook-pretool-block prompt lost some of its text

**What**

In the reminder-hook-pretool-block context (shown when a pre-tool-use hook blocks a tool call), the Bash tool's description as rendered there lost a portion of its text, including the line about using the appropriate dedicated tool instead for a better user experience.

**Why**

This means Claude sees a shorter version of the Bash tool's description specifically in this blocked-hook context, though the tool's description elsewhere is unaffected.

- Area: Bash Tool
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

## In Development

### Classifier keepalive pings for remote coordination sessions

Claude Code adds a keepalive so remote classifier calls don't time out during long coordination checks

**What**

Claude Code has a new keepalive mechanism for the 'api_call' activity classifier, a background process that periodically checks in with a remote service during coordination sessions. While a classifier call to that remote service is still in progress, Claude Code now holds a session-activity hold (called `classifier-check-hold`) open and restarts a deadline timer so the check isn't cut off early. If the hold isn't cleared before the deadline, it logs an event called `session_activity_classifier_hold_expired`.

A new environment variable, `CLAUDE_CODE_AUTO_MODE_CLASSIFIER_OVERLAP`, controls whether more than one classifier call can run at the same time within a lane (a track of concurrent work).

**Why**

This reduces the chance that a slow remote classifier call gets treated as timed-out or dropped mid-check, and gives a way to see when that still happens via the new hold-expired log event.

- Flag `tengu_ccr_classifier_keepalive_enabled`: Off in both readings (read for one account on one subscription tier against v2.1.280; this account: off, anonymous baseline: off, compiled default: off) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Sessions
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### Cloud-review polling failure now behind a remote-config gate

Handling of repeated 404s while polling a cloud /code-review session is now controlled by a gate, with clearer error messages

**What**

When a deep cloud code review (`/code-review ultra`) is polled for results and repeatedly gets a 404 (not found) response, whether that is treated as the session no longer existing, rather than just a timeout, is now controlled by a flag called `tengu_breezy_diffie`. Alongside this, Claude Code adds clearer user-facing messages distinguishing between a session that was archived or stopped remotely, a session that can't be found at all, and general advice to retry with a local review instead.

**Why**

This should make failures during cloud-based reviews easier to understand, telling the user specifically what went wrong instead of a generic timeout message, and suggesting `/code-review` run locally as a fallback.

- Flag `tengu_breezy_diffie`: Not enough to say (read for one account on one subscription tier against v2.1.280; this account: no value returned, anonymous baseline: no value returned, compiled default: on) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Code Review
- Names: `/code-review ultra`
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### New quiet-drop of certain non-interactive turn continuations ('chomp')

New internal logic can silently drop certain non-user-initiated turn continuations, gated off for now

**Unclear.** What the 'host_paused' and 'not_user_started' reasons are actually used for once the flag is on isn't stated.

**What**

A new internal function computes a reason code — either `host_paused` or `not_user_started` — for conversation turns that were triggered by something other than the user directly (for example a scheduled task, a task notification, an automatic continuation, or a system-generated turn). This logic only takes effect when the `tengu_chomp_sable` flag is on; otherwise it does nothing.

**Why**

This appears to be groundwork for quietly skipping certain automated turn continuations under specific conditions, but the behavior isn't active yet for most users since it depends on an internal flag.

- Flag `tengu_chomp_sable`: Not enough to say (read for one account on one subscription tier against v2.1.280; this account: no value returned, anonymous baseline: no value returned, compiled default: off) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Session Continuations
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### New 'tether' subsystem re-creates a thinking thread when the server drops thinking on a prefix mismatch

A new tether subsystem recreates a thinking thread when the server drops earlier thinking due to a prefix mismatch

**What**

Claude Code adds a large new set of internal functions that track, per conversation thread, whether "thinking" content (Claude's visible reasoning) was newly created versus carried over from earlier in the conversation. When the server reports a `prefix_mismatch` that invalidates thinking content Claude Code had already sent, this new logic either recreates the thread on its next request, or, if the drop happened very early after a thread was just recreated, falls back to sending the rest of the conversation without a `thread` id at all.

**Why**

This is meant to keep a conversation working smoothly when the server can no longer accept previously sent thinking content, by automatically recovering instead of leaving the conversation in a broken state.

- Flag `tengu_wondrous_acorn`: Not enough to say (read for one account on one subscription tier against v2.1.280; this account: no value returned, anonymous baseline: no value returned, compiled default: not a boolean we can read) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Session Threading
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### Auto mode now gives up and stops the turn after repeated unusable server-classifier verdicts

Auto mode now stops itself instead of looping forever when safety checks keep failing

**What**

Auto mode relies on a server-side safety classifier to approve tool calls. If that classifier repeatedly comes back with no usable verdict, Claude Code now:

- waits and retries with increasing delays, showing an "auto mode unavailable" retry status in the interface

- after a fixed number of failures in a row, denies the tool call and ends the turn instead of continuing to retry

- tells the user not to retry immediately and to send a new message instead, distinguishing whether the whole session or just a subagent was affected

**Why**

This stops auto mode from looping indefinitely when the safety check itself is unavailable, giving the user a clear message and a way forward instead of a silent hang.

- Flag `tengu_woolly_parsnip`: Not enough to say (read for one account on one subscription tier against v2.1.280; this account: no value returned, anonymous baseline: no value returned, compiled default: on) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Flag `tengu_tranquil_summit`: Not enough to say (read for one account on one subscription tier against v2.1.280; this account: no value returned, anonymous baseline: no value returned, compiled default: on) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Auto Mode
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### New "inline tool definitions" mode for late tool additions

New mode announces newly added tools with full definitions instead of just their names

**What**

When a tool is added partway through a conversation, Claude Code can now announce it to the model as a full tool definition, including its schema, instead of just its name. This "inline tool definitions" mode is only active when a beta setting is on and the tool's metadata is available, and it falls back to the older name-only announcement when needed.

**Why**

Giving the model the full definition of a newly added tool, rather than just its name, likely helps the model use late-added tools more reliably, with a safe fallback if the fuller information isn't available.

- Area: Tool Listing
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### Diskless-session mode for task output exists but is off by default

A diskless mode that skips writing task output to disk exists in the code but is off by default

**Unclear.** Nothing indicates when or how a diskless session is triggered, or who it's for.

**What**

Several internal functions that handle task output (the results a subagent or background task produces) can now check whether the current session is running in a new "diskless" mode. When it is, they skip writing to disk entirely, returning nothing or throwing "Task output is not written to disk in a diskless session" instead.

**Why**

This lays groundwork for sessions that don't persist task output to the local filesystem, though the feature isn't switched on for normal use yet.

- Area: Diskless Sessions
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### Inline mid-conversation tool changes gated behind new "inline_tools" flag

New inline_tools gate adds a layer controlling mid-conversation inline tool declarations and refusals

**Unclear.** It's unclear exactly what "inline tool declarations" look like from a user's perspective or when refusals would occur.

**What**

A new gate called `inline_tools` now works alongside the existing gate that controls mid-conversation tool changes. Together they control whether a second capability tag is added to the list of announced features, and whether tools declared inline mid-conversation are surfaced or refused. New internal state tracks tools defined inline and records refusals of them.

**Why**

This is part of the underlying machinery for letting tools be declared partway through a conversation rather than only at the start, with the ability to reject inline declarations when needed.

Gate state

Nothing has been read yet about whether `inline_tools` is switched on.

- Area: Tool Listing
- Names: `inline_tools`
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### Thinking blocks now kept across arbitrary model changes, not just upgrades

Claude Code can now keep extended-thinking content across any model switch, not just upgrades

**Unclear.** Whether this gate is enabled for any given account, including this site's, is not established by the finding.

**What**

When you switch the model Claude Code is using mid-session, the app has to decide what to do with 'extended thinking' blocks (the model's visible step-by-step reasoning) produced by the previous model. Previously this was a simple yes/no choice, and thinking blocks were only kept when the switch was an upgrade to a newer model. That setting now has three possible values:

- `all` - keep thinking blocks across any model change, upgrade or not

- `upgrade` - keep them only when switching to a newer model, the previous behaviour

- `none` - drop them

A new telemetry event, `api_keep_thinking_on_model_change`, is recorded when the `all` behaviour applies.

**Why**

This gives more flexibility around preserving a model's prior reasoning when you change models, rather than only on upgrades. It's controlled by a gate (an internal switch Anthropic uses to turn features on for some accounts), so which behaviour applies isn't something you can tell from this release alone.

- Flag `tengu_rustling_pixel`: Not enough to say (read for one account on one subscription tier against v2.1.280; this account: no value returned, anonymous baseline: no value returned, compiled default: not a boolean we can read) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Thinking Mode
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### Rich remote-control action details stay off by default

A gate controls whether remote-control approval requests include compact action details like the raw command

**What**

When you approve or respond to an action from a cloud or companion session (a Claude Code session running remotely rather than on your machine), Claude Code sends a control request back asking whether a tool can be used, or asking you to respond to a dialog. Claude Code can now attach a compact summary to that request, called `requires_action` details, including things like the tool's display name, a short description of the action, and the raw command being run, instead of forwarding only the raw request. Whether this summary is built and sent is controlled by a setting named `tengu_bridge_requires_action_details`.

**Why**

When active, this should make it easier to see at a glance what a remote session is asking permission to do, without having to parse the raw request yourself.

- Flag `tengu_bridge_requires_action_details`: Off by default, switched on for this account (read for one account on one subscription tier against v2.1.280; this account: on, anonymous baseline: on, compiled default: off) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Remote Control
- Names: `tengu_bridge_requires_action_details`
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### Inline tools gate consolidated with env-var overrides

Whether 'inline tools' are enabled is now decided by a consolidated check with environment-variable overrides

**What**

A new helper function determines whether "inline tools" are enabled, checking in this order:

- `CCR_SESSION_PROFILE` — if set, inline tools are disabled

- `CLAUDE_CODE_INLINE_TOOLS` — if set, it directly overrides the setting

- Otherwise, it falls back to a remote gate called `tengu_brisk_meadow`

**Why**

This consolidates what was presumably scattered logic into one place and gives environment variables a way to force inline tools on or off regardless of the remote rollout gate.

- Flag `tengu_brisk_meadow`: Off in both readings (read for one account on one subscription tier against v2.1.280; this account: off, anonymous baseline: off, compiled default: not a boolean we can read) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Inline Tools
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 3/5
- Present in the build but not switched on

### Remote Control help text can mention claude.ai project-initiated sessions, gated on by default

Remote Control's help text can now mention that claude.ai projects can ask Claude to work in your current directory

**What**

The description shown for `claude remote-control` (the feature that lets you control a Claude Code session from elsewhere) can now include an extra sentence: that your projects on claude.ai can also ask Claude to work in the current directory.

**Why**

This is controlled by a setting on Anthropic's servers, so whether any individual reader sees the new sentence isn't something this site can determine.

- Flag `tengu_bridge_rc_projects_hint`: Not enough to say (read for one account on one subscription tier against v2.1.280; this account: no value returned, anonymous baseline: no value returned, compiled default: on) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Remote Control
- Names: `claude remote-control`
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 3/5
- Present in the build but not switched on

### Eager tool loading gate for search-matched MCP tools

A gated code path can now make certain search-matched MCP tools load eagerly instead of staying deferred

**Unclear.** Whether the tengu_shiny_stardust gate controlling this behavior is switched on is unread and not stated by the finding.

**What**

Claude Code normally decides whether to load a tool's full details up front (eager) or defer/hide them until needed. A new branch in that decision logic makes a tool eager if it matches certain search criteria, on top of the existing rules that MCP (Model Context Protocol) tools are always loaded eagerly and tools explicitly flagged to defer stay deferred.

**Why**

Loading more relevant tools eagerly can make them available sooner without waiting for deferred loading, though whether this behavior is active depends on an internal setting that hasn't been confirmed either way.

- Flag `tengu_shiny_stardust`: Not enough to say (read for one account on one subscription tier against v2.1.280; this account: no value returned, anonymous baseline: no value returned, compiled default: off) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: MCP
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 3/5
- Present in the build but not switched on

### Remote Control first-run prompt now mentions the mobile app and claude.ai/code, gated by a remote flag

Remote Control's first-run prompt can now mention the mobile app and claude.ai/code

**What**

The explanatory text shown the first time you enable Remote Control (a feature for controlling a Claude Code session from elsewhere) can now include an extra line pointing you to the Code tab in the Claude mobile app, to claude.ai/code in a browser, or to asking Claude to work in the folder from one of your projects on claude.ai. Whether you see this longer version or a shorter fallback depends on a setting that is not yet turned on for everyone.

**Why**

This gives users more ways to discover that Remote Control-enabled sessions can also be reached from the mobile app or the web, though whether any given account sees the expanded text depends on server-side rollout.

- Flag `tengu_bridge_rc_projects_hint`: Not enough to say (read for one account on one subscription tier against v2.1.280; this account: no value returned, anonymous baseline: no value returned, compiled default: on) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Remote Control
- Names: `claude.ai/code`
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 3/5
- Present in the build but not switched on

### Policy-classification 'changed' event subscription is wired but hard-disabled

A new internal listener for skipped or refused safety checks exists in the code but is forced off and never runs

**What**

Claude Code's internals now include a wrapper (`NZn`) that would let the app listen for 'changed' events tracking policy classifications that were skipped or refused, covering categories like bio, cyber, aup (acceptable use policy), agentic, and control. But a guard function (`ILn`) that decides whether this listener is allowed to run is hardcoded to always return false. As a result, `NZn` never actually subscribes to anything: it just hands back a do-nothing cleanup function, and the underlying event stream never fires.

**Why**

This is inactive scaffolding: the plumbing for tracking skipped or refused policy checks is present in the code but is completely disabled, so it has no effect on how Claude Code behaves right now. It's worth knowing about only because it hints at monitoring capability that may be switched on in a future release.

- Area: Permissions
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 3/5
- Present in the build but not switched on

### New per-model effort override table gated by tengu_witty_wand

Model effort level can now be set per-model via a gated remote-configured table

**What**

A new function determines a model's default "effort" level (how much reasoning effort it applies) by checking, in order: an explicit override, a table of per-model values read from a remote gate called `tengu_witty_wand`, an entry in the settings file, the model catalog's built-in `default_effort`, and finally falling back to "high" if nothing else applies.

**Why**

This adds another layer of control for tuning default effort levels per model, sitting above the model catalog's built-in defaults but below any explicit override or settings-file entry.

- Area: Effort
- Names: `tengu_witty_wand`
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 3/5
- Present in the build but not switched on

### Usage-limit reset messaging reworked with a new gate and reset-scope mapping

Usage-limit reset messages now map limit types to session, weekly, or model-based reset scopes

**Unclear.** The finding does not say when the reset note is actually shown to the user or what triggers it, only how it is computed.

**What**

Claude Code now has internal logic for deciding what to tell you when a usage limit resets. A new helper matches each type of usage limit (`five_hour`, `seven_day`, `seven_day_opus`, `seven_day_sonnet`, `seven_day_overage_included`) to a reset scope: session, weekly, or model-specific. A separate function then pulls the actual note text for that scope (`note_${scope}`) from remote configuration, and normally skips showing the note if the limit hasn't actually been used, unless that behavior (`only_if_unused_reset`) is overridden.

This logic sits behind a new gate called `tengu_wise_bear_copy`, whose rollout status hasn't been read yet.

**Why**

This lets Claude Code give more precise, scope-aware explanations of when a usage limit will reset (for example, distinguishing a per-session five-hour limit from a weekly or model-specific one) rather than one generic message.

- Flag `tengu_wise_bear_copy`: Not enough to say (read for one account on one subscription tier against v2.1.280; this account: no value returned, anonymous baseline: no value returned, compiled default: not a boolean we can read) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Usage & Limits
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 2/5
- Present in the build but not switched on

### Usage-limit retry now surfaces a heartbeat system message during main-loop wait

Claude Code can now show a heartbeat message while waiting on a rate-limit retry

**Unclear.** Whether this heartbeat message is actually shown depends on the `tengu_rustling_sunset` gate, which has not been read for this account.

**What**

When a request is being retried because of a usage rate limit, Claude Code can now show a live status message while it waits. New internal logic polls pending retries on a timer and emits a system message (`api_retry`) carrying the attempt number, the maximum retries, the retry delay, and the error type (`rate_limit`), so the interface can reflect that Claude Code is still waiting rather than appearing stuck.

**Why**

This gives clearer feedback during rate-limit waits instead of leaving the session looking frozen.

- Flag `tengu_rustling_sunset`: Not enough to say (read for one account on one subscription tier against v2.1.280; this account: no value returned, anonymous baseline: no value returned, compiled default: on) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Rate Limits
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 2/5
- Present in the build but not switched on

### Remote-tools worker gains a one-shot 'reannounce' ask, gated off by default

Claude Code adds an unreleased one-shot 'reannounce' request for remote tools, off by default

**Unclear.** The finding does not say what a remote tools worker is used for or what happens once it reannounces, so the practical effect for users is unclear.

**What**

A new internal mechanism lets Claude Code send a single request, called `remote_tools_reannounce`, asking a connected worker to re-announce itself. It carries a `worker_epoch` and a `deadline_ms` value, and it is designed to fire only once per arming (a one-shot ask, not a repeating one). The path is controlled by a feature flag, so it only runs at all when that flag says to.

The flag involved, `tengu_violin_scroll`, currently returns off both for this site's account and for the general baseline, and no reading has yet been taken under this release.

**Why**

This is internal plumbing for how Claude Code coordinates with remote tool workers, not something most users will interact with directly. Since the controlling flag is off, it does not currently change behavior for users on this site.

- Flag `tengu_violin_scroll`: Off in both readings (read for one account on one subscription tier against v2.1.280; this account: off, anonymous baseline: off, compiled default: off) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Remote Tools
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 2/5
- Present in the build but not switched on

### Cloud worker reconnection logic tied to CLAUDE_CODE_WORKER_EPOCH

Cloud worker reconnect prompts now gate on the worker generation number having advanced

**Unclear.** Whether this is currently active for a given reader isn't settled: `tengu_violin_wood` read off for both this site's account and the anonymous baseline, but no reading has been taken under this release.

**What**

New helper functions decide whether Claude Code should re-announce itself to a cloud/remote worker or ask the user about reconnecting. They now check that `CLAUDE_CODE_WORKER_EPOCH` (the worker generation number) has advanced past 1, along with other session-state conditions, before prompting the user or computing how long to wait before reconnecting.

**Why**

This refines when Claude Code decides a cloud session's worker has actually restarted and needs re-registration, building on the existing worker-generation tracking, so reconnect prompts and waits are triggered more accurately.

- Flag `tengu_violin_wood`: Off in both readings (read for one account on one subscription tier against v2.1.280; this account: off, anonymous baseline: off, compiled default: off) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Cloud Sessions
- Names: `CLAUDE_CODE_WORKER_EPOCH`
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 2/5
- Present in the build but not switched on

### Write tool now accepts file_text/file_content and path as aliases

Write tool now accepts file_text, file_content, and path as aliases for content and file_path, rewriting input before plugin hooks see it

**Unclear.** Whether the tengu_noble_mountain gate controls this behavior is unread for this account, so it's not stated here.

**What**

The Write tool now coerces certain input fields before they reach plugin hooks:

- a `path` field is read as `file_path` if `file_path` is absent

- either `file_text` or `file_content` (but not both) is read as `content` if `content` is absent

- a `description` field, if present, is silently dropped

A note explaining what was coerced is attached to the result.

**Why**

This makes the Write tool more tolerant of slightly different field names, so calls using `path` or `file_text`/`file_content` instead of the exact expected field names still work rather than failing outright.

- Flag `tengu_noble_mountain`: Not enough to say (read for one account on one subscription tier against v2.1.280; this account: no value returned, anonymous baseline: no value returned, compiled default: on) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Elsewhere
- Names: `file_text`, `file_content`
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 2/5
- Present in the build but not switched on

### Hooks modules (plugin tests) early-access gate and messages

Plugin hook tests now give a specific reason when they can't run: rollout off, or disabled locally

**What**

When a plugin's hook tests can't run, Claude Code now explains why with a specific message:

- If the hooks-modules feature itself isn't turned on, it tells the user to set `CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1` to run the tests.

- If the feature is on but hooks are disabled locally (via `disableAllHooks`, `allowManagedHooksOnly`, or an organization policy), it reports that instead.

**Why**

This gives a clearer, more accurate explanation when plugin hook tests fail to run, instead of one generic message, so users know whether to flip an environment variable or check their local hook settings.

- Flag `tengu_plugin_hooks_modules`: Not enough to say (read for one account on one subscription tier against v2.1.280; this account: no value returned, anonymous baseline: no value returned, compiled default: off) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Plugins
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 2/5
- Present in the build but not switched on

## Internal Changes

### New project-directory cloud-sync coverage checker

New checker determines whether a project directory's files are actually reachable by cloud-session sync

**What**

Claude Code has a new internal module that checks whether a project directory's files are actually reachable and kept in sync by its cloud-session configuration. It walks symbolic links, checks whether paths are contained within the home directory, and checks for network shares, then classifies problems it finds as `root_linked`, `inside_home`, or `unexamined` (with reasons like too many entries, unreadable, or on a network share).

It also defines a fixed set of folder names, such as `agent-memory`, `cache`, `projects`, `mcp-discovery-cache`, `plugins`, and `cowork_plugins`, that are treated as Claude Code's own configuration tree for the purposes of this sync check.

**Why**

This helps identify cases where a project's files won't actually be captured by cloud-session sync, for example because they're symlinked outside the expected location or live on a network share, so problems can be flagged rather than silently missing data.

- Area: Cloud Sync
- Tier: Under the hood
- Useful: 3/5
- Signal: 3/5

### Permission confirm dialog gains a directoryGrantOnly mode

Permission prompts gain a directory-only grant mode alongside the existing block-outside-reads mode

**What**

The part of Claude Code that builds the rows shown in permission confirmation dialogs now supports a `directoryGrantOnly` flag and a `standingRowVetoed` state. Together these change which "accept for the rest of this session" option, if any, is offered to the user, in addition to the existing `offerBlockOutsideReads` mode that limits reads to specific paths.

**Why**

This gives Claude Code finer control over what permission options are offered in a given prompt, so a user isn't offered a session-wide grant in situations where only a directory-scoped grant makes sense.

- Area: Permissions
- Names: `directoryGrantOnly`
- Tier: Under the hood
- Useful: 3/5
- Signal: 3/5

### New bridge API: markEnvironmentOffline

Claude Code can now explicitly mark a remote bridge environment as offline

**Unclear.** The finding doesn't say when this method is called or what triggers marking an environment offline.

**What**

A new client method, `markEnvironmentOffline`, sends a request to mark a remote (bridge) environment as offline.

**Why**

This gives Claude Code a way to explicitly signal that a remote environment is no longer available, rather than relying only on implicit detection.

- Area: Remote Control
- Names: `markEnvironmentOffline`
- Tier: Under the hood
- Useful: 3/5
- Signal: 3/5

### Server thread continuation gains a 'drop and recreate' path with new telemetry

Thread continuation logic gets a new 'drop and recreate' path with added telemetry

**Unclear.** Whether the `tengu_tether_live_outcome` gate is enabled for any accounts is unknown; it has not been read.

**What**

The internal planner that decides whether to continue an existing server-side conversation thread or start a new one has a new mode: a `dropHeldStateless` input and a new plan reason, `thread_minted_drop`, that triggers dropping and recreating a thread. New telemetry fields (`dropArmed`, `dropHeldStateless`, `continuesSinceDropCreate`, `dropReportUnmatched`) are recorded on the existing `tengu_tether_live_outcome` event, and a new `tether_drop_recreate` counter fires whenever this drop-triggered recreate happens.

**Why**

This adds a new way for Claude Code to recover a conversation thread by discarding and recreating it, with telemetry to track how often that path is taken.

- Area: Session Threading
- Tier: Under the hood
- Useful: 3/5
- Signal: 3/5

### Git-sync snapshot/bundle logic adds 'hollow bases' and chained-bundle tracking, plus tamper detection reporting

Working-tree sync gains tamper detection and chained-bundle tracking for remote/background checkouts

**What**

The system that syncs a working tree (used for things like remote or background-agent checkouts) using git bundles has several additions:

- `hollowBases`, a count tracked through push/pull results

- a `chained` bundle flag, with `chainBroken`, `previousLink`, and `lastLink` handling for bundles that build on each other

- `tamperedNames` counts, surfaced when the tool checks a tree's contents and finds unexpected object data

New telemetry fields include `hollow_bases`, `tampered_names`, `sent_prerequisites`, `index_lock_throughout`, `head_moved_accepted`, and `head_moved_accepted_early`.

**Why**

This lets Claude Code detect and report when a synced working tree's contents have been unexpectedly altered, and track the health of chained bundle transfers used to keep a working tree in sync.

- Area: Git Sync
- Tier: Under the hood
- Useful: 3/5
- Signal: 3/5

### SDK/remote elicitation handling reworked around session teardown

SDK now republishes a surviving pending permission request during session teardown instead of rejecting everything

**What**

When a Claude Code SDK or remote session is shutting down while a permission or elicitation request is still pending, the handling logic was reworked. Pending requests are now tracked in a new registry (`publishedPendingActionDetails`) and can be marked as background prompts. Instead of simply rejecting every outstanding question, the teardown path now republishes one surviving pending action (preferring a `can_use_tool` request) via a new `sessionState.republishPendingAction` mechanism.

**Why**

This lets a session hand off a still-relevant pending question rather than discarding it outright during teardown, which should reduce cases where a legitimate permission prompt got silently dropped when a session ended.

- Area: SDK
- Names: `republishPendingAction`
- Tier: Under the hood
- Useful: 3/5
- Signal: 3/5

### Plugin host ops gained a streaming pull/close protocol

Plugin hooks gained a streaming pull/close protocol underlying features like process.spawn

**What**

The worker process that runs plugin hooks now supports a streaming protocol for its internal operations, in addition to the simple request/response calls it already had. This adds message types for pulling further data (`op_pull`) and closing a stream (`op_close`), along with supporting dispatch and context-building code.

**Why**

This is the underlying plumbing that makes new streaming operations, such as `process.spawn`, possible: it lets a plugin operation send back a sequence of results over time instead of just a single reply.

- Area: Plugins
- Names: `op_pull`, `op_close`
- Tier: Under the hood
- Useful: 3/5
- Signal: 3/5

### New @internal SDK control requests for host-rendered dialogs

New internal SDK requests let a host app render /status, /export, /skills, Claude in Chrome, and /sandbox with its own UI

**What**

Several new internal requests were added for applications that embed Claude Code's SDK (software development kit) and want to build their own interface instead of using the built-in terminal screens:

- `get_status` returns the same rows shown by `/status` (version, session, account, provider, model, servers, settings) as plain text.

- `export_conversation` returns the plain text that `/export` would write, plus a default filename.

- `get_skills_dialog` returns the rows shown by the `/skills` menu, including lock and state information.

- `get_chrome_dialog` and `get_chrome_browsers`/`select_chrome_browser` return Claude in Chrome's state and let a host present a browser picker.

- `get_sandbox_dialog` returns the full state of the `/sandbox` dialog.

**Why**

These let a host application replace Claude Code's built-in terminal dialogs with its own custom-styled widgets while still showing the same underlying information.

- Area: SDK
- Tier: Under the hood
- Useful: 3/5
- Signal: 3/5

### New plugin search tool description referencing SuggestPluginInstall

The plugin search tool now has instructions for when to show an install card versus relay results in text

**What**

The plugin search tool (likely called SearchPlugins) now has a full description telling Claude how to handle search results: if the results fit and the `SuggestPluginInstall` tool is available, call it to show an inline install card; otherwise, describe the relevant results in text. If nothing relevant turns up, Claude is told to move on without mentioning that it searched at all.

**Why**

This gives the model clearer, explicit guidance on how to present plugin search results, so it consistently uses the install card when appropriate instead of just describing results in prose, and doesn't clutter the conversation by announcing a fruitless search.

- Area: Plugins
- Names: `SuggestPluginInstall`
- Tier: Under the hood
- Useful: 2/5
- Signal: 3/5

### New remoteModeProvenance / remoteModePendingPress state

The remote-connection state object gained two new fields, remoteModeProvenance and remoteModePendingPress

**Unclear.** What sets or reads remoteModeProvenance and remoteModePendingPress isn't specified.

**What**

The object that tracks remote-connection state gained two new fields, `remoteModeProvenance` and `remoteModePendingPress`, both starting out as null, alongside the existing `remoteConnectionStatus` field.

**Why**

These appear to track additional context about how a remote connection mode was entered and a pending user action, though the finding doesn't specify what populates them or how they're used.

- Area: Remote Control
- Tier: Under the hood
- Useful: 2/5
- Signal: 3/5

### MCP tool calls now pass accountMemory and an offCriticalPath flag

MCP tool calls now carry account memory data and flag whether they're off the critical path

**What**

When Claude Code invokes a tool provided by an MCP (Model Context Protocol) server, the request now includes `accountMemory` data and a new `offCriticalPath` flag. The flag is set to true when the call happens under an agent context or a background agent, rather than the main foreground conversation.

**Why**

Marking calls as off the critical path lets the system distinguish tool calls that don't block the user's immediate interaction, which can inform how those calls are prioritized or handled.

- Area: MCP
- Names: `offCriticalPath`
- Tier: Under the hood
- Useful: 2/5
- Signal: 3/5

### Permission-prompt queueing gets an explicit "ask seat" wait budget

Permission prompts now use a tracked "ask seat" wait budget to manage how many can be in flight at once

**Unclear.** The finding does not say what limit the ask-seat queue enforces or how it visibly changes prompt behavior for a user.

**What**

The internal system that tracks tool-call permission prompts (asking you to approve a tool before it runs) now includes an `askSeatWaitMs` timing value and a `sentWithoutAskSeat` flag, along with a `speculation` parameter and a way to abandon that speculation. Together these point to a concurrency-limited queue, referred to as "ask seats," that governs how many permission prompts can be waiting or in flight at the same time, with the wait time now measured in telemetry.

**Why**

This suggests permission prompts are now queued and measured more deliberately when several tool calls need approval at once, rather than firing without any coordination.

- Area: Permissions
- Tier: Under the hood
- Useful: 2/5
- Signal: 3/5

### New isTransparentWrapper() hook on an agent/tool adapter interface

Tool and agent adapters gain a new isTransparentWrapper() method, currently always false

**Unclear.** The finding does not say what functionality will read this method or when it might start returning true.

**What**

The interface used for tool-or-agent adapters gained a new method, `isTransparentWrapper()`, alongside its existing `prompt()` and `mapToolResultToToolResultBlockParam()` methods. Right now it always returns `false` for every adapter.

**Why**

This lays groundwork for distinguishing adapters that just pass calls straight through from ones that add their own behavior, though no adapter currently reports itself as a transparent wrapper.

- Area: Tool Adapters
- Names: `isTransparentWrapper`
- Tier: Under the hood
- Useful: 2/5
- Signal: 3/5

### 'ui://' URI scheme constant introduced

A new 'ui://' URI scheme constant appeared, likely for MCP UI resources

**Unclear.** What the 'ui://' scheme is used for and what feature it belongs to is not established by the evidence.

**What**

A constant that previously held the version string "0.4.10" now holds the string "ui://", alongside a new companion constant "ui/resourceUri". This suggests a new URI scheme for referencing UI-related resources in MCP (Model Context Protocol, the standard Claude Code uses to talk to external tool servers).

**Why**

The evidence does not say what feature this scheme supports, only that the constant now exists.

- Area: MCP
- Names: `ui://`
- Tier: Under the hood
- Useful: 2/5
- Signal: 3/5

### Thinking block-binding schema error regex now matches prefix_mismatch_behavior

Claude Code's schema-error detection was updated to match the renamed prefix_mismatch_behavior field

**What**

Claude Code has internal logic that recognizes a specific "Extra inputs are not permitted" schema error related to thinking blocks. The regular expression used to detect this error was updated to match `block_binding.prefix_mismatch_behavior`, replacing the older `block_binding.mismatch_behavior`, tracking a rename of that field in the thinking configuration.

**Why**

This keeps Claude Code's error handling in sync with the current field name, so it continues to correctly recognize this particular schema error instead of missing it.

- Area: Thinking Mode
- Names: `prefix_mismatch_behavior`
- Tier: Under the hood
- Useful: 2/5
- Signal: 3/5

### Future model IDs (opus-4-6, opus-4-7, opus-4-8, sonnet-4-6) added to model-recency comparison list

Model-recency list gains claude-opus-4-6, claude-sonnet-4-6, claude-opus-4-7 and claude-opus-4-8

**Unclear.** The finding does not say whether these model IDs correspond to models already released or ones expected in the future.

**What**

Claude Code keeps an ordered list of Claude model IDs that it uses internally to work out whether one model is newer than another, which is used to decide whether certain features are turned on for a given model. This list now includes four more model IDs:

- `claude-opus-4-6`

- `claude-sonnet-4-6`

- `claude-opus-4-7`

- `claude-opus-4-8`

These are added alongside the existing 4-0/4-1/4-5 model entries.

**Why**

Adding these IDs to the recency list means Claude Code can correctly compare them against other models for feature gating once they become available, without needing a separate update.

- Area: Models
- Names: `opus-4-6`, `opus-4-7`, `opus-4-8`, `sonnet-4-6`
- Tier: Under the hood
- Useful: 2/5
- Signal: 3/5

### Safety-classification model routing table gains a 'frontier_llm' entry

Safety-classification model routing gains a new 'frontier_llm' category mapped to claude-opus-5

**What**

A routing table used internally for specific risk-classification categories (previously covering `bio` and `cyber`) now includes a new `frontier_llm` entry, mapped to `claude-opus-5`. The `bio` category maps to `claude-opus-5` and `cyber` to `claude-opus-4-8`. Related sibling tables still only cover `bio` and `cyber`.

**Why**

This adds a new classification category for routing certain safety checks, alongside the existing bio and cyber risk categories.

- Area: Permissions
- Names: `frontier_llm`
- Tier: Under the hood
- Useful: 2/5
- Signal: 3/5

### Host-only native tool speculation path added but currently dead

Groundwork added for flagging certain native tools as host-only, not yet active

**Unclear.** The finding states this path is currently dead code, so it's unclear when or how it will take effect.

**What**

Tool execution now includes a branch that, for certain tools, builds a "speculation" object carrying a `honourHostAllowRules` setting, feeding into how tool approval decisions are made. A new marker (a `claude-code.hostOnlyNativeTool` symbol and a matching function) was also added to flag certain native tools as host-only, meaning they'd only run on the host machine rather than elsewhere.

**Why**

This path exists in the code but isn't yet reachable, so it has no effect on current behavior. It appears to be preparation for a future distinction between tools allowed to run only on the host versus elsewhere.

- Area: Tool Execution
- Tier: Under the hood
- Useful: 2/5
- Signal: 3/5

### New models are unpinned from launch-time forced effort by default; existing installs stay pinned

Newly launched models like claude-opus-4-7 and claude-fable-5 stay pinned to a launch effort level unless unpinned, but only on installs that predate this build

**What**

A function keeps a set of newly-launched models — `claude-opus-4-7`, `claude-opus-4-8`, `claude-fable-5`, and whatever model `ANTHROPIC_DEFAULT_FABLE_MODEL` resolves to — pinned to a fixed launch-time effort level, unless the matching setting (`unpinOpus47LaunchEffort`, `unpinOpus48LaunchEffort`, or `unpinFable5LaunchEffort`) is turned on. For a genuinely first-ever install on this build, where no `firstStartVersion` has been recorded yet, the entire pin list is skipped.

**Why**

This keeps existing installs behaving consistently with a model's launch-time effort level by default, while letting users opt out per model with the corresponding unpin setting, and avoids pinning anything for brand-new installs that have never run an earlier version.

- Area: Effort
- Names: `unpinOpus47LaunchEffort`, `unpinOpus48LaunchEffort`, `unpinFable5LaunchEffort`
- Tier: Under the hood
- Useful: 2/5
- Signal: 3/5

### New plugin file-watcher with debounce/burst/storm reload logic

Claude Code now batches plugin file changes with debounce, burst and storm limits before reloading plugins

**What**

Claude Code has a new watcher for plugin directories that groups together file changes instead of reacting to each one individually. It applies a debounce delay (waiting for changes to settle), a burst threshold, and a storm threshold before triggering a plugin reload, and it rescans directories with a circuit breaker that can defer reloads when changes come in too fast.

**Why**

This prevents plugins from being reloaded repeatedly in quick succession when many files change at once, such as during a bulk edit or a git checkout, which could otherwise slow things down or cause reload thrashing.

- Area: Plugins
- Tier: Under the hood
- Useful: 3/5
- Signal: 2/5

### Agent tool description rewritten to push more delegation

The Agent tool's guidance now actively encourages delegating tasks instead of just handling narrow lookups yourself

**What**

The instructions that tell Claude Code when to use the Agent tool, which hands a task off to a subagent (a separate instance that works on a piece of the task and reports back), were rewritten. The old guidance was narrow: search directly yourself for a single fact if you already know where it is. The new guidance actively pushes delegation, recommending the Agent tool when a task matches an available agent type, when there's independent work that can run in parallel, or when answering would mean reading across several files.

The stated reasoning is that delegating keeps just the conclusion in context rather than the full contents of the files that were read to reach it.

**Why**

This should lead Claude Code to hand off more multi-file or parallelizable work to subagents rather than doing it inline, keeping its own working context leaner.

- Area: Agent Tool
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Directory-sync git worker: chained bundle links and explicit stall reasons

Directory sync can now receive linked updates that point to an earlier bundle instead of resending the whole thing

**Unclear.** The finding does not say what user-visible problem, if any, chained bundles fix or what triggers them.

**What**

Claude Code mirrors your working directory in the background so it can compare and sync file states (directory sync, sometimes called checkout mirroring). This update teaches that internal engine to handle a new kind of update: a 'chained' generation, which arrives as a link pointing back to a previous bundle of files rather than sending the full bundle again.

Along with this, the engine now tracks two specific failure states, `git_failed` and `link_stall`, for when something goes wrong while following one of these chained links. When a chained update doesn't arrive as expected, the internal `not_received` diagnostic event now reports whether it was `chained` and whether it hit a `link_stall`. There's also a new `published: null` field recorded when a sync is in its 'armed' (ready but not yet fired) state.

**Why**

This is internal plumbing for how Claude Code keeps its directory mirror in sync, and it makes failures in the sync process easier to diagnose: instead of a generic timeout, Anthropic can now tell whether a stalled update was following a chain of linked bundles and where exactly it got stuck.

- Area: Directory Sync
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Bridge (remote-control) sessions now track and report 'project thread' status more granularly

Remote-control bridge sessions now track and persist 'project thread' status more precisely, including across restarts

**What**

When Claude Code runs in remote-control mode (a bridge lets a session be controlled from elsewhere), the internal tracking of "project thread" sessions is now more detailed:

- Telemetry sent when a bridge session finishes now records whether it was a `project_thread` session.

- Telemetry sent when a bridge session starts now records `rc_child`, `project_thread`, and `resumed_turn` details.

- When the bridge shuts down, it now separately saves 'parked' and 'live' project-thread session IDs (as `parkedProjectThreadSessionIds`), so parked ones can be remembered and restored the next time it starts up.

**Why**

This makes remote-control sessions more reliable across restarts: project-thread sessions that were parked (paused, not actively running) are no longer lost or conflated with live ones, so the bridge can correctly resume from where things left off.

- Area: Remote Control
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New bundled reference docs (prompt caching, tool-use, platform availability, etc.)

Claude Code bundles new reference docs on prompt caching, tool use, platform availability, and more

**What**

Several new compressed reference documents were added to Claude Code's bundled docs and skill assets, including:

- a new SKILL file

- a doc on live sources

- a doc on platform availability

- a doc on prompt auditing

- a doc on prompt caching

- a doc on tool-use concepts

**Why**

These are reference materials Claude Code can draw on, giving it built-in documentation to consult on these topics rather than relying only on external sources.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New transcript_row_repair telemetry/gate entry

A new transcript_row_repair telemetry identifier was added alongside existing transcript tracking entries

**Unclear.** What transcript_row_repair tracks or when it fires isn't specified.

**What**

A new identifier, `transcript_row_repair`, was added to the same tracked-names list as the existing `transcript_api_invalid_blocks` and `transcript_v2` entries.

**Why**

This adds tracking for a transcript row repair event, though the finding doesn't specify what triggers it or what the repair does.

- Area: Transcript
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New askToAnnounce device-hook request method

A new askToAnnounce method sends a device-hook request and silently ignores failures

**Unclear.** What askToAnnounce is used for and what triggers it isn't specified.

**What**

A remote-session related class gained a new method, `askToAnnounce(n, e)`, which sends a request marked with `{ deviceHook: true }` and swallows any errors that occur.

**Why**

This adds a way to ask a connected device to announce itself as part of remote-session handling, without the caller needing to handle failures, though the finding doesn't say what triggers the announcement or what it's used for.

- Area: Sessions
- Names: `askToAnnounce`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### send-message tool now threads hookCaller through to relay sends

Messages sent between Claude Code sessions now carry along which plugin or hook triggered them, with new retry/approval handling

**Unclear.** It's unclear exactly what scenarios trigger the new retry/approval-carry machinery or what user-visible effect it has.

**What**

The tool that sends messages between Claude Code sessions (over a local socket) now threads a `hookCaller` value through as `fromPlugin` when sending, so the receiving side knows which hook or plugin originated the message. The tool's call path is also now wrapped with new retry and approval-carrying machinery (`carryApproval`, `adoptReask`).

**Why**

Tagging outgoing messages with their origin helps track where inter-session messages come from, and the new retry/approval logic makes sending them more resilient to transient failures.

- Area: Messaging
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Prompt suggestions gain a runtime pause protocol subtype

End-of-turn prompt suggestions can now be paused and resumed at runtime, not just configured at startup

**What**

Claude Code adds a new internal message type, `set_prompt_suggestions_paused`, that lets the host application pause or unpause generation of end-of-turn prompt suggestions while running. This is in addition to the existing `promptSuggestions` startup option and user setting, which only applied at initialization.

**Why**

This lets a host stop generating prompt suggestions on the fly, for example when its input box isn't visible, instead of needing to decide at startup whether suggestions should ever appear.

- Area: Elsewhere
- Names: `set_prompt_suggestions_paused`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Opus renamed to Opus 5.5 as the latest-per-family model

Opus model catalog entry renamed from 'Opus 5' to 'Opus 5.5' as the latest in its family

**What**

The table Claude Code uses to track the newest model in each family, along with fast-mode and model-switching logic, now points to `claude-opus-5-5` instead of `claude-opus-5` as the latest Opus model.

**Why**

This means features that automatically pick the newest Opus model, such as fast mode or model switching, will now resolve to Opus 5.5 instead of the previous Opus model.

- Area: Models
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New terminal/failure states for a bounded operation ('refused', 'input_too_long')

A bounded operation's list of failure outcomes grew to include 'refused' and 'input_too_long'

**Unclear.** The finding doesn't identify which operation this outcome list belongs to.

**What**

An internal list of terminal outcomes for some bounded operation, previously `timeout`, `error`, and `truncated`, now also includes `refused` and `input_too_long`.

**Why**

This lets Claude Code distinguish more specifically between different kinds of failures for this operation, though which operation it applies to isn't specified.

- Area: Elsewhere
- Names: `refused`, `input_too_long`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Builtin hooks-module capability manifests expanded

Builtin plugin hook modules were granted access to more host calls, including two new environment variables

**What**

Internal manifests that declare which host functions a builtin plugin's hook module is allowed to call were expanded:

- One module's allowed calls now include `env.get`, `session.usage`, and `settings.read`.

- A separate "sec-default" security module's list of environment variables it can read grew from just `HOME` and `USERPROFILE` to also include `CLAUDE_CODE_DISABLE_ATTACHMENTS` and `CLAUDE_CODE_SIMPLE`.

**Why**

This widens what these builtin hook modules are permitted to do internally, giving them access to session usage info, settings, and a couple more environment variables relevant to attachment handling and simple/bare mode.

- Area: Plugins
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### User input pipeline gains explicit inline_pastes handling alongside pasted_content

User message processing now also carries an inline_pastes field alongside pasted_content

**Unclear.** What triggers inline_pastes versus pasted_content, and what user-visible behavior results from the chunking or truncation, are not stated in the finding.

**What**

The part of Claude Code that processes incoming user messages now reads and passes through a new `inline_pastes` field, alongside the existing `pasted_content` field. This lines up with other new logic in the code for splitting pasted text into chunks and truncating it when it's too long, referred to internally as `malformed_inline_pastes` and `inline_pastes_cut`.

**Why**

This is internal plumbing for handling text pasted into a prompt, so it isn't something you directly configure, but it points to pasted content being tracked and processed more carefully than before, with handling for cases where a paste is malformed or needs to be cut down to size.

- Area: Input Handling
- Names: `inline_pastes`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### ModelState tracks inline-tools support and repeated auto-mode-unavailable responses

Claude Code now tracks repeated 'auto mode unavailable' responses and inline-tool support per session

**Unclear.** The finding does not say what action the stop notice triggers or how many consecutive unavailable responses cause it.

**What**

Claude Code's internal per-session tracker for what a model supports (called ModelState) now keeps additional records:

- whether inline tools (tools called directly within a response, rather than as a separate step) have been refused or confirmed working, via new refused/emitted flags

- a count of consecutive responses, keyed by a `runKey` identifying a run, where Auto mode reported itself unavailable

- a stop notice that can be set when Auto mode has been unavailable repeatedly

**Why

This lets Claude Code notice when Auto mode (automatic model selection) keeps failing to respond in a row and react accordingly, such as surfacing a stop notice, instead of silently retrying forever. It also lets the app remember whether a given model has already confirmed or refused support for inline tool calls, avoiding repeated probing.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Tool-availability announcements gain by-value removal and replacement tracking

Claude Code now tracks tool replacements separately from plain additions/removals when tools change mid-session

**Unclear.** The finding does not say what triggers a "by value" removal or when `tool_hosts_correction` entries actually appear to a user.

**What**

When Claude Code updates a session about which tools are available (for example, when tools it, mid-conversation, gain or lose access), it can now recognize a case where a tool is removed "by value" rather than just by name, and it separately tracks tools that were replaced versus tools that were simply removed. This feeds into new grouped reminder text (a "the following tools were replaced" style message) and a new internal transcript entry type called `tool_hosts_correction`.

- Tool removals can now be tracked "by value", not just by name

- Replaced tools (`replacedNames`) are now tracked separately from removed tools (`removedByBlock`)

- A new transcript entry kind, `tool_hosts_correction`, records these corrections

- Reminder messages now group replaced tools into their own bucket of text

**Why**

This makes the messages Claude Code shows about tool availability more accurate when tools are swapped out for a new version rather than just dropped, so a reader reviewing a transcript or reminder text can tell replacement from outright removal instead of seeing both lumped together.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Automode/agent safety-evaluation cache is cleared when the verdict isn't 'continue', gated to first-party API usage

Safety-monitor cache for automated agents is cleared whenever the verdict isn't 'continue'

**What**

Claude Code can run agents in an automated mode where a safety monitor checks each action an agent takes. That monitor keeps a cached state (called `mintedOnContinue`) tracking that an agent was cleared to keep going. Now, whenever the monitor's decision on an action is anything other than "continue," that cached state for the agent is explicitly cleared. This applies when using Anthropic's first-party API (behind a gate referred to internally as `Ey`).

**Why**

This stops a stale "cleared to continue" state from lingering after the safety monitor has actually flagged or stopped an action, so a later check can't mistakenly rely on outdated permission.

- Area: Auto Mode
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Task tool gains an inline_pastes field

The Task tool's input can now include inline_pastes for pasted text left in place in the message

**What**

The Task tool (used to launch subagents, separate Claude instances that handle a piece of work) now accepts an `inline_pastes` field in its input: a list of pasted-text entries that stay embedded in place inside the message content, as opposed to `pasted_content`, which is text the host application has already extracted out of the message separately.

**Why**

This gives the Task tool a way to represent pasted text that should remain exactly where it was pasted within a message, alongside the existing mechanism for pasted text that's been pulled out separately.

- Area: Elsewhere
- Names: `inline_pastes`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Message queue tracks an 'urgent' lane separately in backlog reporting, and backoff can carry a resume timestamp

Message queue backlog counts now include an 'urgent' lane, and backoff can store a fixed resume time

**What**

Claude Code's internal message queue now counts messages in a separate "urgent" lane toward its total unsent-message count, alongside messages already in flight or pending. The queue's backoff mechanism (which pauses retries after a failure) can now also be given an absolute timestamp marking when to resume, rather than only a duration to wait.

**Why**

This makes backlog reporting account for urgent messages that weren't previously counted, and lets backoff pauses be scheduled to a specific resume time instead of only a relative delay.

- Area: Message Queue
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New process-role helper: daemon_child / sdk_host / repl

A new internal helper identifies whether the current process is a daemon_child, sdk_host, or repl

**Unclear.** What uses this new role information, and what changes as a result, is not stated in the finding.

**What**

Claude Code now has a helper function that determines which of three roles the current process is running as: `daemon_child`, `sdk_host`, or `repl` (or none of these, if undetermined). It works by combining other existing role-detection checks.

**Why**

This is internal plumbing that lets other parts of Claude Code branch on what kind of process they're running in. It doesn't directly change behavior a reader would notice.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Permission-mode changes from a dialog answer are now reported back to the session layer

Claude Code now tracks when a permission dialog answer itself changes the session's permission mode

**What**

When you answer a permission prompt (the dialog asking whether a tool call is allowed) in a way that also switches the session's permission mode to 'default' or 'acceptEdits', Claude Code now reports that mode change back up to the session layer through a new `noteOwnPermissionModeAnswer` callback, with a matching `noteOwnPermissionModePush` for related updates.

**Why**

This lets Claude Code correctly attribute a permission-mode switch to the dialog answer that caused it, rather than losing track of where the change came from.

- Area: Permissions
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Tool-call input validation now tracks coercion diagnostics (shapeClass/valid/resultNote)

Tool-call input auto-repair now records structured diagnostics instead of a plain pass/fail

**What**

When Claude Code auto-repairs (coerces) a tool call's raw input before checking it against the tool's expected schema, it now records structured diagnostics about that repair: a `shapeClass` describing the input's shape, whether the repaired input actually passed validation, and a `resultNote` with more detail.

**Why**

This gives more precise information about why a tool call's input needed fixing, instead of only a simple pass/fail result, which should help diagnose tool-input problems.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New remote-mode state fields: provenance and pending press

App state gains two new remote-mode fields: provenance and pending press

**Unclear.** It's unclear what `remoteModeProvenance` and `remoteModePendingPress` track or when they're set, beyond their initial null values.

**What**

Claude Code's app state, which already tracks remote-session fields like `remoteConnectionStatus`, now also initializes `remoteModeProvenance` and `remoteModePendingPress`, both starting out as `null`.

**Why**

The finding does not say what drives these fields or when they change, so it's not yet clear what behavior they support beyond being part of remote-mode state.

- Area: Remote Control
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Internal chained-update bundle verification logic

Internal logic added to verify chained self-update bundles for integrity

**What**

Two new internal functions support Claude Code's self-update mechanism: one checks whether a chain of applied updates (`downApplied`) is well-formed or missing, and the other classifies a chained update bundle as 'single', 'links', or 'invalid' (with reasons like 'absent', 'ahead', or 'untied') by comparing generation, worktree commit, checksum (sha256), and size against the current bundle.

**Why**

This is internal groundwork for validating that a sequence of chained update bundles is consistent and safe to apply, catching cases where a bundle doesn't properly link to the current one.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Dir-sync records now carry a bounded history chain with checksums

Folder sync records now keep a bounded history chain with checksums of past generations

**What**

Sync-point records for directory sync now include a `chain` field that captures a bounded list of recent generations that were sent, each with its generation number, worktree commit, sha256 checksum, size, and delivery method (`via`). This is trimmed to a cap and sits alongside the existing `fastForwardedTo` list.

**Why**

Keeping a checksummed history of recent sync generations gives folder sync a way to verify or recover state more precisely than before.

- Area: Directory Sync
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New classifier for retryable automode failure reasons

Automode now groups blocked, unavailable, and parsing-error failures as one retryable category

**Unclear.** The finding does not say what consuming code does with this classification, such as whether it actually triggers a retry.

**What**

A new internal function now classifies certain automode failure reasons as belonging to one group: `automode-blocked`, `automode-unavailable`, and `automode-parsing-error` are all treated as the same category, distinct from other outcomes like `user-rejected`, `permission-rule`, `interrupted`, and `cancelled`.

**Why**

Grouping these reasons together lets Claude Code treat them consistently, for example when deciding whether a failed automode attempt is worth retrying, rather than handling each reason as a one-off case.

- Area: Auto Mode
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Hook execution context now exposes hookOrigin and hookCaller

Hooks can now read a new hookOrigin and hookCaller from their execution context

**Unclear.** The finding does not say what values these getters actually return or how hook authors are meant to use them.

**What**

The object that hooks (scripts Claude Code runs automatically at certain points) can query for context now exposes two new pieces of information: `hookOrigin` and `hookCaller`, alongside the existing `agentContext` and `agentWorktree` values.

**Why**

This gives hook authors more information about where and by what a hook was triggered, which can help a hook behave differently depending on its origin or caller.

- Area: Hooks
- Names: `hookOrigin`, `hookCaller`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Directory-sync anchor now supports cross-directory 'held' operations

Directory sync's file-handling internals now support operations spanning two open directories at once

**Unclear.** The finding does not say what user-facing problem or scenario this two-handle model addresses.

**What**

The internal filesystem layer that directory sync uses to create, link, rename, and unlink files gained a 'hold'/'holdOutside' concept, letting operations like rename and link span two open directory handles at once (`renameOut`, `renameIn`, `linkIn`, `statIn`, `openIn`). This replaces an older model that only worked with a single handle at a time. The Linux and macOS platform backends were both updated to match.

**Why**

This is an internal restructuring of how directory sync manipulates files across directories, which the finding does not tie to any specific new user-facing capability.

- Area: Directory Sync
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Inter-agent SendMessage attribution can now include the sending plugin

Messages sent between agents can now note which plugin sent them

**What**

When one agent sends a message to another via `SendMessage`, the message headers can now include a `from-plugin` attribute naming the plugin that sent it, alongside the existing `from`, `from-session`, `hop-chain`, `from-name`, and `from-mode` attributes.

**Why**

This makes it clearer, when reviewing inter-agent messages, whether a message originated from a plugin and which one, rather than only showing the sending session or agent name.

- Area: Messaging
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### A UI nudge banner's gating switched from a model-name blacklist to session-activity checks

A UI nudge banner now decides whether to show based on session activity instead of the model name

**Unclear.** The finding does not say which banner this is or what condition now causes it to show or hide.

**What**

A function controlling a UI nudge banner used to decide whether to show it purely by checking the current model name against a blacklist (various `claude-3-*`, `opus-4-*`, `sonnet-4-*`, and `haiku-4-5` models). It now instead takes the session's loading state and transcript content as input, computing its result from whether the session is loading, the transcript's content, and another gate function, and no longer checks the model name at all.

**Why**

This makes the banner's visibility depend on what's actually happening in the current session rather than which model is selected, so the same banner logic now applies consistently regardless of model.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Urgent/jump-queue request tracking added to a session queue class

Internal session queue class now tracks urgent and jump-queue requests separately

**Unclear.** The finding does not say what these fields are used for or when they take effect.

**What**

An internal class used for managing session or worker queues gained two new tracking fields: `servedCallRequestsJumpQueue` and `urgentRequestIds` (a set of request identifiers), added alongside its existing heartbeat and upload-trim state.

**Why**

This is internal bookkeeping infrastructure with no described user-facing behavior yet; it likely supports prioritizing certain requests ahead of others in a queue.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Remote-control bridge failures now emit distinct telemetry per failure reason

Failures to start the remote-control bridge now report which specific reason caused the failure

**What**

The remote-control bridge lets Claude Code connect to a remote session. When it fails to start, Claude Code now records which of several specific reasons caused the failure before showing the error:

- `org_policy_denied` — an organization policy blocked the connection

- `bridge_disabled` — the bridge feature itself is turned off

- `version_floor` — the installed version is too old to support it

Previously, this diagnostic reporting only happened for the org-policy case.

**Why**

Recording the exact failure reason makes it possible to tell these distinct causes apart instead of lumping them together, which helps diagnose why a given connection attempt didn't work.

- Area: Remote Control
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Attach vs. create sessions get different "opening initialize honours" sets

Attaching to an existing headless session now honours a caller-supplied list instead of always getting an empty one

**Unclear.** The finding does not say what settings are in the `t1n` list or what values callers pass for `attachHonours`, so the practical effect on attach behavior isn't clear.

**What**

Claude Code can open a headless session (one run without the interactive UI) either by creating a new session or by attaching to one already running. Internally, opening a session applies a set of "opening initialize honours", settings that get applied when the session starts. Previously, attaching to a session always passed an empty set of these, so none applied. Now the code that opens a session takes an `attachHonours` parameter: a brand-new session still always uses a fixed set, but attaching now uses whatever `attachHonours` the caller supplies.

**Why**

This lets attaching to an existing session carry over initialize settings that were previously always dropped, so behavior on attach can now depend on what the caller passes rather than always starting from nothing.

- Area: Session Management
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Shell exit status mapping factored into a shared helper with a new "stopped" outcome

Shell exit-status logic reorganized into shared helpers, adding a distinct 'stopped' outcome

**What**

The logic that decides how a bash command's exit status gets reported (killed, failed, or completed, plus an optional note about the exit code) has been pulled into a shared helper function. A second helper wraps it to relabel a `killed` outcome as `stopped` for the places that use that wording instead.

**Why**

This consolidates duplicated exit-status logic into one place and gives callers that expect "stopped" terminology a consistent way to get it, rather than each handling the translation separately.

- Area: Bash Tool
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Bridge/peer and pasted-content messages now carry plugin identity and inline-paste data

Messages now carry plugin origin and pasted-content data through the internal pipeline

**What**

The internal message parser now reads and passes along two additional fields on user messages: `inline_pastes` (pasted content embedded in the message) and `from_plugin` (which plugin, if any, sent the message). The function that posts messages between sessions now includes `from_plugin` in what it sends, and the code that classifies where a message came from now labels peer messages with their plugin when known.

**Why**

This is the plumbing that lets plugin origin and pasted content follow a message through the system, supporting features like showing which plugin sent a message.

- Area: Messaging
- Names: `inline_pastes`, `from_plugin`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Git bundle staging now computes real git blob IDs (including Git LFS)

Git bundle staging now computes real git blob IDs, including for Git LFS files

**What**

When Claude Code stages files to build a bundle (used for uploading a working tree, for example to start a cloud session), it now hashes each file using git's own object-format hasher to compute its actual git blob ID, and records that ID with the staged file. For files tracked by Git LFS (Git's system for handling large files), it also computes and attaches a separate LFS blob ID.

**Why**

Computing real git blob IDs lets staged files be matched against git's own object identifiers, including for large files managed through Git LFS, which a plain content hash would not do.

- Area: Git Integration
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### SDK tool-result streaming can attach agentId/durationMs for Task-like tools

Streamed tool results for the Task tool can now include an agent ID and duration

**What**

When tool-result events are streamed through the SDK for the Task tool (used to launch subagents) and one other tool, they can now be enriched with an `agentId` (looked up via a new mapper) and a `durationMs` value pulled from the tool result, when those are present.

**Why**

This lets SDK consumers see which agent produced a streamed result and how long it took, useful for tracking subagent work as it streams in.

- Area: SDK
- Names: `agentId`, `durationMs`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### sessionRecord remote capability added

A new sessionRecord capability flag gates remote-session behavior for ccr connections

**Unclear.** What sessionRecord actually does for the user (e.g. recording session activity) is not stated, only that it gates behavior.

**What**

A new `sessionRecord` capability flag was added to the set of remote-control capabilities (`ccr`), joining existing ones like `controlChannel`, `modelCatalog`, `fanout`, `presence`, `catchupReplay`, and `bashExec`. It is checked in two places that track a remote session's origin and mode, and in the remote-transport layer's internal checks.

The capability table that governs which connection kinds get which bridge features now lists `sessionRecord` as enabled for the `ccr` connection kind, but disabled for `ssh` and `direct` connections.

**Why**

This lets Claude Code distinguish which remote-connection types support session recording, so that feature only activates over the connection kind built to support it.

- Area: Remote Control
- Names: `sessionRecord`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Prompt submission gains a cancel/rewind path

Submitting a prompt can now trigger a cancel-and-rewind path under a specific input mode

**Unclear.** It's unclear which input mode enables this path, what user action triggers the cancel/rewind, or whether this is fully wired up to a visible feature yet.

**What**

The code that handles submitting a prompt now optionally wires up two new handlers, `onSubmitCancelRewind` and `replaceDraftWithNextInput`. They only become active when a specific rewind-eligible input mode is set and no `inputModeOverride` is in effect.

**Why**

This lays groundwork for cancelling a submission and rewinding the input in certain input modes, though the finding doesn't specify which mode or what the user-facing trigger is.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Snapshot results now record whether HEAD moved mid-pass and whether the index lock held throughout

Git snapshots can now report whether HEAD moved mid-pass and whether the index lock was held throughout

**What**

Claude Code's snapshot function, used for git directory syncing, gained an `acceptMovedHead` option. If a caller opts in and the repository's HEAD moves while the snapshot is being taken, the snapshot now continues using the HEAD it first read instead of failing with a "momentary" error. The result also now reports `indexLockThroughout` (whether the index lock was held for the whole pass) and `headMovedAccepted` (whether a HEAD move was accepted).

**Why**

This makes git snapshots more resilient to HEAD changing mid-snapshot when explicitly allowed, while still reporting exactly what happened so problems can be diagnosed.

- Area: Git Sync
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Sandbox readability check gains a host-config category

Claude Code's sandbox path-readability check adds a host-config classification

**What**

The internal function that figures out why a file path is unreadable or sensitive inside the sandbox (the restricted environment Claude Code can run commands in) now takes a `hostConfig` parameter. It can return a new `rules_unreadable` result carrying host-config details, and it adds a new `host_config` classification for paths that are covered by the host configuration, alongside the existing `read_denied`, `sensitive`, and `sensitive_tracked` outcomes.

**Why**

This gives the sandbox a more precise way to explain when a path is off-limits because of host-level configuration specifically, rather than lumping it in with other reasons.

- Area: Sandbox
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Hooks pipeline gains a hard deadline (cutAt) alongside its budget

Hook execution now enforces a hard overall deadline in addition to its time budget, and per-hook timeouts can be reset

**What**

Hooks (custom scripts that run at points in Claude Code's workflow) run in a chain with a time budget. That chain now also takes a `cutAt` absolute deadline alongside the existing `budgetMs` time budget, including in its error-handling path. Additionally, a hook's individual timeout can now be re-armed (reset) via a new `rearm()` function.

**Why**

Adding a hard cutoff time, not just a duration budget, gives Claude Code a firmer guarantee that a chain of hooks will stop by a specific moment, and the ability to re-arm a timeout allows more flexible control over individual hook execution.

- Area: Hooks
- Names: `cutAt`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New API error classifications: system_role_misplaced, web_search/code-execution content rejected

API errors now distinguish a misplaced system-role message and failed web-search/code-execution decryption as their own error types

**What**

When Claude Code translates raw error responses (HTTP 400s) from the Anthropic API into its own internal error categories, it now recognizes more specific cases:

- a message with a system role placed in the wrong position is now classified as `system_role_misplaced`, separate from a generic unsupported-role error

- web-search or code-execution results that fail to decrypt are now classified separately from generic errors

**Why**

More specific error classification lets Claude Code surface clearer, more relevant explanations when one of these particular problems occurs, rather than lumping them into a generic error.

- Area: Error Handling
- Names: `system_role_misplaced`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Diff/context-usage base-stats computation gained a 'branch-point' mode that falls back to merge-base diff stats

Diff stats used for context usage can now compare against the branch's merge base

**What**

The internal calculation that produces diff statistics (used, among other things, for tracking context usage) previously only supported comparing uncommitted changes against HEAD. It now also supports a "branch-point" mode, which computes stats against the merge base of the current branch instead.

**Why**

This allows diff-based statistics to reflect everything changed since a branch diverged, not just uncommitted edits, giving a more complete picture in workflows that care about a whole branch's changes.

- Area: Context Usage
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Usage-limit wait tracking added to rate-limit store

Internal rate-limit tracking now records when a user is waiting on a usage limit

**Unclear.** The finding doesn't say what visibly changes for a user as a result of this tracking.

**What**

The internal store that tracks rate-limit and subscription state gained a new `usageLimitWaits` set and a matching change event, alongside the existing signals it already tracked for status changes, overage usage, and quota rejections. A new helper function can snapshot the current set of waits as a list.

**Why**

This is internal bookkeeping that lets other parts of Claude Code know when a usage limit wait is in progress, likely supporting more accurate status displays around usage limits.

- Area: Rate Limits
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New safeguard: forked agents must declare tool-ownership prefix when changing tools

Forked agents now throw an error if they change tools without declaring an ownPrefix

**What**

When Claude Code spawns a forked agent (a copy of an existing agent that branches off to work independently), that fork sometimes changes which tools it has access to compared to its parent. `runForkedAgent`, the internal function that starts these forks, now requires that any such change be accompanied by an `ownPrefix` value stating which tools the fork owns. If a fork changes its parent's tool set without declaring `ownPrefix`, Claude Code now throws an explicit error instead of silently continuing.

**Why**

Previously this situation was allowed to pass silently, which could let a fork's tool access diverge from its parent without anyone noticing. Failing loudly instead should make this kind of misconfiguration easier to catch and fix rather than causing subtle, hard-to-trace problems later.

- Area: Agent Tool
- Names: `ownPrefix`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New worker-to-client control request for remote tool re-announcement

New internal request lets remote-tool workers ask a client to re-announce unrecognized tool machines

**Unclear.** The finding does not say what user-visible problem this fixes or when a worker gets replaced.

**What**

A new internal control request type lets a remote-tool worker (a background process that replaces another one serving a session's tools) ask the connected client to re-announce itself when a tool call refers to a machine the worker doesn't recognize. The request is addressed by worker epoch, carries a deadline, and is rate-limited and epoch-guarded on the client side.

**Why**

This helps keep remote tool routing correct when a worker is replaced mid-session, by giving it a way to recover missing machine information instead of failing the tool call.

- Area: Remote Tools
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### serverPopulated compliance restrictions, killable by remote flag

Compliance restrictions like allow_account_plugins_sync can now be marked server-populated, overridable by a remote kill flag

**What**

Several HIPAA-related compliance restriction entries, including `allow_account_plugins_sync`, now carry a `serverPopulated` marker. A new helper only treats a restriction as server-populated when that marker is set and a remote kill flag is not serving `true`. This changes how compliance restrictions ('compliance taints') are merged when Claude Code decides whether an action is allowed.

**Why**

This gives Anthropic a remote switch to override server-populated compliance restrictions if needed, adding a layer of control over how these restrictions apply.

- Area: Compliance
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Teammate mailbox entries can now be consumed by a session.receive hook

Incoming teammate mailbox messages can now be intercepted and consumed by a session.receive hook

**What**

When a message arrives in a teammate's mailbox (used for agent-to-agent communication), Claude Code now runs each entry through the `session.receive` hook point before delivering it. If the hook marks an entry as consumed, that entry is dropped and logged instead of being shown to the agent.

**Why**

This lets a `session.receive` hook filter or intercept incoming teammate messages before the agent ever sees them, building on the hook's existing role in handling incoming messages.

- Area: Teammates
- Names: `session.receive`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New host-bridge request subtypes for SDK/CLI connections

Claude Code's connection handler gained new request types for status, exporting conversations, and dialogs for skills, Chrome, and sandbox selection

**Unclear.** The finding shows the request subtypes exist but not which SDK or CLI feature actually invokes them yet.

**What**

The internal message handler that processes requests over a connection (used by SDK and CLI integrations) now supports several new request subtypes:

- `get_status` - reports connection status

- `export_conversation` - exports the current conversation

- `get_skills_dialog` - builds a dialog for selecting skills

- `get_chrome_dialog` - builds a dialog related to Chrome

- `get_chrome_browsers` and `select_chrome_browser` - list and select available Chrome browsers

- `get_sandbox_dialog` - builds a dialog for sandbox settings

Each of these is checked against the connection before running, and the code that builds the dialogs is loaded only when needed rather than upfront.

**Why**

This expands what external tools connecting to Claude Code can ask it to do, adding the ability to check connection status, export conversations, and surface dialogs for skills, Chrome browser selection, and sandbox configuration without those tools having to build that logic themselves.

- Area: SDK
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Effort/ultracode settings resolution reworked with legacy fallback

Effort-level settings resolution reworked so a legacy top-level effort setting now properly backs ultracode mode

**What**

The internal logic that computes per-model "effort" levels (how much reasoning effort a model uses) has been rewritten. It now separates a top-level legacy effort setting from effort levels declared in the settings file, and tracks which source provides the top-level default.

- When ultracode is turned on for the whole session, the result now includes a default of `xhigh` plus a full per-model map, whereas before it returned an empty per-model map.

- The per-model effort lookup now falls back to the legacy top-level effort setting when there's no per-model default and the model matches a specific check, instead of just returning the plain default.

**Why**

This fixes cases where turning on ultracode mode wasn't properly reflected in per-model effort settings, and makes sure an older, legacy effort setting still applies correctly under the new model-matching logic.

- Area: Effort
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New debug/feedback report builder with Session/Environment/Internal sections

Claude Code can now build a Session/Environment/Internal debug report and export it as a text file

**Unclear.** It's not stated where in the product this report or export is triggered from, such as a specific command or menu.

**What**

Claude Code has a new internal report builder for debugging and feedback. It puts together a report with up to three sections:

- Session, covering account status

- Environment, covering the main model in use, MCP (Model Context Protocol, used to connect external tools and data sources) state, and the current permission mode

- Internal, with additional internal details

Empty sections are left out of the report. A companion function can export this report as a text file under a default filename, reusing the same transcript-export logic used elsewhere but with its welcome header turned off (`welcomeHeader: false`).

**Why**

This gives Claude Code a built-in way to package up the current session's state into a readable report, which is useful when reporting a problem or debugging an issue, since it captures the relevant context in one exportable file instead of requiring it to be gathered by hand.

- Area: Debugging
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New settings-preference key: attachServeRequest

New attachServeRequest setting lets a session attach to a remote serve/work link

**Unclear.** The finding does not say what a serve/work link is used for beyond attaching a session.

**What**

Claude Code adds a new settings entry, `attachServeRequest`, classified as a preference. A dedicated helper validates and extracts a `workId` and `environmentId` from an `attachServeRequest` payload, checking that they match expected ID patterns.

**Why**

This is used when a session attaches to a remote serve or work link, giving Claude Code a validated way to read which work and environment the link points to.

- Area: Settings
- Names: `attachServeRequest`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### First-party telemetry now runs as an internal plugin module

Claude Code's telemetry now runs as an internal plugin module other builtin plugins call into

**What**

Claude Code's own analytics and telemetry pipeline has been rebuilt as a plugin-style internal module named 'telemetry'. Other builtin plugins now log events and mark feature usage by calling `$.telemetry.log` and `$.telemetry.mark` rather than however this was wired in before.

The telemetry module scans a large number of environment variables, covering things like CI systems, IDEs, cloud and deployment platforms, terminal type, WSL, and GitHub Actions, to build a detailed fingerprint of the environment that gets sent with each event to Anthropic's event-logging endpoint.

**Why**

Restructuring telemetry as an internal plugin module gives other builtin plugins a consistent, shared way to log events and usage, and the richer environment fingerprint gives Anthropic more context about the environments Claude Code runs in.

- Area: Telemetry
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Checkpoint restore records now track a generation 'chain' with hashes

Checkpoint restore records can now track a generation chain of hashed entries

**Unclear.** The finding does not say what readsResultEcho does or how the chain is used during an actual restore.

**What**

A new schema describes a checkpoint 'chain': an array of entries, each with a generation number, worktree commit, sha256 hash, size, and a `via` field, validated so generation numbers strictly increase. The restore-state schema now carries an optional `chain` field, a new `chained` boolean, and a new `readsResultEcho` flag, alongside the existing `attached` and `seedless` flags.

**Why**

This lets Claude Code track and verify a sequence of checkpoint generations with hashes, giving restore operations a way to confirm the integrity and lineage of a chain of checkpoints.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Agent wake router gains stranded-resume recovery

Claude Code adds automatic recovery for agent messages stranded after a failed resume

**What**

Claude Code's internal agent wake router, which delivers messages to background or resumed agents, gains a recovery path for messages that got stuck when an agent's resume previously failed. It now subscribes to a `agentStrandedMessages` signal and retries delivering those queued messages, running a `flushStranded` check before each routing pass. If delivery still cannot succeed, it emits an `agentResumeFailed` event marked as undeliverable and/or terminal.

**Why**

This reduces the chance that a message to a sub-agent silently disappears after a failed resume, since Claude Code will now keep retrying delivery and clearly flag the cases where it ultimately gives up.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New speculative execution for the remote-tool auto-mode classifier

The remote-tool auto-mode classifier can now guess a tool call's permission ahead of time and reuse that guess if it turns out right

**Unclear.** The finding doesn't say what triggers a speculative run to start or how often predictions are expected to match.

**What**

The classifier that decides whether a remote tool call is automatically allowed can now run ahead of time, speculatively predicting the answer before the actual permission request arrives. If the real request matches the prediction, the pre-computed result is reused; if it doesn't match, the speculative work is discarded and the classifier runs normally.

New internal helper functions handle building, checking, and abandoning these speculative runs. The `tengu_remote_tool_classifier` telemetry event, which tracks this classifier's behavior, now also records `speculative_*` and `queue_*` fields, including a `speculative_discard_reason` for when a prediction doesn't pan out.

**Why**

Running the classification speculatively can let the permission decision be ready sooner when the prediction is correct, since the work happens ahead of the actual ask instead of starting after it.

- Area: Auto Mode
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### MCP tools gain an 'account memory' classification with redacted error text

MCP tools tied to memory now get an 'account memory' tag, and their error messages are redacted in logs

**What**

MCP (Model Context Protocol, the standard Claude Code uses to talk to external tool servers) tool listings now carry a new `accountMemory` flag. It is set for:

- the built-in dynamic memory server

- tools with specific names such as `memory_read` and `memory_write`

- tools from trusted SDK configs

When a tool marked this way throws an error during a tool call, Claude Code no longer logs or throws the raw error text. Instead it replaces the message with a placeholder showing only the character count.

**Why**

Memory tools can return the contents of a user's memory file in their answers, so an error message from one of them could leak that file's contents into logs. Redacting the text keeps that private content out of logs while still surfacing that an error occurred.

- Area: MCP
- Names: `accountMemory`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New 'queueTranscriptOnly' user-message kind excluded from turn continuation logic

A new queueTranscriptOnly flag on user messages is now excluded from turn-continuation logic

**Unclear.** The finding does not say what produces a queueTranscriptOnly message or what user-visible effect this exclusion has.

**What**

Claude Code now recognizes a new kind of internal user message, marked with a `queueTranscriptOnly` flag, that is also treated as an interrupted-turn-style message. This new check runs alongside the existing turn-continuation checks and affects several places in how Claude Code decides whether a turn (one exchange between you and Claude) has finished:

- the idle-check, which decides if Claude Code is currently waiting or working

- the interrupted-turn detection, which decides if a turn was cut off

- the main classifier that categorizes messages during this process

**Why**

Messages marked `queueTranscriptOnly` are now handled specially rather than being folded into the normal turn-completion logic, which should make Claude Code's sense of whether a turn is still in progress more accurate when this kind of message appears.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### CLI-facing query stream can now surface a 'rate_limit_event'

CLI query streams can now surface rate-limit events with billing fields stripped

**What**

The stream of events Claude Code produces while processing a query can now include a new message type, `rate_limit_event`. When one arrives, Claude Code parses its rate-limit information, removes two billing-related fields (`canUserPurchaseCredits` and `hasChargeableSavedPaymentMethod`), and forwards the rest into the events a caller sees. If the payload doesn't parse correctly, it logs a warning and drops it instead of forwarding it.

**Why**

This lets tools and scripts that consume Claude Code's query output react to rate-limit information directly, without receiving sensitive billing details.

- Area: SDK
- Names: `rate_limit_event`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### $.model.fork now returns structured outcome instead of a bare string

Internal model-fork helper now returns a structured result instead of plain text or null

**What**

An internal helper used for one-off background or utility calls to the model ("forking" a copy of an ongoing conversation to ask it something separately) now returns a structured result that distinguishes several outcomes: aborted, an API error (with status and error details), an empty reply, or a successful answer, plus token usage. Previously it just returned joined text or `null`.

When there is no warm main-thread conversation available to fork from, it now returns a structured object with `isAnswered: false` and `reason: 'nothing-to-fork'` instead of `null`, with an updated log message.

**Why**

This lets code calling into this helper tell apart different failure modes (aborted vs. an API error vs. an empty reply) instead of only seeing a missing result, which should make related bugs easier to diagnose.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Compliance-taint checks now separate server-fetched session state from locally hinted taints

Compliance restriction checks now only trust server-fetched taint data, not local hints, before a fetch completes

**What**

The internal check that decides whether a session is subject to compliance restrictions ("taints") was restructured so that `compliance_taints` from state is only applied when the session data actually came from a server fetch. Before that fetch completes, the check falls back to locally hinted taints only.

**Why**

This changes how restriction decisions are computed before the server has responded, avoiding decisions based on server-derived taint data that hasn't actually been confirmed by the server yet.

- Area: Compliance
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New claude.ai MCP connector 'discover verdict' cache

claude.ai MCP connectors now cache 'discover' probe results for 24 hours

**What**

When Claude Code connects to MCP (Model Context Protocol) servers through claude.ai, it now remembers, per server, whether a discovery probe already succeeded using the modern protocol version. That result is cached for 24 hours, so the same server isn't re-probed on every connection during that window. The cached verdicts are saved to a state file on disk, or, when a plugin's filesystem sandbox is active, to a virtual state store instead, and writes to this cache are serialized so they don't collide.

**Why**

Skipping repeat discovery probes for servers already known to support the modern protocol should make repeated MCP connections faster and reduce unnecessary network round-trips.

- Flag `tengu_dreamy_sundae`: Not enough to say (read for one account on one subscription tier against v2.1.280; this account: no value returned, anonymous baseline: no value returned, compiled default: on) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: MCP
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Generic 'shared control request' answering path added to the control bridge

Control bridge gains a generic 'shared control request' handling path

**What**

Before the control bridge dispatches a `control_request` to its per-type handler (for things like `initialize` or `set_model`), it now first calls a new `answerSharedControlRequest` hook with the request. If that hook returns a promise, the request is handled asynchronously through a new helper; if it returns a result right away, a `control_response` is sent immediately and the normal per-type handling is skipped entirely.

**Why**

This adds a shared entry point for answering control requests before they fall into type-specific handling, allowing certain requests to be intercepted and answered generically rather than requiring separate logic for each request type.

- Area: Remote Control
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Refusal/safeguard handling gains a policy_refusal path

Refused evaluations can now produce a distinct 'policy_refusal' block reason instead of a generic unavailable one

**What**

When Claude Code cannot get an evaluation result because it was refused, it now can produce a specific blocking result with failure mode `policy_refusal` and reason category `policy_refusal`, rather than falling through to the generic 'unavailable' handling.

**Why**

This gives refusal-caused blocks a distinct, identifiable reason instead of lumping them in with other unavailable-result cases, which should make it clearer when a refusal specifically was the cause.

- Flag `tengu_tranquil_summit`: Not enough to say (read for one account on one subscription tier against v2.1.280; this account: no value returned, anonymous baseline: no value returned, compiled default: on) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Permissions
- Names: `policy_refusal`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New skill-state, sandbox, and Claude-in-Chrome settings-write APIs

Three new internal settings-write functions handle per-skill state, sandbox mode, and Claude-in-Chrome default-enabled toggle

**Unclear.** What triggers each writer (e.g. a specific command or automatic behavior) is not stated in the finding.

**What**

Three new internal functions can now write validated settings changes to `localSettings`:

- A per-skill invocation state writer, setting a skill to on, name-only, user-invocable-only, or off, and handling identifiers like its unqualified name, aliases, and a bare-name-reserved flag

- A sandbox mode writer, setting sandboxing to auto-allow, regular, or disabled, along with `allowUnsandboxedCommands` and `excludeCommand` options

- A writer for the Claude-in-Chrome default-enabled toggle

Each of these checks the requested value with zod (a validation library) before writing, and each checks whether the setting is locked by policy, by a plugin, or by the settings' author before allowing the change.

**Why**

These give Claude Code controlled, validated ways to change skill availability, sandbox behavior, and the Claude-in-Chrome default on a user's behalf, while still respecting locks set by policy, plugins, or the settings author so those changes can't be silently overridden.

- Area: Settings
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Dir-sync gains lightweight 'link' sync alongside content sync

Directory sync between your laptop and remote worker can now share small 'link' records, not just full folder contents

**Unclear.** The finding shows the new methods and their keys but not what a 'link' record is used for beyond referencing a worktree commit.

**What**

Claude Code keeps a working directory in sync between your laptop and a remote worker machine. That sync mechanism has gained a second, lighter-weight channel alongside the existing one:

- The existing channel (`putOutbound`/`getInbound`) sends full directory content between machines.

- The new channel (`putLink`/`getLink`) sends a much smaller record, identified by a generation number and a `worktreeCommit`, rather than full file contents.

This looks like plumbing for referencing a specific commit in a git worktree across machines, rather than copying its contents wholesale.

**Why**

A smaller, commit-keyed record is cheaper to sync than full directory contents, so this likely lets Claude Code keep machines aware of each other's state without the cost of transferring everything each time.

- Area: Directory Sync
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### SDK/plugin session scope gains savedAgentMessages and requestMessages callbacks

The SDK's internal session bridge gained savedAgentMessages and requestMessages callbacks

**Unclear.** The finding does not say what consumes these new callbacks or what user-facing behavior they enable.

**What**

The internal bridge object that Claude Code's SDK and plugins use to talk to a running session (the same object that already exposed things like `canUseTool` and `toast`) now also exposes two new functions: `savedAgentMessages` and `requestMessages`. They are wired up to the session's stored data and its computed list of tools.

**Why**

This is internal plumbing rather than something most users will interact with directly. It gives SDK integrations and plugins a way to read back saved agent messages and request messages for a session, which they could not do through this bridge before.

- Area: SDK
- Names: `savedAgentMessages`, `requestMessages`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New tool-definition rejection reasons: unsupported_on_platform, kind_not_enabled, name_conflict

Claude Code now gives clearer reasons when a custom tool definition is rejected

**Unclear.** The finding doesn't say whether or how this classification is surfaced to end users versus used only internally.

**What**

When a custom tool definition (a description telling Claude about a tool it can call) is rejected, Claude Code can now classify why, based on the error it gets back:

- `unsupported_on_platform` — the current platform doesn't support tool definitions at all

- `kind_not_enabled` — that kind of tool cannot yet be defined in a message

- `name_conflict` — the tool's name collides with an existing tool or addition

**Why**

Previously these rejections likely surfaced as raw, undifferentiated errors. Sorting them into named reasons makes it possible to show a clearer explanation of why a custom tool didn't work, rather than a generic failure.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New ui.copy control action

New 'ui.copy' control action added, likely for copy-to-clipboard

**Unclear.** The finding infers this backs a copy-to-clipboard UI action but doesn't confirm what specifically triggers it.

**What**

A new client control-protocol action called `ui.copy` was added, which sends text and an optional surface identifier through the same channel used by the existing `ui.focus` action.

**Why**

This appears to back a copy-to-clipboard action in the interface, though the finding doesn't confirm exactly where it's used yet.

- Area: Plugins
- Names: `ui.copy`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New 'seat' abstraction gates concurrent remote approval requests

New 'seat' system limits how many remote approval requests can be in flight at once

**Unclear.** The finding does not say what determines seat capacity or what triggers withdrawal.

**What**

A new module introduces a 'seat' concept that must be acquired before a remote tool approval request is issued, and released afterward. It includes a wait-limit timeout, a callback that fires while waiting, and logic to record a human-readable description of what was withdrawn if a seat could not be retaken.

**Why**

This appears to gate how many remote tool approval requests can be outstanding at once, preventing an unbounded pile-up of pending approvals and giving a way to report what got displaced when capacity ran out.

- Area: Remote Tools
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### PowerShell tool gains remoteExecution capability and a sleep-blocking check tied to remote calls

PowerShell tool adds remote-execution support and blocks bare sleep/wait commands unless a remote call forbids backgrounding

**What**

The PowerShell tool now declares support for remote execution, meaning its commands can potentially be routed to run on a remote host rather than locally. It also gains a way to suppress bundling multiple permission updates together.

Separately, its input validation now blocks bare `sleep`/`wait`-style commands in an additional case: when the command is part of a remote call whose settings don't explicitly forbid running in the background.

**Why**

This extends the same remote-execution routing already used by other tools (like Grep and Search) to PowerShell, while the added sleep-blocking check helps prevent commands that would otherwise hang or block unexpectedly when run remotely.

- Area: PowerShell
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New 'created_empty' directory-sync bootstrap path threaded through the git worker

Directory sync gains a 'created_empty' startup path that seeds from an initial upload snapshot instead of reading local git state

**What**

The part of Claude Code that keeps a project directory synced (for example, to a cloud session) now handles a new case, `created_empty`, when figuring out where to start syncing from. Instead of reading the local git setup, it builds the starting point by walking through the snapshot data from the first upload's head and head-parent information. This new path shares the same (shorter) timeout as the existing `overlay` startup path.

**Why**

This gives directory sync a way to bootstrap correctly when a directory starts out empty, rather than assuming there's local git history to read from.

- Area: Directory Sync
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New pricing tier tier_4_20_cache_read_0_20

New pricing tier tier_4_20_cache_read_0_20 added, used for Opus 5.5

**What**

A new pricing tier called `tier_4_20_cache_read_0_20` was added, defining per-million-token rates of $4 for input, $20 for output, $5 for 5-minute cache writes, $8 for 1-hour cache writes, and $0.20 for cache reads. This tier is used for Opus 5.5.

**Why**

This records the pricing Claude Code uses when calculating cost for Opus 5.5 usage.

- Area: Elsewhere
- Names: `tier_4_20_cache_read_0_20`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Tool routing now checks a per-tool state machine before local/prefetch path

Tool call routing now checks for an active per-tool state machine first, before falling back to the old local/prefetch logic

**What**

The internal logic that decides how a tool call gets dispatched now first checks whether that tool has an active state machine associated with it. For non-MCP tools (tools not provided via the Model Context Protocol) that do have one, the call is routed directly through that state machine, bypassing the previous logic based on a 'supported' flag and prefetch requests.

**Why**

This changes the underlying mechanism for dispatching tool calls, letting individual tools manage their own call-handling logic via a dedicated state machine rather than going through one shared routing path.

- Area: Tool Routing
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New CLAUDE_CODE_PLUGIN_DIRS helper module: Son/OBn/nDe/Zst plus a dedicated refusal message

Claude Code adds internal handling for CLAUDE_CODE_PLUGIN_DIRS, including validation of the paths it lists and a message explaining how to unset it

**Unclear.** The finding does not say what these paths are validated or used for beyond plugin loading, or in what situation the refusal message is actually shown to a user.

**What**

A new internal helper handles the `CLAUDE_CODE_PLUGIN_DIRS` environment variable, which lists folders Claude Code loads plugins from. The helper:

- Parses the list of directories from `CLAUDE_CODE_PLUGIN_DIRS`

- Rejects entries that are absolute paths or start with `~`, printing a warning

- Removes duplicate entries

- Can subtract one set of plugin directories from another

- Comes with a ready-made message explaining how to unset `CLAUDE_CODE_PLUGIN_DIRS`

`CLAUDE_CODE_PLUGIN_DIRS` can be set directly in the environment or through the `env` block in settings. To stop Claude Code from loading plugins from those folders, unset the variable.

**Why**

This tightens up how plugin directories are validated, catching malformed entries like absolute or `~`-prefixed paths before they cause problems, and makes it easier for users to figure out how to turn the setting off if it's causing issues.

- Area: Plugins
- Names: `CLAUDE_CODE_PLUGIN_DIRS`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New git-worktree/session container origin kind: created_empty

Claude Code adds a created_empty origin kind for git worktree/session containers

**Unclear.** The finding does not say what user-facing scenario produces a created_empty origin, or what text differs between the detached and current_branch cases.

**What**

Claude Code's internal handling of where a session's container (a git worktree, the isolated working copy used for a session) comes from gains a new case called `created_empty`. When a container originates this way, Claude Code now:

- picks different explanatory text depending on whether the container's position is `detached` or `current_branch`

- records the origin as `created_empty` in its internal facts, along with whether the container was rerouted

**Why**

This lets Claude Code correctly explain and track sessions whose worktree started out empty, rather than lumping them in with other origin kinds. Readers aren't likely to notice this directly, but it should make session/worktree status messages more accurate in this specific case.

- Area: Git Worktrees
- Names: `created_empty`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New error classifiers for web-search and code-execution content rejection

New error handling recognizes rejected encrypted web-search and code-execution content and retries accordingly

**What**

Two new classifiers detect specific error messages from the API: one for web-search results whose encrypted content failed to decrypt or validate, and one for encrypted code-execution output (stdout) that failed the same way. Each is mapped to a new named outcome — `web_search_content_rejected` and `code_execution_output_rejected` — in the error-recovery system that decides how to retry after a failure.

**Why**

This lets Claude Code recognize these specific failure cases and handle them through a defined retry path instead of treating them as generic, unclassified errors.

- Area: Error Handling
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New tool_definition error classifier (yke) with live caller, feature server-gated

New error classifier detects unsupported or conflicting tool definitions and is wired into the retry path

**What**

A new function classifies error responses mentioning `tool_definition` into three cases: `unsupported_on_platform`, `kind_not_enabled`, or `name_conflict`. It is used in the retry path that decides whether to strip or downgrade a tool definition and try the request again.

**Why**

This lets Claude Code respond more precisely when a tool it tries to use isn't supported, isn't enabled, or conflicts with another tool's name, by automatically adjusting and retrying instead of just failing.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Tool-call routing gains a per-tool 'machine' path, bypassed for MCP tools

Tool calls can now be routed through a registered per-tool state machine before falling back to the old dispatch path

**What**

When Claude Code dispatches a tool call, it now first checks whether a state machine has been registered for that specific tool. If one exists, the call is routed through it instead of the older logic that handles local tools and tools passed through from a host. This new routing is explicitly skipped for MCP (Model Context Protocol, a standard way external tools connect to Claude Code) tools, which continue to use the previous path.

**Why**

This lets individual tools define their own custom handling logic for how their calls are processed, without disturbing how MCP tool calls are dispatched.

- Area: Tool Routing
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### 'hearth' channel binding schema simplified

The 'hearth' channel binding no longer returns channel/thread names, only IDs and URLs

**Unclear.** placeholder

**What

- Area: Remote Control
- Tier: Under the hood
- Useful: 1/5
- Signal: 2/5

### New session-origin categories route to host_synthetic

New internal session-origin types now explicitly map to the host_synthetic category

**Unclear.** The finding does not say what side-session-brief, side-session-start, or side-session-wake correspond to in user-visible terms, only that they route to host_synthetic.

**What**

Claude Code tracks where a session or turn originated from, and internally groups these into broader categories for reporting purposes. Several origin types have been added to the mapping that produces this grouping:

- `side-session-brief`

- `side-session-start`

- `side-session-wake`

- `other`

Each of these now explicitly maps to the `host_synthetic` category, rather than falling into it through a default catch-all case.

**Why**

This is an internal bookkeeping change. Making the mapping explicit rather than relying on a default case reduces the chance that new origin types get miscategorized in the future, but it should not change anything a user of Claude Code sees or interacts with directly.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 2/5

### tengu_kairos_ready_nudge no longer treats bare `true` as full-probability enable

The kairos ready nudge config no longer treats a bare `true` value as an automatic full-probability enable

**What**

The remote-configuration gate controlling the 'kairos ready' nudge used to have a shortcut: if the config value was simply `true`, it was treated as `{probability: 1, maxImpressions: 5, impressionKey: ""}`. That shortcut has been removed. Now a bare `true` value falls through to the normal object-shape validation, which likely results in the config being treated as invalid (returning null) instead.

**Why**

This removes a special case that let a simple boolean stand in for a full configuration object, meaning the nudge's settings now need to be specified in their proper object form to take effect.

- Flag `tengu_kairos_ready_nudge`: Not enough to say (read for one account on one subscription tier against v2.1.280; this account: no value returned, anonymous baseline: no value returned, compiled default: not a boolean we can read) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 2/5

### Tool listing cache key now accounts for a byValueListing flag and PS tool set

The tool-description cache key now also factors in a byValueListing flag and a new tool predicate

**Unclear.** What byValueListing and the new tool predicate (PS1/PS0) actually control isn't specified.

**What**

The cache key used for tool descriptions now includes two new components: a `PS1:`/`PS0:` marker reflecting a new tool predicate, and a `V${byValueListing}:` segment added when `byValueListing` is set. These join the existing `withoutToolDescribeHooks` component already used in the key.

**Why**

This ensures the cached tool descriptions are recomputed correctly when these new factors differ, rather than potentially reusing a stale cached entry that doesn't reflect them.

- Area: Tool Listing
- Tier: Under the hood
- Useful: 1/5
- Signal: 2/5

### Remote tools admission gate for 'announce' hook

Remote-controlled sessions now register a dedicated permission check before announcing themselves, once admitted

**Unclear.** The finding doesn't say what the 'announce' hook itself does, only that its permission handling changed.

**What**

When a session has been admitted for remote tools use (`remoteToolsAdmission?.admitted` is true), Claude Code now registers a dedicated permission provider for an "announce" action on its control channel. This replaces an older inline block that previously always handled cancellation for this path.

**Why**

This routes the announce step through the same permission-admission gating as other remote tool actions, rather than always running unconditionally, tightening control over what a remotely-controlled session can do.

- Area: Remote Tools
- Tier: Under the hood
- Useful: 1/5
- Signal: 2/5

### New lazy-loaded 'responsive-mode' bundle chunk

A new 'responsive-mode' code chunk is now lazy-loaded alongside the existing 'diff' chunk

**Unclear.** What functionality the 'responsive-mode' chunk provides is not stated in the evidence.

**What**

Claude Code's loader now lazily loads an additional bundle chunk named `responsive-mode`, under the same conditions as the existing `diff` chunk (when not running as a local agent entry point).

**Why**

Loading this chunk only when needed keeps the main bundle smaller for entry points that don't need it, consistent with how the `diff` chunk is already handled.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 2/5

### New always-on integrity check for the incremental transcript normalizer

New integrity check verifies cached transcript output before reusing it

**What

- Area: Transcript
- Tier: Under the hood
- Useful: 1/5
- Signal: 2/5

### SESSION_PINNED (tengu_gentle_frost) gated behind an extra environment check

One of the SESSION_PINNED feature checks now requires an extra environment condition before it queries the flag server

**What**

SESSION_PINNED is checked via two feature-flag lookups. One of them, tied to the `tengu_gentle_frost` flag, now first runs an additional environment check (`le()`) before it queries the remote feature-flag server at all, whereas previously it queried the flag unconditionally.

**Why**

This narrows when Claude Code even bothers asking the flag server about this particular `tengu_gentle_frost` variant, likely to skip the remote check in environments where it wouldn't apply anyway.

- Flag `tengu_gentle_frost`: Off in both readings (read for one account on one subscription tier against v2.1.280; this account: off, anonymous baseline: off, compiled default: not a boolean we can read) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Internals
- Tier: Under the hood
- Useful: 1/5
- Signal: 2/5

### Remote session manager tracks 'unanswered' replicas

Remote session tracking adds an 'unanswered' category for replicas that never responded

**Unclear.** leaving placeholder, fix below

**What

- Area: Sessions
- Tier: Under the hood
- Useful: 1/5
- Signal: 2/5

### New cleanup pass for an MCP-discovery verdicts cache file

A new mcp-discover-verdicts.json cache file is now cleaned up periodically

**What**

The periodic cleanup process that prunes old state files now also removes a file called `mcp-discover-verdicts.json`. This implies that MCP server discovery now caches its verdicts to disk, and this cache is subject to the same periodic cleanup as other state files.

**Why**

This prevents the discovery-verdicts cache from growing unbounded over time, keeping it tidy alongside other stored state.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 2/5

### Hardcoded 'long turn nudge' default preset removed

The long-turn nudge feature no longer accepts a simple on/off setting; it now requires a full config object

**What**

The "long turn nudge" feature, controlled by the remote gate `tengu_rc_long_turn_nudge`, previously allowed that gate to just be set to `true`, which mapped to a hardcoded default configuration (a 90-second threshold, probability 1, a maximum of 3 impressions, and a 7am-9pm active window). That shorthand has been removed; only an explicit configuration object now takes effect.

**Why**

This removes the implicit default behind a bare `true` value, meaning the nudge now requires explicit configuration to behave as before rather than falling back to hardcoded defaults.

- Flag `tengu_rc_long_turn_nudge`: Not enough to say (read for one account on one subscription tier against v2.1.280; this account: no value returned, anonymous baseline: no value returned, compiled default: not a boolean we can read) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 2/5

### Cloud/remote session serve-link signing becomes request-scoped

The link used to serve a device from Claude Code's cloud/remote sessions can now be signed per-request instead of with one plain signature

**Unclear.** The finding does not say what user-visible effect, if any, this has, or why request-scoped signing was introduced.

**What**

The internal flow that creates a serving link for a cloud or remote session (`linkForServing`) now carries along a `request` value, built from the session's own startup data, and passes it into a new step called `signRequest`. The signer behind this (previously called `Yn`, now `ns`) can then sign either the plain way or in a way that is tied to the specific request, depending on whether a request was given.

**Why**

This is an internal change to how serve links are signed, tying a signature more closely to the specific session request rather than reusing a generic signature. It has no direct setting or command for readers to use, but it affects the security plumbing behind device-serving links for cloud and remote sessions.

- Area: Sessions
- Tier: Under the hood
- Useful: 1/5
- Signal: 2/5

### New tengu_sorted_flute gate can suppress local flag-settings writes

A new internal check can now silently skip saving flag settings changes to disk

**Unclear.** Nothing has been read yet about whether tengu_sorted_flute is on or off by default, and the finding does not say what practical problem this guard is meant to solve.

**What**

Claude Code has an internal function, `apply_flag_settings`, that saves merged settings to disk and tells other parts of the app about the change. Previously it always did both of those things. Now, under a new condition, it can skip saving and notifying entirely:

- the settings being applied are unchanged from what's already stored

- the new `tengu_sorted_flute` gate (an internal switch Anthropic can turn on or off remotely) is on

- a guard function supplied by the calling code returns false

When all three are true, the write and notification are suppressed.

**Why**

This looks like a guard against unnecessary disk writes when nothing has actually changed, letting a caller opt out of a redundant save-and-notify cycle. If you notice a settings change not taking effect or not triggering an update you expected, this new skip path is a place to look.

- Flag `tengu_sorted_flute`: Not enough to say (read for one account on one subscription tier against v2.1.280; this account: no value returned, anonymous baseline: no value returned, compiled default: off) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Settings
- Tier: Under the hood
- Useful: 1/5
- Signal: 2/5

### Sandbox/swarm permission check helper added (pendingSandbox)

Added an internal helper to check whether a sandboxed permission request is still pending

**Unclear.** What calls this helper and what visible effect it has isn't specified.

**What**

Claude Code adds a helper function that checks whether a given id is listed in `swarmPermissions.pendingSandbox`, meaning a sandboxed (isolated-environment) permission request for that id is still waiting to be resolved.

**Why**

This supports Claude Code's internal handling of sandbox permission requests; the finding doesn't describe a directly visible change in behavior.

- Area: Sandbox
- Tier: Under the hood
- Useful: 1/5
- Signal: 2/5

### New model-config field 'auto_permission_mode: unavailable' has no found reader

Several models, including Haiku 4.5, now carry a new auto_permission_mode field set to unavailable

**Unclear.** What auto_permission_mode is meant to control, or whether anything currently reads it, is not established.

**What**

Several entries in the models manifest, including Haiku 4.5, now include a new field, `auto_permission_mode: "unavailable"`, alongside existing fields such as `quick_select`.

**Why**

No code was found anywhere in the app that actually reads this field, so it isn't clear what effect, if any, it has for someone using Claude Code right now.

- Area: Elsewhere
- Names: `auto_permission_mode`
- Tier: Under the hood
- Useful: 1/5
- Signal: 2/5

### Swarm inbox messages get a provenance/pass-through check before delivery

Swarm inbox messages now go through a provenance check before delivery, not just a text filter

**What

- Area: Swarm
- Tier: Under the hood
- Useful: 1/5
- Signal: 2/5

### New gated check `tengu_validated_clover`

A new internal check called tengu_validated_clover appeared in Claude Code's code, but what it does isn't known yet

**Unclear.** What `tengu_validated_clover` actually controls, and whether it is enabled for any accounts, is not known.

**What**

A new helper function called `yco` was added that checks a gate named `tengu_validated_clover`. A companion helper, `Xf`, runs a reader callback wrapped in error handling and only reports success if that callback returns a specific value. It is not yet known what feature or behavior this gate controls.

**Why**

This looks like groundwork for a feature that is not yet active for most users. There is nothing for a reader to do differently yet, since what the gate turns on has not been determined.

- Area: Internals
- Names: `tengu_validated_clover`
- Tier: Under the hood
- Useful: 1/5
- Signal: 2/5

### New model-capability gate tied to opus_5_5_prompt_bundle

A new capability gate tied to the opus_5_5_prompt_bundle flag can unlock certain model features, and a tool_pear beta header now depends on a flag not yet read for this account

**What**

A set of model capability checks (including `silent_turn_reminder` and `quizzical_shore`) now also returns true when a new condition is met: the `opus_5_5_prompt_bundle` remote-config flag is on and a separate internal condition is false. Separately, a beta header is now added to requests when the model isn't `claude-opus-4-1` and the `tengu_tool_pear` flag is on, alongside other first-party capability betas.

**Why**

This lets certain model capabilities be unlocked via the `opus_5_5_prompt_bundle` remote flag, and adds a conditional API beta header tied to `tengu_tool_pear` for applicable models.

- Flag `tengu_tool_pear`: Off in both readings (read for one account on one subscription tier against v2.1.280; this account: off, anonymous baseline: off, compiled default: off) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Models
- Names: `opus_5_5_prompt_bundle`
- Tier: Under the hood
- Useful: 1/5
- Signal: 2/5

### Two new feature-gate constants added, one hardcoded off

Two new internal feature gates appeared: tengu_unified_waterfall and tengu_violin_speculative_classifier, the latter currently stubbed to always return false

**Unclear.** What tengu_unified_waterfall and tengu_violin_speculative_classifier actually enable is not stated, and neither gate's on/off state for this release is known.

**What**

Two new internal switches (called feature gates, they let Claude Code turn a feature on or off remotely without shipping new code) have shown up:

- `tengu_unified_waterfall` controls a function referred to internally as `mir()`, and is read together with an environment variable, `CLAUDE_CODE_REMOTE_TOOLS_ASK_SEATS`, which defaults to true if the gate doesn't say otherwise.

- `tengu_violin_speculative_classifier` controls a second function, `gir()`, but right now `gir()` is hardcoded to always return false, so whatever this gate is meant to turn on is not actually reachable yet.

**Why**

Both appear to be groundwork for features that aren't active for users yet. The second one in particular is a common pattern for shipping code ahead of time ("dark launching"): the gate and its plumbing exist, but the actual behavior is switched off in code regardless of what the gate says, so there's nothing for users to notice or configure yet.

- Flag `tengu_unified_waterfall`: Not enough to say (read for one account on one subscription tier against v2.1.280; this account: no value returned, anonymous baseline: no value returned, compiled default: on) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Flag `tengu_violin_speculative_classifier`: Gate removed from the code (read for one account on one subscription tier against v2.1.280; this account: on, anonymous baseline: on, compiled default: not a boolean we can read) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Internals
- Tier: Under the hood
- Useful: 1/5
- Signal: 2/5

### Plugin-directory sources exempted from a blocklist check under a gate

Plugin-directory sources can now skip the usual blocklist check under a gated condition

**Unclear.** The finding does not say what the gating condition w() checks or which accounts it applies to.

**What**

When Claude Code checks whether a plugin source is blocked, sources of type `pluginDirectory` can now bypass that blocklist check entirely, if a certain internal condition is met. Previously, every plugin source went through the same blocklist matching logic.

**Why**

This changes how plugin directories are vetted before use, letting them skip a check that other plugin sources still go through. The practical effect for a given account depends on server-side conditions not visible from the client.

- Area: Plugins
- Tier: Under the hood
- Useful: 1/5
- Signal: 2/5

### New gated flag 'tengu_iridescent_pascal' controls skill/tool permission-context resets

New gated flag tengu_iridescent_pascal can skip redundant permission-context resets

**Unclear.** Nothing has been read about the tengu_iridescent_pascal gate, so whether it is active for readers is unknown.

**What**

A new internal helper resets certain permission settings (the `alwaysAllowRules.command` list and a `pollEventDeliveryGuard` marker) on the tool-permission context. Behind a new flag called `tengu_iridescent_pascal`, this reset can now be skipped and the existing context reused when nothing actually needs to change. When a caller explicitly opts out of the reset, it can instead set the poll-event-delivery guard directly.

**Why**

Skipping unnecessary resets avoids rebuilding the permission context on every call. Nothing has been read yet about how this flag is currently set for this site's account, so its effect for readers isn't yet known.

- Flag `tengu_iridescent_pascal`: Not enough to say (read for one account on one subscription tier against v2.1.280; this account: no value returned, anonymous baseline: no value returned, compiled default: off) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Permissions
- Names: `tengu_iridescent_pascal`
- Tier: Under the hood
- Useful: 1/5
- Signal: 2/5

### New autoModeClassified field on tool-use records

Tool-use records gain a new autoModeClassified field, currently unset

**Unclear.** Since the field is only initialized and not yet set to a meaningful value, what it will be used for is not established by the evidence.

**What**

Internal tool-use records now carry a new `autoModeClassified` field alongside the existing `toolUseId`. It's currently initialized to an empty value, suggesting groundwork for tracking whether a tool call has been classified for an auto mode.

**Why**

The field isn't populated yet, so this is internal bookkeeping with no visible effect for now.

- Area: Auto Mode
- Tier: Under the hood
- Useful: 1/5
- Signal: 2/5

### Remote Control 'projects hint' feature split off its own flag

Remote Control's 'projects hint' feature moves to its own dedicated flag

**What**

A Remote Control feature (letting a phone or other device control a Claude Code session remotely) that shows a "projects hint" was previously gated by the flag `tengu_cuddly_willow`. It now checks a separate, dedicated flag, `tengu_bridge_rc_projects_hint`. The original `tengu_cuddly_willow` flag is now reused by a new helper that adds a check for whether flags have finished loading ("settled") before evaluating.

**Why**

Splitting the projects-hint feature onto its own flag lets it be turned on or off independently of whatever else `tengu_cuddly_willow` now controls.

- Flag `tengu_bridge_rc_projects_hint`: Not enough to say (read for one account on one subscription tier against v2.1.280; this account: no value returned, anonymous baseline: no value returned, compiled default: on) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Flag `tengu_cuddly_willow`: On for this account, and not off by default (read for one account on one subscription tier against v2.1.280; this account: on, anonymous baseline: on, compiled default: on) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Remote Control
- Names: `tengu_bridge_rc_projects_hint`
- Tier: Under the hood
- Useful: 1/5
- Signal: 2/5

### New prompt bundle for Opus 5.5

Opus 5.5 gets its own dedicated system prompt bundle

**What**

A new prompt bundle named `opus_5_5_prompt_bundle` has been added alongside the existing `opus_5_prompt_bundle` and `fable_5_1_prompt_bundle` entries, giving the Opus 5.5 model its own tailored system prompt bundle rather than sharing one with other models.

**Why**

This lets Claude Code customize prompt behavior specifically for Opus 5.5 rather than reusing the general Opus 5 bundle.

- Area: Models
- Names: `opus_5_5_prompt_bundle`
- Tier: Under the hood
- Useful: 1/5
- Signal: 2/5

### Telemetry event ccr_flag_settings_floor defined with no emitter found

A new telemetry event name, ccr_flag_settings_floor, was added but nothing in the app currently fires it

**Unclear.** What `ccr_flag_settings_floor` will eventually track is not stated, since no emitting code exists yet.

**What**

A new telemetry event identifier, `ccr_flag_settings_floor`, was added to Claude Code's master list of allowed telemetry events. No code that actually sends this event was found anywhere in the app.

**Why**

This looks like groundwork for a feature or check that isn't wired up yet, so it currently has no observable effect for users.

- Area: Telemetry
- Names: `ccr_flag_settings_floor`
- Tier: Under the hood
- Useful: 1/5
- Signal: 2/5

### Elicitation watchdog abort gated by tengu_misty_twilight

New helper can abort leftover elicitation watchdogs, controlled by the tengu_misty_twilight flag

**Unclear.** Other readings show `tengu_misty_twilight` returned on for this site's account and for the anonymous baseline, but no reading has been taken under this release, so whether it is active in this version is unknown.

**What**

When the set of tracked watchdogs for elicitation calls (requests where an MCP server asks the user for input) becomes empty, a new helper can abort all of them at once. This behavior is controlled by the `tengu_misty_twilight` flag.

**Why**

This is meant to clean up leftover elicitation watchdogs once there's nothing left to track, avoiding them lingering unnecessarily.

- Flag `tengu_misty_twilight`: On for this account, and not off by default (read for one account on one subscription tier against v2.1.280; this account: on, anonymous baseline: on, compiled default: on) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: MCP
- Names: `tengu_misty_twilight`
- Tier: Under the hood
- Useful: 1/5
- Signal: 2/5

### New hooks-modules gate condition via BJ()

A new internal check can force 'managed hooks only' mode even without the matching policy setting

**Unclear.** What condition BJ() actually represents and what practical effect it has beyond the existing allowManagedHooksOnly policy is not stated.

**What**

Claude Code's check for whether to restrict hooks (small scripts that run automatically at certain points) to only the ones an organization manages now also returns true based on a new internal condition, `BJ()`, in addition to the existing `allowManagedHooksOnly` policy setting. `BJ()` looks at whether any hooks currently exist.

**Why**

This adds another path that can trigger managed-hooks-only mode beyond the explicit organization policy setting, though the finding does not say what user-facing behavior results.

- Area: Hooks
- Names: `allowManagedHooksOnly`
- Tier: Under the hood
- Useful: 1/5
- Signal: 2/5

### Two stub functions unconditionally return false, right next to real session-gating logic

Two new always-false stub functions appeared next to Claude Code's session-detection logic, purpose unclear

**Unclear.** It's unclear what these two functions do or control, since no caller could be traced in this part of the code.

**What**

The part of Claude Code that starts up the command-line tool now includes two small new functions that always return `false`, sitting right beside the existing logic that detects things like whether a session is non-interactive or running in remote mode. Because their names overlap with other heavily-reused shorthand names elsewhere in the code, it wasn't possible to trace where or whether anything actually calls them yet.

**Why**

With no confirmed caller, it's not clear what behavior these functions are meant to gate or disable. They may be early scaffolding for a future check that isn't wired up yet.

- Area: CLI
- Tier: Under the hood
- Useful: 1/5
- Signal: 2/5

### Dead branches in the tool-transcript renderer: hardcoded `!1` disables new denial-rewrite logic

New logic for tracking tool-denial-and-rewrite pairs in the transcript view was added but left disabled by hardcoded constants

**What**

Code was added to the part of Claude Code that renders individual tool calls in the transcript, meant to track cases where a denied tool use is paired with a rewrite. However, the controlling expressions are written so they always evaluate to false or to a no-op, and the data structures they feed are always seeded empty. As a result, this new machinery cannot currently see or act on any data.

**Why**

Nothing changes for users in this build: the feature exists in the code but is effectively switched off by the way its conditions are written, so it has no visible effect yet.

- Area: Transcript
- Tier: Under the hood
- Useful: 1/5
- Signal: 2/5

### Hoverable list rows gain a 'tint' vs 'pointer' hover style option

List rows can now highlight on hover with a background tint instead of just a pointer cursor

**What**

Selectable rows in lists, along with attachment and scroll-indicator components, now accept a `hoverStyle` setting that chooses between two hover behaviors: "tint", which changes the row's background color on hover, and the existing default "pointer", which just changes the cursor.

**Why**

This gives Claude Code's interface components a clearer visual cue for which row is under the pointer in places where a background highlight is more useful than a plain cursor change.

- Area: UI Components
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Composer/search input can now take raw key events and paste directly

The search/filter input used in pickers can now receive raw key presses and pasted text directly

**What**

The search/filter input component, used for example in plugin and session picker screens, now accepts `onKeyDown`, `onPaste`, and `ref` props. Previously it only worked as a simple controlled text field; it can now behave more like a full text composer that receives individual key presses and pasted content directly.

**Why**

This lets pickers that use this input support richer interactions, such as custom key handling or pasting text directly into a filter box, instead of being limited to simple typed text.

- Area: UI Components
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### register_repo_root gains structured SDK telemetry and error codes

register_repo_root, which adds a working directory, now logs detailed telemetry and error codes

**What**

The `register_repo_root` tool, used to add a working directory to a session, now tracks which reload options were requested (`reload_claude_md`, `reload_skills`, `reload_plugins`) and sends a new, more specific telemetry event when it runs, including a distinct error code on failure instead of a generic one.

**Why**

This makes it easier to diagnose exactly what went wrong when registering a new repo root fails, and what reload behavior was requested at the time.

- Area: Elsewhere
- Names: `register_repo_root`
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Internal bash/shell process-tracking class reworked

Claude Code's internal tracking for background shell processes was rebuilt with a new data structure

**Unclear.** The finding shows a data-structure change but not what effect, if any, it has on user-visible behavior.

**What**

An internal class that keeps track of background shell (bash) commands was reworked. It previously used two sets called `pendingKillBackstops` and `liveShellCommands` to track running processes; it now uses a `reportedDroppedEntries` set, a `pendingPrunes` map, and a `ledger` object instead.

**Why**

This is an internal change to how Claude Code manages background shell processes, not a user-facing feature. The finding does not say what problem the new structure fixes or what a user might notice differently.

- Area: Bash Tool
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Loop/babysit list view now virtual-scrolls with keyboard focus tracking

The active loops/babysit list now scrolls a bounded window of items instead of rendering every loop at once

**What**

The list view showing active loops (recurring background tasks) now uses a component that tracks a visible count, a default focus index, and focus changes, instead of simply rendering every loop as a row. This implies the list now scrolls through a limited visible window of entries with keyboard focus tracking, rather than showing the full list at once.

**Why**

This should keep the loops panel usable and responsive even when there are many active loops, rather than rendering an ever-growing list.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Artifacts tool gains a 'validation error remedy' hook

Artifacts tool can now suggest a specific remedy for validation errors

**What**

The artifacts tool now exposes a `validationErrorRemedy` function that returns a `.remedy` field alongside its existing validation error message. The related steer-override logic (which can redirect Claude's response after an error) now looks up this same remedy information, falling back to a different message source if none is found.

**Why**

Providing a specific remedy alongside a validation error should make it easier to correct artifact validation problems, rather than just being told something went wrong.

- Area: Artifacts
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Beta-header selection refactored into declarative rule tables

Beta-feature header selection was rewritten from if-chains into declarative rule tables

**What**

The internal functions that decide which Anthropic API beta headers to send (covering things like interleaved thinking, per-turn timing, and context management) were rewritten. Instead of long if-chains, they now use two arrays of `{beta, when}` rules, one for the main request path and one for per-turn timing.

**Why**

This is an internal restructuring; the behavior for each existing rule appears to be preserved, so it shouldn't change what you see, but it makes the header logic easier to maintain going forward.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### SDK client_composed field description greatly expanded to document skipped attachment behavior

SDK docs now spell out exactly what client-composed turns skip: file mentions, slash commands, MCP mentions, and attachments

**What**

The SDK's `client_composed` field marks a turn as assembled by the client application rather than typed by a user. Its description was expanded from a brief internal note into a detailed explanation of what such turns skip:

- `@path` file-mention expansion (turning a typed file path into its contents)

- slash-command dispatch

- `@server:resource` MCP mention expansion (pulling in a resource from an MCP server)

- the whole turn-start attachment pass, including nested `CLAUDE.md`/rules files, skill and tool listings, and reminders

The pass that runs between tool calls is unaffected by this setting.

**Why**

This tells developers building on the SDK exactly what processing a client-composed turn bypasses, so they know they must handle file mentions, commands, and MCP references themselves if they want that behavior for turns they compose directly.

- Area: SDK
- Names: `client_composed`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Fast mode's default model resolution changed in prompt and code

Fast mode's system-prompt wording and its default-model fallback in code both changed

**What**

The system prompt's sentence about fast mode (toggled with `/fast`) dropped the qualifier that it's "available on Opus 5/4.8," now simply saying it can be toggled with `/fast`. Separately, the code that picks a default model for the fast-mode picker no longer hardcodes `claude-opus-5`; it now calls a function to determine the current model instead.

**Why**

Together these mean fast mode's model selection is no longer pinned to a fixed model name in either the prompt text or the underlying default-model logic.

- Area: Models
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New SDK MCP dial telemetry counters

New telemetry counters track how often SDK MCP servers are dialed in a session

**What**

Two new counters, `sdk_mcp_dial_runs` and `sdk_mcp_servers_dialed`, have been added to session telemetry, alongside the existing `plugin_full_loads` and `user_context_builds` counters. A tracker method increments these whenever SDK MCP servers (MCP servers connected through the SDK) are dialed.

**Why**

This gives visibility into how often and how many SDK MCP servers get connected during a session, useful for diagnosing SDK MCP usage and performance.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Model fallback event now carries a human-readable original model name

Model-fallback events now include the original model's human-readable name, not just its ID

**What**

When Claude Code falls back from one model to another, the event it logs now includes an `originalModelName` field with the human-readable name of the model that was switched away from, in addition to the existing `originalModel` ID field.

**Why**

This makes logs of model fallback events easier to read, since they now show a recognizable name rather than only an internal model ID.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Stop/error parsing now distinguishes a 'stopped' reason

Internal error parsing now separately flags when a run was stopped

**Unclear.** The finding doesn't say what consumes the new `stopped` field or how it changes visible behavior.

**What**

A helper that extracts error information from JSON responses used to return just the error text. It now also checks a 'reason' field in the response and returns whether the run was specifically stopped, alongside the error.

**Why**

This lets Claude Code's internal handling distinguish a run that was deliberately stopped from other kinds of failures, which can affect how the situation is reported or recovered from.

- Area: Error Handling
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New thinkingMode/thinkingDisplay telemetry fields

Claude Code's internal telemetry now records thinkingMode and thinkingDisplay for each event

**Unclear.** The finding does not say what the allowed values are or which thinking modes/displays they correspond to.

**What**

An internal data schema that Claude Code uses to record usage events gained two new fields: `thinkingMode` and `thinkingDisplay`. Both are text fields limited to a fixed set of allowed values, and both default to an empty string when not set.

**Why**

This is internal telemetry rather than a user-facing feature, so it does not change how Claude Code behaves. It means the tool can now track which thinking mode and display setting were active during a session.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Truncation length for some text field is now dynamic rather than a fixed constant

The cutoff length used when truncating long text fields is now computed dynamically instead of fixed

**Unclear.** What determines the dynamic truncation length, and which text field(s) it applies to, isn't specified.

**What**

A helper function that shortens long strings now determines the maximum length by calling another function (`lV()`) at the time it runs, rather than always using the same fixed number.

**Why**

This lets the truncation limit vary depending on context instead of being locked to one constant, though the finding doesn't specify what the limit now depends on.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Plugin marketplace removal now tracks shared data dir plugin ids

Removing a plugin marketplace now also reports which removed plugins shared a data directory

**What**

When a plugin marketplace is removed, the cleanup result now also lists which of the removed plugins had a shared data directory (`sharedDataDirPluginIds`), in addition to the orphaned file paths and removed plugin ids it already reported.

**Why**

This gives more detail about the cleanup, specifically flagging plugins that shared storage with others, which matters for deciding what data is safe to delete versus what other plugins might still depend on.

- Area: Plugins
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Git store-staleness check now also compares objects stamp

Git store freshness checks now also compare an objects timestamp, not just info/pack/alternates

**What**

The check Claude Code uses to decide whether a cached git store is still fresh now also compares the `objects` timestamp between the current state and the stored stamps, in addition to the existing `info`, `pack`, `alternates`, and `httpAlternates` comparisons it already made.

**Why**

This makes the staleness check more thorough, catching cases where the underlying git objects changed even if the other tracked components didn't, so a stale cache is less likely to be used.

- Area: Git Integration
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New telemetry event: plugin_function_hooks_pane_ask

New telemetry events added for plugin hooks pane, MCP resource reads, and artifact live edits; one old event removed

**What**

Several telemetry event/gate identifiers changed:

- `plugin_function_hooks_pane_ask` is a new event fired when a plugin function-hooks pane's 'asked' persistence state changes, either recorded successfully or failed with reason `not_persisted`.

- `mcp_read_resource` is a new identifier added alongside existing MCP-related entries like `mcp_reconnect` and `mcp_oauth_revoke`.

- `artifact_live_edit_reissue` is a new event added alongside existing artifact events `artifact_live_push` and `artifact_live_subscribe`.

- `repl_clear_view` was removed from the telemetry allowlist, and a related `replCount` field was dropped from a usage-aggregation object.

**Why**

These changes track new behaviors (plugin hook panes, MCP resource reads, artifact live-edit reissues) while retiring telemetry for a REPL clear-view action that's no longer tracked.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact boot/probe reuse within a single tool use

Claude Code reuses a recent share-status check instead of re-fetching an artifact within the same tool call

**What**

When Claude Code reads an artifact (a file-like object it can boot up and inspect), the internal boot function now accepts a `probeToolUseId`. For plain status-probe reads, it checks a cache of recent probe results keyed by the artifact's slug (short identifier); if the same tool call already probed that artifact recently and the cached version isn't stale, it reuses that result instead of fetching again.

**Why**

This avoids redundant network fetches when the same artifact is checked more than once within a single tool call, making artifact reads faster and less wasteful.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Remote session response posting gets an optional post-listener with timing

Remote session responses can now trigger a post-send listener that reports timing, without affecting delivery

**What**

`RemoteSessionManager.sendResponse`, which sends control responses for remote sessions, now accepts an optional callback that runs after the response is sent, passing it the response and how many milliseconds it took. If that callback throws an error, the error is caught and logged, but it does not affect whether the response was actually delivered.

**Why**

This lets other parts of Claude Code observe timing on remote session responses without risking breaking the response delivery itself if that observation code has a bug.

- Area: SDK
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Tether decision telemetry gains dropHeldStateless field

Tether decision telemetry now also records whether held state was dropped

**What**

The `tengu_tether_decision` telemetry event, part of the internal system ("tether") that decides whether to continue an existing conversation thread rather than start a new one, now also reports a `dropHeldStateless` field alongside the existing `modelHeldStateless`, `relayHeldStateless`, and `classifierHeldStateless` fields.

**Why**

This gives more detail for analyzing tether decisions, letting Claude Code track cases where held stateless data was dropped rather than carried forward.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Local UDS messages can now be tagged as sent from a plugin

Local messages between sessions can now be tagged as originating from a plugin

**What**

The internal function used to send local/remote-control messages now accepts a `fromPlugin` option, which stamps outgoing messages with a `from_plugin` field.

**Why**

This lets Claude Code track which messages sent between sessions originated from a plugin, which other changes in this release rely on to pass that origin information along.

- Area: Messaging
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Process-spawn telemetry gains stdout/stderr chunk validation

Process-spawn telemetry now validates the shape of each stdout/stderr chunk it records

**What**

The telemetry for the `process.spawn` event, which records when Claude Code launches a subprocess, now checks that each output chunk it captures has a valid shape: a `stream` field that is either `stdout` or `stderr`, and a `text` field that is a non-empty string. If a chunk doesn't match, an error label is surfaced instead.

**Why**

This catches malformed process output data at the telemetry layer, helping ensure spawn-related telemetry stays reliable rather than silently recording broken entries.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### MCP listing-prior-rejected telemetry gains a priorSource field

MCP telemetry for rejected cached listings now records where the cached data came from

**Unclear.** Whether the `tengu_mcp_listing_prior_rejected` gate is enabled for any accounts is unknown; it has not been read.

**What**

The `tengu_mcp_listing_prior_rejected` telemetry event, which fires when a server rejects a connection built from a cached list of MCP tools/servers, now also records a `priorSource` field alongside the existing `priorKind` and `reason` fields.

**Why**

This gives more detail about where the stale cached data came from when a connection built from it gets rejected, which can help diagnose why a cached MCP listing went bad.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New telemetry event for usage-limit wait heartbeats

New telemetry event tracks heartbeats while a session waits out a usage limit

**What**

Claude Code added a new event, `usage_limit_wait_heartbeat`, to its list of known telemetry states. It fires periodically while a session is waiting for a usage limit to lift.

**Why**

This gives visibility into how long and how often sessions spend waiting on usage limits, which was not previously tracked as its own recurring event.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Unanswered control-request handlers tracked across shutdown

SDK control connection now tracks handlers for still-pending requests across a shutdown

**What**

The SDK's control-protocol connection now keeps a new map, `unansweredSettleHandlers`, alongside its existing tracking of in-flight requests. It's used on the path that hands off a `control_response` for requests that are still pending when the process shuts down, passing them to the next process.

**Why**

This helps ensure that requests still awaiting a response don't lose their response handler when a process shuts down and control passes to the next one.

- Area: SDK
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Addon search-hint text can now be a lazy function

Addon search-hint text can now be generated by a function instead of only a fixed string

**What**

When building an addon's description and search hint, Claude Code now accepts `searchHint` as either a plain string, as before, or a function that returns one, which is evaluated each time it's needed.

**Why**

This allows an addon's search hint text to be computed dynamically instead of being fixed at definition time.

- Area: Plugins
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New telemetry field for account-memory line rendering

New telemetry field tracks whether an account-level memory line was included when building memory prompts

**What**

Internal telemetry events for extracting memories (`tengu_extract_memories_extraction`) and for the automatic memory-consolidation process ("auto-dream") now include a new field, `account_memory_line_rendered`, a true/false value recording whether a line of account-level memory was included when Claude Code built the prompt for that operation.

**Why**

This is an internal tracking change with no direct effect on how Claude Code behaves; it helps track how account-level memory is used when building these prompts.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Bridge (headless) session start gains structured telemetry

Headless bridge sessions now emit structured start and thread-requeue telemetry

**What**

Starting a headless "bridge" session now emits a `tengu_bridge_started` telemetry event that records `max_sessions`, `sandbox`, `spawn_mode`, `heartbeat_interval_ms`, and `headless` details. Separately, when project-thread sessions are requeued at startup, a new `tengu_bridge_project_thread_requeue` event records counts of how many were requested, requeued, dropped, deferred, and left unattempted.

**Why**

This is internal telemetry that gives more visibility into how headless bridge sessions start up and how project threads are restored, without changing what a user sees directly.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New skip-file patterns for dir-sync-empty temp/marker files

File sync now also ignores new '.dir-sync-empty.json' marker files used for empty directories

**What**

The directory-sync scanner, which decides which files to sync for a session, now also ignores files ending in `.dir-sync-empty.json` and files containing `.dir-sync-empty.json.tmp.`, in addition to the existing `.dir-sync.json` patterns it already skipped.

**Why**

This suggests a new kind of marker file used to represent empty folders during syncing; excluding it keeps these internal marker files from being treated as regular synced content.

- Area: Directory Sync
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New telemetry outcome 'model_default_server_sync'

New telemetry reason code 'model_default_server_sync' added to model-selection tracking

**Unclear.** The finding doesn't say what triggers this specific reason code or what user-facing situation it corresponds to.

**What**

A new value, `model_default_server_sync`, was added to an internal list of model-related telemetry reason codes, alongside existing entries like `model_catalog_primary` and `model_env_default`.

**Why**

This is an internal telemetry addition, likely marking cases where the default model is set via a sync from the server; it doesn't change visible behavior.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New telemetry fields projectsSession and remoteControlLane

Two new telemetry fields, projectsSession and remoteControlLane, added to a tracking allowlist

**What**

Two new keys, `projectsSession` and `remoteControlLane`, were added to an internal telemetry property allowlist, alongside existing fields like `outcome`, `platform`, `projectsRole`, and `provider`.

**Why**

This is an internal telemetry change with no direct user-facing effect; it likely supports tracking related to Projects and Remote Control features.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### thinkingModeChanged / thinkingDisplayChanged added to request-diff tracking

Request-diff tracking now also detects changes to thinking mode and thinking display

**What**

The internal mechanism that tracks what changed between successive requests sent to the model now also tracks `thinkingModeChanged` and `thinkingDisplayChanged`, alongside existing tracked changes like `overageChanged`, `effortChanged`, and `extraBodyChanged`.

**Why**

This lets Claude Code detect and presumably respond to changes in extended thinking mode or how thinking is displayed between requests, similar to how it already tracks other configuration changes.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Git-worktree session sync writes an 'empty session' marker

Claude Code now marks a synced git-worktree session as empty when it was created but never received any writes

**Unclear.** The finding does not say what the warning looks like to the user or exactly when the empty check is triggered.

**What**

Claude Code syncs session data across git worktrees (separate working copies of the same repository checked out at once). When a session's sync record is created but ends up with no writes to it, Claude Code now writes a small marker file recording that the session is empty.

When something later attaches to that session directory, it can check this marker and be warned that the session is empty, rather than treating it as a normal session with no indication anything is off.

**Why**

This prevents confusion when reopening a session tied to a git worktree that never actually received any data: instead of looking like a normal, silently empty session, it can now be flagged as such.

- Area: Git Worktrees
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Shell command-line tail parsing now tracks whether a segment was reached via &&

Claude Code now tracks whether a shell command segment was reached via && when parsing compound command lines

**Unclear.** The finding does not say what feature or permission check consumes this new andGated flag, so the practical effect on user-visible behavior is unclear.

**What**

When Claude Code looks at a compound shell command (one with multiple parts joined by things like `&&`, `;`, `|`, or newlines) to figure out the last meaningful segment, it now also records whether that segment was reached specifically through an `&&` chain, as opposed to being separated by `;`, `|`, or a newline. Previously this internal check only returned the segment text itself.

**Why**

This is an internal parsing detail rather than something a user directly configures, but it means Claude Code's handling of command lines (for example, when deciding how to treat or permission-check a command) can now distinguish `&&`-chained commands from other kinds of separators.

- Area: Bash Tool
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Prompt-cache diff tracking now covers thinking-mode and thinking-display changes

Claude Code now tracks thinking-mode and thinking-display changes when deciding whether to reuse the prompt cache

**What**

Claude Code keeps an internal record of what changed between requests (things like the model, the system prompt, and the reasoning effort) to decide whether it can reuse the cached prompt or needs to send a fresh one, and to help with diagnostics. This record now also tracks two more fields:

- `thinkingModeChanged`, whether extended thinking mode was turned on or off

- `thinkingDisplayChanged`, whether the display of that thinking changed

Both fields record the previous and new values, matching how the existing fields already work.

**Why**

Switching thinking mode on or off, or changing how thinking is displayed, can affect what should be cached. Tracking these changes explicitly lets Claude Code handle the prompt cache correctly around those switches instead of missing them.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New 'safety_monitor_blocked' failure reason maps to an API error

Claude Code now reports a blocked-by-safety-monitor response as an API error, like the existing DLP-denial case

**What**

Claude Code's internal error classifier decides which tool or request failures should be treated as a hard failure and shown as an API error. It previously did this only for `dlp_request_denied` (a request blocked by data-loss-prevention rules). It now does the same for a new case, `safety_monitor_blocked`.

`safety_monitor_blocked` means a server-side safety monitor blocked the model's response for that turn. This is a new kind of API error, added alongside existing ones like `claude_code_version_too_old`. It is terminal for that turn: Claude Code will not try to resend the same prompt that caused it.

**Why**

This gives a specific, recognizable error instead of a generic failure when a response gets blocked by a safety check, and it stops Claude Code from retrying a prompt that will just be blocked again.

- Area: Error Handling
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Git worktree config detection now distinguishes 'file' vs 'extension' vs 'absent' states

Git worktree config detection now reports 'file', 'extension', or 'absent' instead of the old three states

**Unclear.** The finding does not say what different behavior each of the three states now triggers.

**What**

Claude Code checks how a git repository's worktree configuration is set up, since this affects how it handles multiple working copies of a repo. The internal check now reports one of three outcomes: `file` (a real `config.worktree` file exists), `extension` (git reports the worktree extension is turned on but no backing file exists), or `absent` (neither is set).

**Why**

This is an internal reclassification of an existing check, giving Claude Code a more precise read on how a repo's worktree setup is configured, which can affect how it interacts with git worktrees.

- Area: Git Worktrees
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Hooks dispatch payload gains a cutAt field

Hook event payloads sent to Claude Code hooks now include a cutAt field

**Unclear.** What the cutAt field represents or is used for is not stated in the finding.

**What**

When Claude Code dispatches an event to a hook (a user-configured script that runs at specific points, such as before a tool call), the payload it builds now includes a `cutAt` field alongside the existing id, event, payload, environments, and other fields.

**Why**

The finding doesn't say what `cutAt` represents or how hooks can use it, but it means hook payloads now carry this additional piece of data.

- Area: Hooks
- Names: `cutAt`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Design tool auth error now tagged with a structured error kind

The Design tool's missing-access error now carries a structured error tag for auth_missing_scope

**What**

When a claude.ai credential lacks access to Claude Design, Claude Code raises a `DesignNeedsScopesError`. That error now also carries a structured tag, `{kind: "auth_missing_scope", provider: "claude_design"}`, in addition to its existing name.

**Why**

This is internal bookkeeping: it lets Claude Code (and its telemetry) classify this specific kind of authentication failure consistently, rather than relying only on the error's name. It should not change what a reader sees when this error occurs.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Dynamic help text for the design page-check tool

The Design tool's page-check help text now says 'before', 'after', or 'before or after' publishing depending on which checks are enabled

**What**

The instructions describing when to use the page-verification tool for Claude Design now adapt to which checks are turned on. Depending on configuration, the text says to check a page:

- before or after publishing it (if both preview and verify checks are enabled)

- before publishing it (if only the preview check is enabled)

- after publishing it (if only the verify check is enabled)

**Why**

This keeps the guidance shown to Claude accurate to the actual configuration instead of always suggesting both timings, which should lead to more relevant use of the page-check tool.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New telemetry: spilled_bytes on tool output events

Tool output telemetry now reports spilled_bytes, the size of the truncated portion

**What**

When a tool's result is too large and gets "spilled" (truncated, with the rest only retrievable by re-running the tool), the telemetry for that event now records `spilled_bytes`: the size of the part that was cut off. This is reported alongside the existing flags that mark output as truncated.

**Why**

This gives better visibility into how much output is being dropped from large tool results, which is useful for diagnosing when important information may have been truncated away.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New telemetry: boot_reused on artifact file list event

Artifact file list telemetry now records boot_reused, whether the session's boot artifact was reused

**What**

The `artifact_file_list` telemetry event now includes a `boot_reused` true/false field, indicating whether the underlying boot or session artifact was reused from an existing one rather than freshly created.

**Why**

This is diagnostic telemetry that helps distinguish sessions that reused existing setup from ones that started fresh, without changing anything a reader interacts with directly.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Device-linking (QR/pairing) requests can carry an onUpload callback

Device-linking (QR pairing) requests can now carry an onUpload callback

**Unclear.** What triggers the onUpload callback or what it's used for is not stated in the finding.

**What**

The tracker used for device-linking requests, such as pairing a new device via QR code, now accepts and stores an `onUpload` callback in addition to the existing `kind`, `accepts`, and `instanceId` fields when tracking a live request.

**Why**

This lets the pairing flow run additional logic when something is uploaded as part of linking a device, though the finding doesn't specify what that upload step does.

- Area: Device Linking
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New error classification for API 'policy_blocked' safety responses

Claude Code now recognizes a distinct API error for safety-policy-blocked requests

**What**

Claude Code can now detect a specific kind of API error: an HTTP 400 response whose body reports `error.type === 'policy_blocked'`. This is now classified separately using a new constant, `safety_monitor_blocked`.

**Why**

This lets Claude Code tell a safety-policy block apart from other generic 400 errors, which should make it possible to handle or explain this case more precisely instead of treating it like any other bad request.

- Area: Error Handling
- Names: `safety_monitor_blocked`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New cache-invalidation reasons for thinking toggles

Two new reasons added for why Claude Code re-sends a cached request after a thinking toggle

**What**

Claude Code keeps a cache of prompts/requests and invalidates (discards and re-sends) them when relevant settings change. Two new invalidation reasons have been added: `thinking_mode_changed` and `thinking_display_changed`, both tied to toggling Claude's extended thinking behavior.

**Why**

This makes it clearer, in logs and diagnostics, why a cached request was dropped and resent specifically because a thinking-related toggle changed.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Hooks errors carry a sanitized telemetry message

Hook errors now report a generic message to telemetry instead of the actual error text

**What**

When a function hook (a custom script that runs at certain events) throws an error, Claude Code now attaches a fixed, generic `telemetryMessage` to the resulting `HooksError`. That generic placeholder is what gets sent to telemetry, not the hook's actual error text.

**Why**

Hooks can be authored by plugins or other third parties, so their error messages might contain private or sensitive details. Sending a generic message instead protects that information from ending up in telemetry.

- Area: Hooks
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### File search index gains filename-only matching arrays

File search index gains separate data for matching against just the filename

**Unclear.** The finding shows the new arrays being added but not yet how they change actual search results or ranking.

**What**

Claude Code's fuzzy file-search index, which already stores per-file arrays like `lowerPaths`, `charBits`, and `pathLens` for matching, now also stores `nameStarts` and `nameCharBits`.

**Why**

These appear to let file search match against just the filename portion of a path on its own, separately from matching the full path, which should make searches for a bare filename more accurate.

- Area: File Search
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Background bash task metadata now records which shell was used

Background bash task info now records which shell ran the command

**What**

When Claude Code runs a bash command in the background and tracks it as a monitored task, the task's metadata now includes a `shell` field, alongside the existing command and working directory, recording which shell was used.

**Why**

This gives more complete information about how a background command was actually run, which can help when reviewing or debugging background tasks.

- Area: Bash Tool
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New tracking set for MCP elicitation requests

Claude Code adds tracking for outbound MCP 'elicitation' requests

**Unclear.** The finding only shows the tracking set being added, not what elicitation requests are used for or how they surface to the user.

**What**

Claude Code keeps track of outbound request IDs by category, such as `knownOutboundRequestIds`, `automatedOutboundRequestIds`, and `deviceOutboundRequestIds`. It now also tracks and clears an `elicitationOutboundRequestIds` set, corresponding to MCP (Model Context Protocol) 'elicitation' requests.

**Why**

This suggests Claude Code now recognizes MCP elicitation, a request type where a connected tool server asks for more information, as its own tracked category of outbound request.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Session context gains a toolDecisions map

Session context now includes a toolDecisions map alongside permission relays

**Unclear.** The finding shows the map being added to session context but not how or when decisions are recorded into it or read from it.

**What**

The context object Claude Code builds when running a query now includes a new `toolDecisions: new Map()`, alongside the existing `permissionRelays`.

**Why**

This suggests Claude Code now tracks tool permission decisions on a per-session basis, separately from the existing relay mechanism, though the finding doesn't show how this map is used yet.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New atomic-write conflict error cases for staged tempfiles

Two new error cases handle stuck or duplicated temp files during atomic file writes

**What**

The file-write error mapper gained two new error variants for atomic writes (writes that stage a temporary file before replacing the real one):

- `WORKING_TMP_STUCK` — the staged temporary file couldn't be removed after being taken back

- `WORKING_NAME_TWINNED` — the staged temporary file couldn't be removed or taken back, and may now exist as a second link at its target name

**Why**

These give more precise diagnostics for rare failure cases during atomic file writes, where a leftover or duplicated temp file could otherwise cause confusing or silent problems.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Customizable 'cut' warning text for a dir-sync arming flow

Folder-sync's 'cut' and 'arming' warning messages can now be customized instead of using fixed text

**What**

In a state machine that manages an arming/exit flow (likely for directory sync), the "cut" case now returns a caller-supplied `cutShortLine` warning message, where before it only logged internally and returned nothing to show. The "arming" default case now uses a caller-supplied `cutBeforeArmedLine`, falling back to a fixed constant if none is supplied.

**Why**

This lets callers customize the warning text shown at these points in the flow instead of being stuck with one fixed message or no message at all.

- Area: Directory Sync
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New per-turn running model override tracking

Claude Code now tracks which model override is actually in effect for the turn currently running

**What**

A new internal getter, `runningTurnModelOverride`, reports the model override that applies to the turn currently in progress. It only reports a value while that turn is still running and matches the current generation, and only if the session's current model and its 'pick as written' state still match what was recorded when the override was originally set.

**Why**

This keeps Claude Code from misreporting a model override if the session's model selection changes partway through a turn, since the override is only honored when the conditions it was captured under still hold.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Ultracode activation no longer triggers a side-effect nudge call

Checking whether ultracode mode is active no longer triggers a side-effect call

**Unclear.** The finding does not say what the removed call (`Dze()`) did, so its practical effect on behavior is unclear.

**What**

The internal check for whether 'ultracode' mode is active, whether turned on via settings or triggered by typing the keyword 'ultracode', previously also called a separate function as a side effect whenever it detected ultracode was active. That side-effect call has been removed, leaving the check as a plain true/false test.

**Why**

This makes checking for ultracode mode a pure lookup with no other consequences, removing whatever the extra call used to do each time the check ran.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Single-character text-entry key presses get a dedicated fast path

Typing a single character into a text field now takes a faster, dedicated code path

**What**

When a key press lands on a text-entry field and the key is exactly one character, Claude Code's input handling now short-circuits to a direct key-apply call instead of going through its normal input-handling path.

**Why**

This is a performance optimization for the common case of typing ordinary characters into text fields, letting Claude Code apply them more directly rather than routing them through the general-purpose input handler.

- Area: Input Handling
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### GitHub Actions/App installer flow rewritten (functionally equivalent)

The GitHub App install wizard was rewritten internally with no change to its steps or messages

**What**

The setup wizard behind `/install-github-app`, which connects a repository, checks GitHub CLI authentication and scopes, installs the Claude GitHub App, and wires up secrets and workflows, was substantially rewritten internally. A hand-rolled memoization cache was replaced with plain hooks and closures. The step names, error messages, and telemetry events (`tengu_install_github_app_started`, `tengu_install_github_app_step_completed`, `tengu_install_github_app_completed`, `tengu_install_github_app_error`) are unchanged.

**Why**

This is an internal code-quality rewrite; `/install-github-app` should behave the same as before from a user's perspective.

- Area: Elsewhere
- Names: `/install-github-app`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New telemetry reasons for thinking mode/display changes

Changing thinking mode or its display now gets its own telemetry reasons

**What**

Claude Code's config-change tracking gained two new fields, `thinkingModeChanged` and `thinkingDisplayChanged`. When either is set, it adds `thinking_mode_changed` or `thinking_display_changed` to the list of reasons recorded for why a request's context was rebuilt.

**Why**

This lets internal telemetry distinguish request rebuilds caused by changes to thinking mode or its display from other kinds of config changes, which is useful for diagnosing behavior rather than something a user directly interacts with.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Remote Control policy-denial path consolidated

Remote Control's org-policy-denial error handling was refactored to use a shared logging helper

**What**

When Remote Control (the feature that lets you control a Claude Code session from another device) is blocked by your organization's policy, Claude Code still shows the same "Remote Control is disabled by your organization's policy." message. Internally, the code that handles this now goes through a shared helper which logs a `policy_denied` reason and flushes analytics, instead of separately importing an analytics-flushing function.

**Why**

This is an internal cleanup of how the denial is logged and reported; it doesn't change what you see when Remote Control is blocked by policy.

- Area: Remote Control
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New optional "chained" field in a sync/session schema

Sync/session data now includes an optional "chained" field

**Unclear.** The finding does not say what the `chained` field represents or how it affects session syncing.

**What**

A data structure used for syncing session state (which already tracked `indexCommit`, `worktreeCommit`, and `bundle`) gained a new optional field called `chained`, with a fallback value if it can't be determined.

**Why**

This is internal state used by Claude Code's sync mechanism; the finding does not describe what behavior it enables for users.

- Area: Session Sync
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### correctionAttachment added to REPL/tool routing

REPL/tool routing for cloud sessions gains a new "correctionAttachment" field

**Unclear.** The finding does not say what a correction attachment is used for or when it is populated.

**What**

The internal routing information used when executing tool calls in a cloud-hosted or remote-capable session now includes a `correctionAttachment` field, alongside the existing `noticeAttachment` field.

**Why**

This is internal plumbing for how tool execution results get attached back to a session; the finding does not describe what a correction attachment contains or when it appears.

- Area: Tool Routing
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Git stash-create now passes sparse-checkout scoping env/args

Git stash snapshots now respect sparse-checkout scoping instead of always stashing everything

**Unclear.** The finding does not say exactly what the new `s` parameter contains or how it is determined, only that it feeds sparse-checkout related args and env vars into the stash command.

**What**

When Claude Code creates a git stash to snapshot uncommitted changes (for example before syncing a directory to the cloud), it now passes sparse-checkout related arguments and environment variables into the underlying `git stash create` command, based on a new parameter. Previously the stash was always created as a plain `git stash create` with no such scoping applied.

**Why**

Sparse checkouts let a repository check out only part of its files. Without scoping, a stash snapshot could behave inconsistently with a sparse checkout's limited file set. Passing this information through keeps the snapshot behavior consistent with how the repository is actually checked out.

- Area: Git Integration
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### MCP connect failure telemetry now includes an extra field via Mae(n)

MCP connect-failure telemetry now includes an extra data field

**Unclear.** What data the added field actually carries is not specified in the evidence.

**What**

When a connection to an MCP server (a way Claude Code connects to external tools and data sources) fails, the telemetry events sent for it (`mcp_connect_failed`, `mcp_connect`) now include an additional set of fields drawn from a new source, alongside the fields already collected.

**Why**

This gives more detail to diagnose why MCP connections fail, though the finding does not specify what the new fields contain.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New session-initiator / wakeup-source telemetry categories

New telemetry categories record why and how a session was started or woken up

**What**

Claude Code now records, in telemetry, a category explaining what triggered a session to start. The options include:

- `user`

- `scheduled-task`

- `sleep-auto-resume`

- `quit-auto-resume`

- `remote-restart-auto-resume`

- `ci-monitor`

- `dispatch`

- `side-session-brief`

- `side-session-start`

- `side-session-wake`

- `other`

A separate `wakeup_source` field records whether a wakeup came from `loop_wakeup` or `schedule_wakeup`.

**Why**

This gives more detailed visibility into how sessions get started or resumed, whether by a person, a scheduled task, auto-resume after sleep or a quit, or other automated triggers.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Remote Control's usage-fetch callback generalized into a shared control request handler

Remote Control's usage-fetch handler is now part of a broader shared control request mechanism

**What**

The callback that Remote Control (controlling a Claude Code session from another device) used to fetch usage data, previously named `onGetUsage`, has been replaced with `answerSharedControlRequest`, a more general handler. Usage queries now appear to be handled as one type of request within this broader shared-control mechanism rather than a dedicated callback of their own.

**Why**

Generalizing the usage callback into a shared request handler suggests Remote Control is being built to support more kinds of requests beyond just usage data through the same mechanism.

- Area: Remote Control
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Permission approvals can now record a wait-time note when a host was slow to answer

Permission approvals can now note how long the host took to reconnect after an environment restart

**What**

The tool-approval flow now accepts a `speculation` parameter, and when a wait time (`waitedMs`) is recorded, it adds a note to the session reporting how many seconds the flow waited for the host to reconnect after the session's environment restarted.

**Why**

This surfaces delays caused by the host reconnecting after an environment restart, making it clearer why a permission approval took longer than expected.

- Area: Permissions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### macOS O_NOFOLLOW file-open now probes for kernel support first

macOS symlink-safe file open now checks for kernel support before choosing its method

**What**

The file-opening logic used on macOS to safely read files without following symlinks now first runs a probe to check whether the extended no-follow-symlink option is supported by the current system, caching the result. If it isn't supported, it falls back to a plain open instead of trying the extended flags and retrying after failure.

**Why**

This avoids an unnecessary failed attempt and retry on macOS systems where the extended symlink-safety option isn't available, making the file-open path more efficient and reliable.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Proactive-suggestion tool schema drops the enum for 'trigger'

A tool's 'trigger' input field lost its fixed list of allowed values

**Unclear.** What tool this `trigger` field belongs to and why the enum constraint was dropped are not stated.

**What**

A tool input field named `trigger`, which previously had to be either `"user_asked"` or `"proactive"` (with a description explaining the distinction), now accepts a looser, unconstrained value.

**Why**

The evidence does not state why the constraint was loosened or what effect this has on the associated tool's behavior.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Plugin install/update telemetry now records git commit SHA

Plugin install/update telemetry now also records the plugin's install location and, for updates, its git commit SHA

**What**

The `tengu_plugin_installed_cli` and `tengu_plugin_updated_cli` telemetry events (sent when a plugin is installed or updated from the command line) now include extra fields:

- a set of fields keyed off the plugin's install location, sent with both events

- the plugin's git commit SHA, sent with the update event only

This builds on the marketplace-catalog verification step added earlier, which confirms a plugin exists in the marketplace before logging it and otherwise falls back to a redacted, third-party record.

**Why**

Recording the install location and commit SHA gives more precise identification of exactly which plugin version was installed or updated, on top of the existing marketplace verification.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### File suggestion index now tracks and returns a base directory

File path suggestions (for @-mentions) now also report the base directory they were matched against

**Unclear.** The finding does not say what user-visible effect, if any, this has on file suggestion behavior.

**What**

When you type a file path in Claude Code, such as after an `@`-mention, an internal function looks up matching files and paths to suggest. That function used to return just a plain list of matches. It now returns an object with two parts: `items` (the list of matches) and `baseDir` (the directory the matches were resolved against).

Related to this, the internal function that refreshes the git-based file index (`getFilesUsingGit`) now takes the working directory as an explicit parameter, instead of figuring it out on its own.

**Why**

This is an internal change to how file suggestions are computed and doesn't change what you type or see when using @-mentions or path completion, but it makes the base directory used for matching explicit and traceable rather than implicit.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Model list gains basePickerIds excluding "session tail" entries

The model picker's internal list now has a version that excludes "session tail" entries

**Unclear.** It is unclear what a "session tail" model entry is or what visible effect excluding it from `basePickerIds` has for users of the model picker.

**What**

The internal code that builds the list of models shown in the model picker now also produces a second list, `basePickerIds`, alongside the existing `pickerIds`. This new list filters out any entries marked `sessionTail`.

**Why**

This is an internal change to how the model picker's data is assembled, so it is not clear from this alone what a reader will see differently, if anything.

- Area: Models
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Served-tools session channel reannounces after reconnect for control-only channels

Claude Code now re-announces available tools after a reconnect on control-only session channels

**What**

Claude Code keeps a per-session channel that announces which tools are available to a "worker" process. For channels marked control-only, the channel now notices when the worker disappears, and when it comes back online (`onWorkerLive`), it triggers a `reconnected` reannounce of the available tools. This is on top of the existing reannounce that already happened when the connection stream itself reconnected.

**Why**

Without this, a control-only channel whose worker dropped and came back could end up with a stale or missing record of which tools were available. Reannouncing on worker reconnect keeps that list accurate.

- Area: Remote Tools
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Turn-diff telemetry gains thinking-mode and thinking-display change tracking

Claude Code's internal turn logs now note when thinking mode or thinking display settings change

**What**

Claude Code keeps an internal log of what changes between turns of a conversation, such as effort level or model. That log now also records:

- when the thinking mode changes, showing the previous and new value

- when the thinking display changes, showing the previous and new value

('Thinking mode' controls how Claude reasons before responding, and 'thinking display' controls whether that reasoning is shown.)

**Why**

This is internal diagnostic logging rather than a visible feature, so it doesn't change what you see or do in Claude Code. It gives more detail for diagnosing issues where reasoning behavior changes unexpectedly between turns.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Git dir-sync tamper-tracking key format changed

The internal key Claude Code uses to track tampered or planted git directories now has a root: prefix

**What**

When Claude Code syncs a linked git working directory (used for features like cloud sessions), it keeps track of directories it has flagged as "tampered" or "planted" (altered outside Claude Code's control). The internal identifier used to record this state is now prefixed with `root:` instead of being just the raw identifier.

**Why**

This is an internal bookkeeping change; it doesn't change what gets flagged, only the format of the key Claude Code uses to track it.

- Area: Git Sync
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Git-sync session state gains servedLinked and everSent-on-empty-checkout fields

Git-sync session data now tracks whether a linked working tree was served and, for empty checkouts, a list of already-sent files

**What**

Claude Code's git directory-sync feature keeps a record of each sync session's state. This record can now optionally include:

- `servedLinked`, noting whether a linked working tree (rather than a full copy) was served for that session

- an `everSent` list, started empty, set up when a session begins from an empty checkout

**Why**

These additions let Claude Code keep more accurate track of what has already been synced, which should help sync sessions behave correctly around linked working trees and empty checkouts.

- Area: Git Sync
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New turnOrigin field on a generation/session object

Claude Code's internal turn-tracking object gained a new turnOrigin field

**Unclear.** What turnOrigin is used for and how it affects behavior isn't specified.

**What**

The internal object Claude Code uses to manage a streaming generation turn, alongside existing fields like `shuttingDown`, `holdsResults`, and `cacheSafeParams`, now also carries a `turnOrigin` property.

**Why**

This is an internal data field with no described effect on visible behavior.

- Area: Session Management
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New abort-check helper for local agents and in-process teammates

Added a helper to check whether local agents or in-process teammates have been aborted

**What**

Claude Code adds a helper function that checks whether a piece of work has been cancelled. For a `local_agent`, it checks that agent's own abort signal; for an `in_process_teammate` (a teammate running in the same process), it checks a separate `currentWorkAbortController` abort signal.

**Why**

This lets Claude Code correctly detect cancellation for both local agents and in-process teammates, which are tracked differently internally.

- Area: Swarm
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Discover-support probe for claudeai-proxy connections

Claude Code added a probe to check whether claudeai-proxy connections need a legacy discovery fallback

**What**

Claude Code adds a new check that runs for connections of type `claudeai-proxy` to determine whether they need to fall back to an older discovery method. The check skips connections that are stateless or already confirmed to support discovery, and it caches ids already found not to support the newer listing/discovery behavior ("burned" priors) so they aren't checked repeatedly.

**Why**

This helps Claude Code avoid unnecessary repeated checks when talking to claudeai-proxy connections, falling back to older behavior only when needed.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Tool denials during a permission-stop now explicitly end the turn

Denying a tool call during a permission-stop now explicitly ends the turn instead of just blocking that one call

**What**

When a tool call is denied while Claude Code is in a "permission-stop" state (a running turn halted pending a permission decision), the resulting tool-result message now carries a `toolDenialEndsTurn` flag. A new helper walks back through the conversation's messages and treats a user message with `toolDenialEndsTurn` set to true as ending the turn outright, rather than as merely interrupted.

Separately, when a permission decision to deny a tool has `endsTurn` set, Claude Code now aborts the whole running turn, with reason `permission-stop`, instead of just denying that single tool call.

**Why**

This changes how Claude Code classifies what happens after a tool denial: some denials now cleanly end the turn rather than leaving it in an ambiguous "interrupted" state, making turn completion and permission handling more predictable.

- Area: Permissions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Claude in Chrome status telemetry function added

Added a telemetry function that reports Claude in Chrome's extension pairing and connection status

**What**

Claude Code adds a function that gathers status information about the Claude in Chrome browser extension for telemetry, including:

- whether the extension is installed

- whether an MCP client (a connector to external tools) for the extension is connected

- the name of the paired browser device

- whether the extension is enabled by default, controlled by the `claudeInChromeDefaultEnabled` config setting

**Why**

This gives Claude Code visibility into how the Claude in Chrome extension is set up and connected, supporting diagnosis and improvement of that integration.

- Area: Claude in Chrome
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### claude plugin test refusal messaging refactored into a shared helper

The claude plugin test command's refusal messaging was refactored into a shared helper function

**What**

When `claude plugin test` or `claude plugin test --file` refuses to run because hooks modules are disabled, the logic that decides on and produces that refusal message now goes through a single shared helper called `pluginTestRefusal`, instead of separate inline checks. The helper takes the error details, whether the relevant rollout is on, and whether user modules can be loaded.

**Why**

This is an internal code cleanup with no visible change to what the command does or says. It should make the refusal behavior more consistent and easier to maintain going forward.

- Area: Plugins
- Names: `claude plugin test`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Early-input capture now skips agents.json invocations

Claude Code no longer captures early terminal input when launched via an agents.json invocation

**What**

Claude Code has a startup check that decides whether to start capturing terminal input very early, before the app is fully ready. That check now also skips capture when the process was started as an `agents.json` invocation, joining the existing exclusions for MCP-serve, plugin-eval, and remote-control launches.

**Why**

This avoids grabbing terminal input in a launch mode where doing so isn't appropriate, matching how the other special launch modes already behave.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Remote-create permission-mode push gets an onTaken callback

Pushing the initial permission mode to a new remote session now supports an onTaken callback

**What**

The internal function that sends the starting permission mode (the rule set controlling what actions Claude can take without asking) to a newly created remote session now accepts an `onTaken` callback. This callback fires once the session confirms it has taken the pushed mode.

**Why**

This is an internal plumbing change that lets other code react precisely when a remote session's permission mode has actually taken effect, rather than assuming it happened.

- Area: Sessions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New 'elicitation' kind for pending-action republish telemetry

Pending-action telemetry now tracks elicitation requests as their own category, separate from dialogs and permissions

**What**

Internal telemetry for `tengu_pending_action_republished` records a `survivor_kind` for pending actions. It now distinguishes an "elicitation" request (a specific tool request type) as its own category, where previously such requests would have fallen under "dialog" or "permission".

**Why**

This gives more precise internal tracking of what kind of pending action was republished, which doesn't change what a reader sees but helps Anthropic understand this behavior more accurately.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New MailboxBridge helper to mark non-structured messages read has no in-bundle caller

A new internal function can mark a batch of non-structured mailbox messages as read, though nothing yet calls it

**Unclear.** Whether or how this function is invoked elsewhere is not established.

**What**

Claude Code adds a new function that marks a batch of "non-structured" mailbox messages as read for a given agent or team, logging either success or a warning if the mark-as-read fails (in which case the messages will be re-attached next turn).

**Why**

No code was found in the app that actually calls this function with its full set of arguments, so it isn't yet in active use.

- Area: Teammates
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Rate-limit tracker gains restoreLimits to reinstate a previously-known status

Rate-limit tracking gains a restoreLimits method to directly reinstate a previously known limit status

**What**

The internal tracker that follows Claude Code's API rate limits has a new `restoreLimits(limits, observed)` method. It directly sets the current limits and observation state and announces the change, without going through the usual process of deriving limits from live observations.

**Why**

This gives Claude Code a way to reinstate a known rate-limit status directly, which is useful when a previously seen state needs to be restored rather than recomputed from scratch.

- Area: Rate Limits
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New filesystem error case: WORKING_NAME_NOT_PLAIN

A new filesystem error, WORKING_NAME_NOT_PLAIN, reports when a file placement isn't a plain file name

**What**

Claude Code has a new internal error case for file placement failures, which produces the message "not a plain file name here".

**Why**

This gives a clearer, specific error when a file operation fails because the name being used isn't a plain file name, rather than reporting a generic failure.

- Area: File Handling
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New invariant guard on sync journal notes

A new internal check now throws an error if a sync journal note carries a chain that would otherwise silently be dropped

**What**

Claude Code keeps a sync journal to track certain state. A new runtime assertion now throws an error when a journal note carries a chain of data that its reader would otherwise drop, such as entries out of order, a malformed link, or a carrier type this build doesn't know how to write.

**Why**

This turns a case that used to fail silently, by quietly discarding data, into a visible error, making problems in sync journal data easier to catch instead of going unnoticed.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New system message subtype recognized: api_retry

Claude Code now recognizes a system message subtype called api_retry

**Unclear.** What the api_retry subtype recognition is used for once identified is not stated.

**What**

A new helper function identifies internal system-type messages carrying the subtype `api_retry`.

**Why**

The finding doesn't say what uses this recognition for, so it's unclear what behavior it enables beyond identifying these messages.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Pasted content now wrapped with an id attribute

Pasted content is now wrapped in tags that carry an id attribute

**What**

When Claude Code wraps text you pasted into a prompt (as opposed to typed) in `<pasted_content>` tags, those tags now carry an `id` attribute, appearing as `<pasted_content id="...">`.

**Why**

Giving each pasted block an id makes it possible to identify and refer to a specific piece of pasted content individually, rather than treating all pasted text as an undifferentiated block.

- Area: Input Handling
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New schema fields: single_page and trigger

Two config schemas gained new optional fields, single_page and trigger

**Unclear.** The finding shows the new fields exist but not what setting them actually does.

**What**

A permissions/config schema now accepts an optional `single_page` true/false setting, and a schema related to plugin search now accepts an optional `trigger` field.

**Why**

These are internal schema additions with no described behavior yet, so it's unclear what using them changes in practice.

- Area: Elsewhere
- Names: `single_page`, `trigger`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Browser-related skill asset converted from script text to a SKILL.md file

Bundled browser skill switched from a compiled script file to a SKILL.md file

**What**

A built-in "skill" (a packaged set of instructions Claude Code can load for a task) related to browser use used to ship as a compiled script file (`ctbrowser.mjs`). It now ships as a `SKILL.md` file instead, written in markdown, matching the format used by other bundled skills.

**Why**

This is a packaging change to how the skill is stored and shipped, bringing it in line with the format other skills already use.

- Area: Skills
- Names: `SKILL.md`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Windows-specific env vars added to the host-passthrough allowlist

More environment variables, including Windows-specific ones, now pass through to Claude Code

**What**

Claude Code now allows more environment variables through to itself:

- `HOMEDRIVE`, `HOMEPATH`, and `PROGRAMDATA`, which help resolve credential and config paths on Windows

- `CCR_ENABLE_BUNDLE`, `CCR_FORCE_BUNDLE`, and `CLAUDE_CODE_DIR_SYNC_CHAIN`, alongside existing directory-sync and legacy-bundle variables

`CCR_FORCE_BUNDLE` is documented as forcing `claude --cloud` to bundle and upload your local repository instead of cloning it from its remote.

**Why**

The Windows-specific variables improve how Claude Code finds config and credential paths on Windows. The `CCR_*` variables continue to support remote "teleport" sessions that seed a remote workspace from a local git bundle.

- Area: Windows
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### MCP elicitation dialogs get their own outbound-request tracking

MCP elicitation dialogs now get their own tracking of outbound requests

**What**

Claude Code now tracks outbound requests for MCP "elicitation" dialogs (prompts an MCP server can trigger to ask the user for input) separately, with a dedicated tracking list and a new dialog type identifier, alongside the existing tracking for known, automated, and device-related outbound requests.

**Why**

This is internal bookkeeping that lets Claude Code distinguish elicitation-triggered dialogs from other kinds of outbound requests, which likely improves how these dialogs are matched to their responses.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### toolDecisions moved from plain object to Map

Internal tool-decision tracking switched from a plain object to a Map

**Unclear.** The finding only shows the underlying data structure changed, not why or what effect it has.

**What**

The internal record of tool decisions (`toolDecisions`), which is looked up by a tool call's id, changed from a plain object to a Map data structure.

**Why**

This is an internal data-structure change with no described effect on behavior, so it's unclear what it changes for users.

- Area: Permissions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Tool-search 'surfaced' tracking now distinguishes value-defined tools

Tool-search bookkeeping now tracks whether a newly added tool was defined inline

**Unclear.** The finding doesn't state what practical difference this distinction makes to users.

**What**

The internal bookkeeping for deferred tool search (which tracks which tools have been announced to the model) now records whether a tool addition was defined inline by its full value, versus just referenced by name on the wire. This is tracked alongside the existing record of which tools have been surfaced.

**Why**

This is internal plumbing supporting how newly-added tools get announced to the model, with no directly described user-facing effect.

- Area: Tool Listing
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Agent-to-agent messages can now carry a from-plugin identifier

Agent-to-agent messages can now carry a from-plugin identifier

**What**

Messages passed between agents or sessions already carried tags like `from`, `from-session`, `hop-chain`, `from-name`, and `from-mode`. They now support an additional optional `from-plugin="..."` attribute, which Claude Code parses into a `fromPlugin` field.

**Why**

This lets a receiving agent know which plugin originated a message, which matters when multiple plugins are sending messages into the same conversation.

- Area: Messaging
- Names: `from-plugin`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Subprocess exit codes now attached to errors for telemetry

Claude Code now attaches a child process's exit code to any resulting error for telemetry

**What**

When a subprocess (a program Claude Code runs on your behalf) exits, Claude Code now tags the resulting error or exception with that process's exit code, using a new hidden marker called `telemetryChildExitStatus`. The exit code is checked to be a whole number within an expected range before being attached.

**Why**

This is internal bookkeeping: it lets Claude Code's telemetry pull the exact exit code out of an error later, rather than the failure being reported without that detail. It does not change any visible behavior.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Plugin-load telemetry now also reports disabled plugin names

Claude Code's plugin-load telemetry now also records the names of disabled plugins

**What**

When Claude Code loads plugins (add-ons that extend its functionality) and sends its `tengu_plugins_loaded` telemetry event, it now includes a `disabled_names` field listing plugins that are disabled, alongside the `enabled_names` field it already sent for enabled plugins.

**Why**

This gives Anthropic visibility into which plugins users have disabled, not just which ones are active, which can help with understanding plugin adoption and troubleshooting.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Compliance taint list now filters out entries via a new predicate before merging

Compliance taint merging now drops taints matching a new filter before combining and trimming the list

**Unclear.** What specific taints the new filter excludes, and why, is not stated in the evidence.

**What**

When Claude Code merges `compliance_taints` (internal markers used to track compliance-related state) from a new source into the existing list, it now runs each incoming taint through a new filter check before adding it. Any taint for which this check returns true is left out of the merge. The combined list is still trimmed down to a maximum number of entries afterward, as before.

**Why**

This prevents certain taint entries from being carried into the merged list, keeping it from accumulating entries that should be excluded. The finding does not say which taints the filter excludes or what condition it checks.

- Area: Compliance
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New device-binding rejection reasons 'environment' and 'target_device_unsupported'

Two new reasons, 'environment' and 'target_device_unsupported', can now mark a session as not bindable to a device

**Unclear.** The finding does not say what triggers these two new reasons or how they affect user-visible behavior.

**What**

Claude Code has internal logic that checks whether a session can be bound to a particular device. This check returns a reason when binding isn't allowed, and two new reasons have been added:

- `environment`

- `target_device_unsupported`

Both join existing reasons such as `endpoint`, `pool`, and `correlation`, and like those, they mean the session is not bindable.

**Why**

This is internal plumbing for device or session binding rather than something a reader directly configures. The practical effect is that more specific situations can now be identified as not supporting binding, rather than falling into a generic or existing category.

- Area: Device Binding
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Directory-sync push telemetry expanded to track chained pushes and basis info

Directory-sync push telemetry now records whether a push chained off a prior one and other basis details

**What**

The `tengu_dir_sync_push` telemetry event, which records when Claude Code pushes local directory changes through its git-based sync, now reports several new fields: `chained` (whether this push builds on a previous one), `chains` (how many pushes are chained together), `busy_cause` (why a snapshot was refused when git was busy), `first_upload`, `basis`, `link_edge`, and `chain_broken`.

**Why**

These extra fields give more detail about how each sync push relates to the ones before it, which can help diagnose sync issues like stalled or broken chains of pushes.

- Area: Directory Sync
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Memory editor now aware of 'added instruction files'

The /memory editor now knows about 'added instruction files' when picking files

**Unclear.** It's not clear from the evidence what visible behavior this enables in the file picker.

**What**

The component behind `/memory`, the screen for editing `CLAUDE.md` files and managing auto memory, now takes an `addedInstructionFiles` parameter and passes it down into its file-picker part alongside the existing session, selection, and cancel handling.

**Why**

This lets the file picker in `/memory` be aware of instruction files that have already been added, though the finding doesn't specify exactly how that awareness changes what's shown.

- Area: Memory
- Names: `/memory`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### git ls-files calls now force core.precomposeUnicode=false

Git file-listing calls now force off macOS Unicode filename normalization

**What**

The internal helper that lists tracked files with `git ls-files` now always passes `-c core.precomposeUnicode=false` before running the command.

**Why**

This keeps filename Unicode normalization consistent regardless of local git configuration, avoiding mismatches (such as differences between NFD and NFC forms on macOS) when Claude Code inspects or diffs a working tree with filenames containing accented or special characters.

- Area: Git Integration
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Session-scoped bypass added to fable overage consent check

A per-session cache can now short-circuit the fable overage billing consent check

**Unclear.** The finding does not state why the session-scoped cache was added, only what it does.

**What**

The function that checks whether a user has consented to fable overage billing now first checks a cached value scoped to the current session. If that cached value matches the current organization and account, it short-circuits to "consented" without checking the persisted `fableOverageConsentV2` record.

**Why**

This likely avoids repeatedly re-checking the persisted consent record within the same session, though the finding doesn't specify the performance or behavioral benefit directly.

- Area: Usage & Limits
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New telemetry for SDK MCP first-query wait time

New telemetry tracks how long a turn waits for SDK MCP servers to connect

**What**

When a turn starts before SDK MCP servers (Model Context Protocol servers set up through the SDK) have finished connecting, Claude Code now records a metric, `sdk_mcp_first_query_wait_ms`, capturing how long the turn had to wait. This is in addition to the existing warning message that tools aren't available yet.

**Why**

This gives visibility into how much delay is caused by MCP servers still connecting when a query starts, which can help identify slow-starting servers.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### E2BIG shell-exec failures now classified distinctly

Shell commands that fail because the argument list is too long are now labeled with a distinct error code

**What**

When a shell command fails to start because its argument list is too long (an "E2BIG" error), Claude Code now tags the failure with an explicit `e2big` reason code, instead of just logging and throwing a generic error. This matches how other parts of the codebase already check for `preSpawnErrorCode === "e2big"`.

**Why**

This lets other parts of Claude Code recognize and handle argument-list-too-long failures specifically, rather than treating them the same as any other shell startup failure.

- Area: Bash Tool
- Names: `e2big`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### isVerified flag threaded through for unverified content blocks

Content blocks can now be marked as unverified via a new isVerified flag

**Unclear.** It's unclear what kind of content this applies to or how an unverified flag is shown to the user.

**What**

A rendering or content-handling path now sets `isVerified: false` when a fourth captured field in the underlying data equals the string "false", alongside the existing color and summary handling.

**Why**

This suggests some content blocks can now be flagged as unverified, but the finding doesn't say what unverified content looks like to the user or what triggers it.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Telemetry gains ant_disabled_names alongside ant_enabled_names

Theme-loading telemetry now also records disabled theme names, not just enabled ones

**What**

The telemetry event fired when themes load already reported `ant_enabled_names`; it now also reports `ant_disabled_names`, though in the failure path captured here the value is currently empty (`void 0`).

**Why**

This gives more complete visibility into theme state by recording which themes were disabled, not just which were enabled, when diagnosing theme-loading issues.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Plugin evidence resolution added (stack / resumed / dispatch)

New logic resolves which plugin is responsible for something via stack, resumed-session, or dispatch lookup

**Unclear.** The finding doesn't say what feature relies on knowing which plugin is responsible, such as error reporting or telemetry.

**What**

A new function determines which plugin something belongs to by trying, in order: a stack-based lookup, a lookup for resumed sessions using an atomics-backed name table, and finally a dispatch-based lookup. Whichever method succeeds tags the result with an `evidence` field of `"stack"`, `"resumed"`, or `"dispatch"` noting how the answer was found.

**Why**

This makes plugin attribution more reliable across different situations, including sessions that have been resumed, and records how confident or by what method the attribution was made.

- Area: Plugins
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Remote rate-limit frames deduped and dropped-frame telemetry added

Remote rate-limit updates are now deduplicated per account, with telemetry for dropped or invalid frames

**What**

A new module handles incoming remote rate-limit updates on a per-account basis. It drops stale or duplicate updates when the active account has changed, and reports telemetry whenever an update fails validation or gets dropped because of an account switch.

**Why**

This prevents rate-limit information from one account leaking into or confusing the display for another account after a switch, and gives visibility into how often that situation occurs.

- Area: Rate Limits
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Remote tool serving adds detailed reply-timing telemetry

Serving a remote tool call now records detailed timing for each stage of the reply

**What**

When Claude Code serves a tool call that came in remotely, it now measures and reports how long each step took: serving the call, preparing the reply, and signing or posting the signed reply. This is sent as a `tengu_remote_tool_serve` telemetry event, alongside a matching low-level trace for each step.

**Why**

This gives finer-grained visibility into where time goes when a remote tool call is answered, which helps diagnose slowness in remote tool execution.

- Area: Remote Tools
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New content-hash-based dedup cache for outgoing notification messages

A new cache prevents the same notification message from being written to a recipient twice

**What**

A new internal cache hashes each outgoing notification message (its sender, timestamp, text, summary, color, and originating plugin) and tracks whether that exact message has already been delivered to a given recipient. It supports retiring, retaining, and forgetting entries, and evicts old entries once it hits a size limit.

**Why**

This stops duplicate notifications from being written to the same recipient more than once.

- Area: Terminal UI
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Session telemetry gains remote_control_lane and projects_session fields

Session-start telemetry can now include remote_control_lane and projects_session fields

**Unclear.** The finding doesn't say what values these fields take or when they're populated.

**What**

The telemetry event sent when a session starts can now optionally carry two new fields, `remote_control_lane` and `projects_session`, in addition to the existing `subscription_type`, `parent_agent_id`, `cc_prompt_id`, and `desktop_app_version` fields.

**Why**

This gives more context about how and where a session was started, useful for distinguishing sessions started via remote control or as part of a project.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### PowerShell tool records the call's origin (local vs remote) in telemetry

PowerShell/Bash tool telemetry now records whether a command came from a local or remote call

**What**

Both the success and failure telemetry events for the PowerShell (and Bash) tool now include a `call_origin` field, set to either "local" or "remote" depending on where the command was issued from.

**Why**

This lets telemetry distinguish commands run by a local user from those issued remotely, which is useful for understanding usage and diagnosing issues tied to remote execution.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Coalesced teammate messages now carry sender name and verification status

Grouped teammate messages now record the sender's name and whether they're unverified

**What**

When several consecutive messages from the same display name are collapsed into a single grouped entry, that entry now also stores `senderName` and `isUnverified`, not just a message count as before.

**Why**

This preserves who sent a coalesced group of messages and whether their identity is unverified, information that would otherwise be lost when messages are grouped together.

- Area: Teammates
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New "device_reenroll" telemetry/operation kind

A new device_reenroll telemetry/operation kind was added

**Unclear.** The finding doesn't say what triggers a device_reenroll operation or how it differs in practice from device_registry_register.

**What**

A new entry, `device_reenroll`, was added to the set of device-related operation kinds, joining existing ones like `device_key_store`, `device_mcp_host_consent`, `device_mcp_serving`, and `device_registry_register`.

**Why**

This adds a distinct category for tracking device re-enrollment as its own operation, separate from initial registration or key storage.

- Area: Device Linking
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### PowerShell tool availability now reported in device-bridge telemetry

Device-bridge connection telemetry now also reports whether PowerShell is available

**What**

The telemetry event sent when a device bridge connection frame is established now includes a `serves_powershell` field indicating whether PowerShell is among the tools served, alongside the existing field for whether `bash` is served.

**Why**

This gives visibility into whether PowerShell is available over a device bridge connection, matching what was already tracked for Bash.

Gate state

Nothing has been read yet about whether `tengu_device_bridge_connect_frame` is switched on.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Attestation now tracks elicitation-related request IDs

Request-ID attestation now also tracks elicitation-related outbound request IDs

**Unclear.** The finding doesn't say what elicitation requests are used for in this context.

**What**

The check that validates request IDs match between inbound and outbound requests now also checks a new set, `elicitationOutboundRequestIds`, alongside the existing inbound and outbound request ID sets.

**Why**

This extends request-ID validation to cover elicitation requests (a mechanism for asking for additional input), helping ensure those requests are properly correlated too.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New "remote_tools_probe" and "remote_tools_reannounce" added to an existing event/name set

remote_tools_probe and remote_tools_reannounce added to an existing internal event/name set

**Unclear.** What the set governs, and what practical effect adding these two names has, is not shown in the evidence.

**What**

An existing set of names, built by extending a prior set, now also includes `remote_tools_probe` and `remote_tools_reannounce`.

**Why**

This is a small internal addition; the finding doesn't specify what the set is used for or what effect including these two names has.

- Area: Remote Tools
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### sdk_apply_flag_settings and sdk_update_settings switched to a different wrapping helper

SDK methods applyFlagSettings and updateSettings now route through a different internal wrapper function

**Unclear.** The finding does not say what behavior, if any, differs as a result of using the new wrapper function.

**What**

Two methods used by the Claude Code SDK's query client, `applyFlagSettings` and `updateSettings`, now send their asynchronous requests through a different internal helper function than before. The SDK is the toolkit that lets code outside Claude Code drive it programmatically, and `updateSettings` is the method that lets that outside code change settings.

**Why**

This is an internal plumbing change: the finding does not indicate any difference in what `applyFlagSettings` or `updateSettings` do or how they're called, only that a different underlying function now carries the request.

- Area: SDK
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New host.requestLatches.markThinkingHighlightsRefused helper

A new markThinkingHighlightsRefused helper marks 'thinking highlights' as refused in Claude Code's internal session state

**Unclear.** What triggers a 'thinking highlights' refusal or what user-visible effect it has is not stated.

**What**

A new internal helper, `markThinkingHighlightsRefused`, was added to `host.requestLatches`, the part of Claude Code that tracks per-session request state. It marks 'thinking highlights' (a feature related to displaying Claude's reasoning) as refused, following the same pattern as the existing `markThinkingResumptionRefused` helper.

**Why**

This is an internal plumbing change with no described effect on how Claude Code behaves day to day. It extends the session state tracking so the app can record when thinking highlights are refused, similar to how it already tracks refused thinking resumption.

- Area: Thinking Mode
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Background-agents view startup now gated by an upfront check

Opening the background-agents view now runs a startup check first and won't open if it fails

**Unclear.** The finding does not say what the check verifies or what conditions cause it to fail.

**What**

When opening the background-agents (fleet) view, Claude Code now runs an upfront check before showing the view. If that check fails, it prints an error message and stops without opening the view.

**Why**

This prevents the background-agents view from opening into a broken or unready state, showing an error instead so the underlying problem is clear.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### propose_skills tool now validates proposal targets before the read-before-improve check

The propose_skills tool now checks that proposals are valid before running its existing freshness checks

**Unclear.** The finding does not say what specifically makes a proposal fail this new validation.

**What**

The `propose_skills` tool (used to submit proposed skills, which are packaged instructions Claude Code can follow for a task) now runs an extra validation pass over all proposals before it gets to the existing check that requires a skill to have been read recently before it can be improved. If this new check fails, the tool returns an error (error code 2) with a message explaining the problem.

This builds on the tool's existing description-length cap, which previously enforced descriptions under 200 characters (never exceeding 1024).

**Why**

Catching invalid proposals earlier means the tool can reject bad input with a clear message before spending time on the later freshness check, giving faster and more direct feedback when a proposal is malformed.

- Area: Skills
- Names: `propose_skills`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New "protected_name"/host-config withholding reasons for file sync

File-sync now recognizes and withholds a machine's own Claude Code config files linked under another name

**What**

When Claude Code compares or syncs files (for example during merges or worktree checks), it now checks whether a file is actually this machine's own Claude Code configuration, just linked in under a different name from its config home. If so, the file is withheld with a specific reason instead of being treated as an ordinary file that failed to be read.

Two new reasons can now appear when files are withheld:

- `withheld_host_config` - the file is this machine's Claude Code configuration under another name, linked from its config home, and was left alone

- `withheld_config_unexamined` - the file was left alone because this machine's Claude Code configuration could not be examined in full

**Why**

This prevents Claude Code from mistaking its own configuration files, when they happen to be linked into a synced or compared location under another name, for ordinary content that needs to be diffed or merged. It also gives a clearer, more specific explanation when such a file is skipped, rather than lumping it in with generic unreadable files.

- Area: File Sync
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New remote-control message kind: remote_tools_reannounce

Claude Code's remote-control protocol adds a remote_tools_reannounce message for re-sending available tools

**Unclear.** The finding does not say what triggers a reannouncement or how it affects the client side beyond the protocol addition itself.

**What**

Claude Code can be driven remotely through a remote-control protocol, which lets a separate session or client send messages back and forth with a running worker. A new message kind, `remote_tools_reannounce`, has been added to this protocol. It is used so a worker can reannounce its available tools, tied to the worker's epoch (a marker for which run instance it belongs to) and a deadline.

**Why**

This is an internal protocol addition rather than something a user configures directly. It gives the remote-control system a way to refresh which tools a worker has available without needing a full reconnect, which matters for keeping remote sessions in sync.

- Area: Remote Control
- Names: `remote_tools_reannounce`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Stalled state added to remote/plumbing status tracking

Remote/plumbing status tracking gains a new 'stalled' state for requests that were never taken back

**Unclear.** It's unclear which user-facing feature consumes this 'stalled' status or how it's surfaced.

**What**

A status object used to track timed or capped operations in the remote/plumbing layer now marks a request as `open: "stalled"` when the request isn't a probe and hasn't been taken back, alongside the existing logic based on whether a request was taken back.

**Why**

This gives a clearer signal when an operation is stuck waiting rather than actively progressing, making it easier to distinguish a genuinely stalled request from one that's simply still open.

- Area: Remote Control
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Filename-basename indexing added to path search structure

Path search indexing now tracks each file's basename separately for faster/more accurate filename matches

**What**

The path-indexing structure used for search now records, for each path, where the last segment of the path (the filename itself, called the basename) starts, plus a separate marker of which lowercase letters appear within just that basename. This is in addition to the bitmask it already kept for letters across the whole path.

**Why**

Tracking the basename separately lets search narrow down matches based on the filename alone rather than the full path, which should make filename-focused searches faster and more precise.

- Area: File Search
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Skill-delivery prompt now conditions the save instructions on org settings

Claude now explains that saving a delivered skill file depends on org settings it can't see, and won't promise it will work

**What**

When Claude hands a skill file to the user through the file-send tool, rather than through the dedicated save or propose tool, the system prompt's 'Saving skills' instructions now tell Claude to explain that whether the user can then save it as a skill, from the file card or by uploading it, depends on their organization's settings, which Claude cannot see. Claude is also told never to instruct the user outright to save it.

**Why**

This keeps Claude from confidently telling a user to just save a delivered skill file when the ability to do so may be restricted by organization policy Claude has no visibility into, avoiding instructions that might not actually work for that user.

- Area: Skills
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Model-list telemetry now tracks a 'served overflow' and base/main picker mismatch separately

Model-list telemetry now separately tracks 'served overflow' counts and full picker-set mismatches

**What**

Internal telemetry that compares model capability lists now reports `picker_set_match`, `picker_added`, and `picker_removed` from a richer underlying object, and adds two new fields: `picker_full_match` and `served_overflow_count`. The detailed before/after picker payloads (`picker_old`/`picker_new`) are now only included when either the base or the full picker set doesn't match.

**Why**

This gives more precise internal visibility into when the list of models shown to users diverges from what's expected, and avoids sending the full payload for comparisons that already match, trimming unnecessary telemetry data.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Working-directory registration failures now carry a machine-readable error code

Working-directory registration failures now include a machine-readable error code alongside the human-readable reason

**What**

When registering a working directory fails (for example, for multi-repo or worktree features), the check now returns a `code` field, either `is_cwd` or `already_registered`, in addition to the existing human-readable `reason` text. Similarly, the helper that verifies a path is actually a directory now returns a `code` field (such as `not_directory`) alongside its human-readable reason when the check fails.

**Why**

A machine-readable code lets calling code branch on the specific failure reason programmatically, instead of having to parse or match against the human-readable text.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Bash tool pre-spawn failures can now report a structured error code

Failed Bash commands that never even started now report a structured preSpawnErrorCode

**What**

When the `Bash` tool can't even launch a command (a pre-spawn failure), it builds a synthetic failed result to report back. That result can now include an optional `preSpawnErrorCode`, in addition to the existing `preSpawnError` message text.

**Why**

A structured error code is easier to check and handle programmatically than parsing the error message text, which should make failures that happen before a command even runs easier to diagnose.

- Area: Bash Tool
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New file-scan skip reason: skipped_host_config

File-scanning now tracks a separate skip reason for files belonging to host_config

**What**

When Claude Code scans files and rules, it already kept counts of why certain files were skipped, such as `skipped_sensitive_tracked`, `skipped_read_denied`, and `skipped_rules_unreadable`. A new counter, `skipped_host_config`, has been added to track files skipped because they belong to `host_config`, which is organization-linked Claude Code configuration.

**Why**

This gives a more precise breakdown of scan results, so files tied to organization-managed configuration are counted separately instead of being lumped in with other skip reasons.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Hover style added to a selectable list component

A selectable list component now highlights the item under the cursor with a tint

**Unclear.** The finding does not say which specific list or menu in Claude Code uses this component.

**What**

An internal list component used for selectable menus now sets a `hoverStyle` of `"tint"` alongside its existing settings. When you hover over an item in one of these lists, it now gets a tint highlight.

**Why**

This makes it easier to see which item in a list you're currently pointed at while navigating menus in Claude Code.

- Area: UI Components
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Session/message pipeline now threads a fromPlugin flag

Inbound session messages can now carry a flag marking whether they came from a plugin

**Unclear.** The finding shows the flag being threaded through but does not say what behavior actually changes based on its value.

**What**

The internal code that classifies incoming session messages (the same code that already tracks things like grouping IDs, Slack origin, and activity tracking) now also takes in a `fromPlugin` value. This means messages can be tagged with whether they originated from a plugin, a package that extends Claude Code with extra capabilities.

**Why**

Tagging messages by their plugin origin lets Claude Code tell plugin-generated content apart from other message sources, which is a building block for handling plugin messages correctly elsewhere in the pipeline.

- Area: Messaging
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Bash-tool result field allowlist gains a new tool entry

The Bash tool's allowed result fields now include stdout, stderr, interrupted, and timedOutAfterMs

**Unclear.** It's not stated which tool identifier this new entry corresponds to, though the fields match a shell command's output.

**What**

Claude Code keeps an internal list, keyed by tool, of which result fields a tool is allowed to report (used for things like comparing or caching a tool's output). A new entry was added to this list for the Bash tool, allowing its results to carry `stdout`, `stderr`, `interrupted`, and `timedOutAfterMs`. Previously, the entries in this list only allowed a `structuredPatch` field, used by file-editing tools.

**Why**

This lets the system track a command's standard output, standard error, whether it was interrupted, and how long it ran before timing out, as recognized fields on Bash tool results.

- Area: Bash Tool
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Bash pre-spawn 'argument list too long' errors now get a distinct error kind

Claude Code now gives a distinct error type when a Bash command's argument list is too long to run

**What**

When Claude Code tries to run a command in the terminal (via its Bash tool) and the command fails before it even starts because its argument list is too long for the system to handle, that failure is now tagged with its own error kind, `spawn_arg_limit`, instead of being lumped in with generic startup failures.

**Why**

Giving this failure its own label makes it possible to recognize "argument list too long" errors specifically, rather than treating them the same as any other command startup problem.

- Area: Bash Tool
- Names: `spawn_arg_limit`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Git checkpoint env now derives from a pinned release, with graft-file fallback preserved

Git checkpoint environment variables now come from a pinned release, falling back to /dev/null only when needed

**What**

When Claude Code builds the environment variables used for git checkpoints, it now reads them from a pinned release's own environment first. The `GIT_GRAFT_FILE` variable (a git setting used to graft commit history) is only set to `/dev/null` if that pinned environment doesn't already provide a value. Previously, `/dev/null` was always used unconditionally.

**Why**

This lets the pinned release's own git configuration take precedence for checkpoint operations, while still falling back to the old safe default when nothing else specifies one.

- Area: Git Checkpoints
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### mcp_read_resource control requests now fast-pathed like generate_session_title

SDK calls that read MCP resources now get fast-tracked instead of waiting in the request queue

**What**

When a program using the Claude Code SDK sends a request to read a resource exposed by an MCP server (a connector that gives Claude access to external tools and data), that request is now handled immediately rather than waiting behind other in-flight control requests. This puts `mcp_read_resource` in the same fast-path category as the existing `generate_session_title` request.

**Why**

This avoids MCP resource reads getting stuck behind slower, unrelated queued requests, so SDK callers get a quicker response.

- Area: SDK
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New detection for misordered 'system' role messages in API errors

Claude Code now recognizes API errors about misplaced 'system' role messages and pinpoints the offending message

**Unclear.** What Claude Code does with the detected error or message index beyond parsing it is not stated.

**What**

Claude Code can now detect a specific class of API error: when the API complains that a `system` role message needs to come before or after other messages, or that the top-level `system` parameter should be used instead for the initial system prompt. A new parser extracts the index of the offending message from the error text when it's present.

**Why**

This allows Claude Code to recognize and potentially handle this error condition more precisely, since it can now identify exactly which message in the conversation caused the problem.

- Area: Error Handling
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### File-integrity check now distinguishes 'missing' from 'differs' from 'holds'

File-integrity checks now report whether a file is missing, differs, or matches, instead of just yes/no

**What**

A helper function that compares a file on disk against expected contents previously only returned true or false. It now returns one of three specific results: `holds` (the file matches), `differs` (the file exists but its size or content doesn't match), or `missing` (the file doesn't exist at all).

**Why**

This lets code that checks file integrity distinguish between a file being absent versus a file being present but changed, which are different situations that may need different handling.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### MCP server ownership lease released with a gap/cap backoff

MCP server ownership leases now release with a timed backoff instead of immediately

**Unclear.** The exact events that trigger this release, and the precise effect of the gap/cap values, are not detailed in the evidence.

**What**

Claude Code now releases an MCP server's ownership lease (a claim on managing that server's registration) using a backoff pattern with an 8000ms gap and a 60000ms cap, rather than releasing it immediately when certain events occur.

**Why**

Pacing how quickly ownership of an MCP server registration can be released and reclaimed likely helps avoid rapid churn or conflicts when multiple processes are involved.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Task/background command status gains an 'open' field distinguishing still-running vs unknown delivery

Background task status responses now include an 'open' field showing whether delivery of a still-running task is known or unknown

**What**

When checking the status of a background task or command, the `still_running` response now includes a new `open` field. It's set to `still_running` when the task's state is literally running, or `delivery_unknown` otherwise, in addition to the existing code, message, and host fields.

**Why**

This gives callers a clearer signal about whether a task's status is confidently known to still be running, versus a case where its delivery status can't be confirmed.

- Area: Background Tasks
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Windows-path safety check now returns a reason code instead of a boolean

Windows path-safety checks now report a specific reason instead of just true or false

**What**

The function that checks whether a file path is unsafe on the current platform now returns a specific reason code instead of a plain true/false. Possible reasons include `nt_device_namespace`, `colon_past_drive_position`, `tilde_digit`, `device_path_prefix`, `trailing_dot_or_whitespace`, `dos_device_suffix`, `dot_run_segment`, and `unc_or_webdav_form`.

**Why**

Knowing the specific reason a Windows path was flagged as unsafe, rather than just that it was, allows more precise handling or messaging around path validation, particularly for Windows-specific quirks like device namespaces and reserved path forms.

- Area: Windows
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Peer handback queued-command replay logic added

Claude Code can now replay queued commands handed back from a peer session

**Unclear.** The finding does not say what triggers a peer handback or how the replayed commands are used once collected.

**What**

A new internal function scans the messages that come after the most recent assistant reply and looks for queued commands that were attached as part of a "peer handback" (marked with `origin.kind === 'peer'` and `origin.handback === true`). Commands matching this pattern that haven't already been processed are collected so they can be replayed or restored.

This appears to relate to handing off work between linked sessions, where one session passes queued commands to another (a "peer") and those commands need to be picked back up.

**Why**

This should help make sure commands queued during a handoff between sessions aren't lost or dropped, restoring them so they still get executed after the handback.

- Area: Multi-Machine
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Settings-source enumeration now includes a 'classic' entry

Settings-source listings now include a 'classic' entry alongside each configuration namespace

**Unclear.** It's unclear what the 'classic' entry represents or how it affects settings behavior visible to a user.

**What**

An internal function that lists Claude Code's configuration namespaces (the different places settings can come from) now also adds a `classic` entry to that list, in addition to the per-namespace entries it already returned.

**Why**

The finding does not say what consumes this list or what effect the new `classic` entry has for someone using Claude Code, so its practical impact is unclear.

- Area: Settings
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Hook launcher exclusion now matches multiple launcher names

Backup/restore now skips multiple hook-launcher filenames instead of just one

**What**

The backup and restore code that skips over hook-launcher files (small helper programs that run hooks, which are scripts Claude Code can trigger at certain points) used to check for a single hardcoded filename, `ccr-launcher`. It now checks a file against a list of launcher names instead of just that one.

**Why**

By recognizing more than one launcher name, backup and restore operations correctly skip all known hook-launcher files rather than only the one named `ccr-launcher`, avoiding files being mishandled when a different launcher name is in use.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Queued command text can be rewritten/consumed per origin before dispatch

Queued commands can now be rewritten or dropped by a per-origin handler before they run

**Unclear.** The finding does not say which origins are recognized or what rewriting/consuming is used for in practice.

**What**

When Claude Code turns a forwarded message into a queued command, it now runs the command text through a per-origin handler before adding it to the queue. Depending on where the message came from, this handler can rewrite the command text or mark it as 'consumed', in which case it is dropped entirely and never reaches the queue.

**Why**

This gives Claude Code a place to adjust or filter queued commands based on their source before they get a chance to execute, rather than queuing everything unconditionally.

- Area: Message Queue
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Auto mode classifier now reports whether it actually ran

Auto mode's tool classifier now reports whether it actually ran

**What**

In Claude Code's auto mode, the internal classifier that decides how to handle a tool call now returns a `classifierRan` flag alongside its verdict, stating whether the classification step actually executed. The fallback logic used when the classifier refuses to answer or gives no verdict was reworked to use this new flag.

**Why**

This lets the fallback logic distinguish between the classifier running and abstaining versus not running at all, which should make auto mode's fallback behavior more accurate in edge cases.

- Area: Auto Mode
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Plugin metadata now tracks git commit SHA and Claude.ai server plugin ID

Plugin info now includes the git commit SHA and Claude.ai server plugin ID

**What**

When Claude Code resolves information about an installed plugin, it now also records the plugin's `gitCommitSha` and a `serverPluginId` (taken from a `claudeaiPluginId` field), subject to path-matching and an ID validity check.

**Why**

This lets Claude Code track which git commit and which Claude.ai server-side plugin record a locally installed plugin corresponds to.

- Area: Plugins
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Thinking-mode/thinking-display change detection added to status diffing

Status change detection now flags when thinking mode or its display setting changes

**What**

The internal helper that compares two status snapshots to see what changed now also reports `thinkingModeChanged` and `thinkingDisplayChanged`. These only trigger when a non-empty thinking mode was already set on both sides being compared.

**Why**

This lets other parts of Claude Code react specifically to changes in thinking mode or how thinking is displayed, rather than treating them as part of a generic status change.

- Area: Thinking Mode
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Chrome-extension action map slimmed to install/reconnect/permissions

Claude-in-Chrome extension's action list trimmed down to install, reconnect, and permissions

**Unclear.** The finding does not say whether the removed actions still exist elsewhere or were dropped from the extension entirely.

**What**

A dispatch table used for the Claude-in-Chrome browser extension previously listed many MCP-related actions, including checking MCP status, usage and session cost, listing models, getting the binary version, setting thinking token limits, and managing sessions and background tasks. At this call site, that list has been replaced with just three entries: `install`, `reconnect`, and a `permissions` URL.

**Why**

This narrows what this particular part of the Chrome extension integration can trigger, down to installing, reconnecting, and pointing to permissions, removing the broader set of MCP actions from this call site.

- Area: Claude in Chrome
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Session history entries get a sessionTail marker

Recent session history entries are now tagged with a sessionTail marker

**Unclear.** The finding does not say what consumes the sessionTail flag or how it changes behavior.

**What**

When Claude Code builds its list of recent sessions and paths, matched entries are now tagged with a `sessionTail: true` flag as they're added to the result list.

**Why**

This marks certain entries so other code can distinguish them within the session history list, though the finding does not specify how the marker is used afterward.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Permission stash now stores path spellings instead of raw path object

Read-permission stash now records a path's spellings instead of the full path object

**Unclear.** The finding does not explain what spellings contains or exactly how it changes matching behavior.

**What**

When Claude Code stashes a record of a file read for later permission-prompt matching, it now stores `g.spellings` (the different ways a path can be written) instead of the entire path object.

**Why**

Storing just the spellings rather than the full object likely makes deduplication and matching against future permission prompts more precise or lighter weight.

- Area: Permissions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### First-upload hook added to a sync/session config path

Session sync config gains a firstUpload hook for initial uploads

**Unclear.** The finding does not say what the firstUpload handler actually does.

**What**

The configuration object used when syncing or attaching a session, which already includes things like credentials, `allowBundle`, and `seedDirSync`, now also has a `firstUpload` field pointing to a named handler.

**Why**

This gives the sync process a dedicated hook to run specifically on the first upload of a session, separate from later uploads.

- Area: Session Sync
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### read-file helper signature simplified, admitPublicRead option dropped from destructuring

A low-level file-read helper's signature was simplified, dropping the admitPublicRead option

**Unclear.** Whether admitPublicRead handling still exists elsewhere or was fully removed is not stated.

**What**

An internal file-reading helper changed its parameter list from `(r, n, l, h, { admitPublicRead: i } = {})` to `(r, n, u, g, e = {})`. It no longer pulls out an `admitPublicRead` option at this point in the code.

**Why**

This is a signature cleanup; the finding does not say whether the `admitPublicRead` behavior moved elsewhere or was removed outright.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Direct-upload API gains a create-only / conflict mode

Direct-upload API gains a createOnly mode that reports a conflict instead of overwriting

**What**

The low-level direct-upload function used by directory sync now accepts a `createOnly` option, which defaults to false. When set and a remote download already exists at the target location, the function returns a `conflict` result instead of overwriting it.

**Why**

This lets callers opt into a safer create-only upload that won't silently overwrite existing remote content, surfacing a conflict instead.

- Area: Directory Sync
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Plugin autoupdate credential-helper flag removed; helper now always disabled during background refresh

Plugin autoupdate now always disables the git credential helper during background refresh

**What**

When Claude Code refreshes plugin marketplaces in the background, it always disables the git credential helper for that operation now. Previously this was controlled by a flag (`tengu_plugin_autoupdate_allow_credential_helper`) that could allow the helper to stay enabled; that flag and the surrounding conditional have been removed, so the helper is unconditionally disabled during background refresh.

**Why**

This removes a configurable exception, making background plugin marketplace updates behave the same way for everyone with respect to git credentials.

- Flag `tengu_plugin_autoupdate_allow_credential_helper`: Not enough to say (read for one account on one subscription tier against v2.1.280; this account: no value returned, anonymous baseline: no value returned, compiled default: not a boolean we can read) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: Plugins
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New narration_hint field controls VS Code narration-summary hint styling

New narration_hint field lets the VS Code extension style the 'summarized' hint on thinking blocks

**What**

Assistant message data can now include a `narration_hint` field set to `hidden` or `faint`. It tells a renderer how to display the trailing " · summarized" hint that appears on narration-summary thinking blocks (condensed summaries of Claude's reasoning). This field is sent only to the VS Code extension.

**Why**

This gives the VS Code extension finer control over how prominently it displays the summarized-thinking indicator.

- Area: VSCode Extension
- Names: `narration_hint`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New remote-control entrypoint detection helper

Remote-control session detection now recognizes a remote_trigger entrypoint

**What**

A helper that determines whether the current process is a remote-control session now checks that `CLAUDE_CODE_REMOTE` is truthy and that `CLAUDE_CODE_ENTRYPOINT` is one of `remote`, `remote_desktop`, `remote_mobile`, or `remote_trigger`.

**Why**

Adding `remote_trigger` as a recognized entrypoint lets Claude Code correctly identify that kind of session as remote-control, so its remote-specific behavior applies there too.

- Area: Remote Control
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New telemetry: remote_control_entry feature logging

Claude Code now logs telemetry around remote-control session entry and exit

**What**

Claude Code now calls a new logging helper, `logFeatureBadAsync`, with the feature name `remote_control_entry` and an outcome string such as `registration_failed` or `trusted_device_unenrolled`, around the points where a remote-control session begins and ends. This runs alongside the existing `flushAnalyticsBeforeExit` call.

**Why**

This gives visibility into how remote-control sessions start and fail, which can help diagnose issues like a device losing its trusted status or failing to register.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New credential-redacting URL formatter

New helper masks usernames and passwords embedded in URLs before display

**What**

Claude Code has a new function that formats URLs by replacing any embedded username and password with `***`. It handles both standard URLs with credentials and bare `user@host` forms.

**Why**

This keeps sensitive credentials that are embedded directly in a URL from being shown in logs or on screen in plain text.

- Area: Permissions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New 'running' status style added to status icon map

Status icon list gains a dedicated 'running' entry

**What**

The lookup table Claude Code uses to pick an icon for task or tool status now has a `running` entry, with its own icon and no set color, alongside the existing `info`, `pending`, and `loading` entries.

**Why**

This lets Claude Code visually distinguish a running task or tool from the other existing states rather than reusing one of their icons.

- Area: UI Components
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Task delegation now carries usage stats forward

Sub-task handoff now carries forward token, tool-use, and duration stats

**What**

When Claude Code spawns or hands off a sub-task to another agent, the payload sent now includes a `usage` object with `totalTokens`, `toolUses`, and `durationMs`, in addition to the existing `agentId`, `priority`, and `taskId` fields.

**Why**

This carries usage statistics along with a delegated task, making it possible to track token consumption, tool use, and time spent as work moves between agents.

- Area: Agent Tool
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New 'was stopped: <reason>' message variant

New 'was stopped: ' message variant added for turn-stopped cases

**Unclear.** The finding doesn't say what specific case triggers this new message variant.

**What**

The logic that produces a message when a turn is stopped gained a new variant, `was stopped: <reason>`, for a case separate from the existing Claude-stopped, user-stopped, and generic "was stopped" messages.

**Why**

This lets Claude Code report a more specific reason when a turn stops for this additional case, rather than falling back to a generic message.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Session-scoped model list now tags entries with sessionTail

Session-scoped models added to the available-model list are now tagged with sessionTail

**Unclear.** The finding doesn't say what behavior depends on the sessionTail tag or why the matching helper was swapped.

**What**

When a model gets appended to the list of available models, in both the plain string-value case and the custom-model case, the new entry is now tagged with `sessionTail: true`. The matching logic used to find existing entries also switched from one internal helper to another (`zr` in place of `Xv`).

**Why**

Tagging session-scoped model entries this way lets Claude Code distinguish models added for the current session from other entries in the list.

- Area: Models
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Fable consent tracking gains a session consent key

Fable's consent tracking now stores a per-session consent key alongside its existing fallback flag

**Unclear.** The finding does not say what Fable is or what user-facing effect, if any, this consent tracking has.

**What**

The internal component that tracks consent for Fable now keeps a `sessionConsentKey`, exposed through a new `sessionConsentKey()` method. It is reset at the same time as the existing consent fallback flag it already tracked.

**Why**

This is an internal bookkeeping change to how consent state is tracked per session; it does not describe a new setting or behavior a reader needs to act on.

- Area: Usage & Limits
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Git worktree telemetry gains private_layout field

Telemetry for pinned git worktree layouts now records a private_layout field

**Unclear.** The finding does not say what private_layout tracks or how it differs from work_tree_pinned.

**What**

When Claude Code records telemetry about a pinned git worktree layout (a setup where a project is checked out into a separate working directory pinned to it), the data it sends now includes a new `private_layout` true/false field, alongside the existing `work_tree_pinned` and `names_read` fields.

**Why**

This is an internal telemetry change with no visible effect on how Claude Code behaves day to day.

- Area: Git Worktrees
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Fuzzy file matcher gains name-based indexing

Claude Code's fuzzy file matcher now indexes file names separately from full paths

**Unclear.** Whether or how this changes the actual search results a user sees is not stated.

**What**

The internal system that powers fuzzy file search (finding files as you type a partial or approximate name) now builds extra lookup arrays for just the file name portion of each path, alongside the arrays it already kept for the full path. These new arrays are called `nameStarts`, `nameCharBits`, and `nameMatchPositions`, and they sit next to the existing `lowerPaths`, `charBits`, `pathLens`, and `matchPositions` arrays.

**Why**

Indexing file names on their own, separately from the full path, lets the matcher weigh or search a file's own name apart from the directories it lives in. The finding doesn't say exactly how this is used yet, only that the data structure now tracks it.

- Area: File Search
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Subagent spawn results can now report that the subagent shares the parent's working directory

Subagent launch results can now include a sharesCwd flag noting the subagent uses the parent's working directory

**Unclear.** The finding does not say what consumes this field or how a user would see its effect.

**What**

When Claude Code spawns a subagent (a separate agent instance handling part of a task), the internal result data for that launch can now include a `sharesCwd: true` field. A working directory (`cwd`) is the folder a process treats as its base location for file paths. This field appears in both the synchronous and asynchronous versions of the subagent-launch result.

**Why**

This lets the system record and distinguish cases where a subagent operates in the same working directory as the agent that launched it, rather than a separate one.

- Area: Agent Tool
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### MCP-required-missing agent spawn errors now carry structured data

Errors for missing required MCP servers during agent spawning now include structured error data, not just a text message

**What**

When a plugin's `agent.spawn` hook tries to launch an agent that needs one or more MCP servers (external tool integrations) that aren't configured, Claude Code throws an error. That error now carries structured metadata alongside its existing text message, including a `kind` field set to `mcp_required_missing` and a `servers` field listing which servers were missing.

**Why**

This makes it possible for tooling around Claude Code to detect and handle this specific failure programmatically, rather than having to parse the error's text message to figure out what went wrong and which servers need to be configured.

- Area: Plugins
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Subagent cancellation now distinguishes a permission-stop from a user cancel

Subagent shutdowns now tell apart a permission stop from a user cancel in cleanup and telemetry

**What**

When a synchronous subagent (a helper agent that Claude Code runs and waits on) is stopped because of a permission check, that stop is now tracked separately from a manual cancel by the user.

- The stop is now logged with reason `permission_stop_sync` in the `tengu_agent_tool_terminated` telemetry, instead of always being logged as `user_cancel_sync`.

- The resulting tool-result cleanup is now routed as system-authored rather than user-authored.

**Why**

Previously both cases were recorded the same way, as if the user had cancelled the subagent themselves. Separating them means logs and any downstream handling can correctly reflect that a permission rule, not the person, ended the subagent's run.

- Area: Agent Tool
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Self-hosted runner poll responses can now suggest a polling interval

Self-hosted runners can now be told by the server how often to poll for work

**Unclear.** The finding shows the value is read and stored but does not confirm exactly how it changes polling behavior.

**What**

When a self-hosted runner (a worker you run yourself that checks in with the server for tasks) polls for work, the server's response can now include a `suggested_poll_interval` field. The runner reads this value and stores it, and it appears to be used to pace how often the runner polls again afterward.

**Why**

This lets the server control how frequently a self-hosted runner checks in, rather than the runner polling on a fixed schedule regardless of conditions. It matters mainly to anyone operating self-hosted runners.

- Area: Self-Hosted Runner
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Revoked device-registration error now carries the refused public key

Errors for revoked device registrations now include the device's rejected public key

**What**

When Claude Code detects that a device's registration has been revoked (an internal state called `registration_revoked`), the error it throws now carries the device's public key. This key is included as `refusedPublicKey`, encoded as a base64 string in SPKI format (a standard way of representing public keys). Previously, this error carried no information about which key was refused.

**Why**

Including the actual refused key in the error makes it possible to identify or debug exactly which device registration was rejected, rather than just knowing that some revocation occurred.

- Area: Device Enrollment
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New withheld-file categories for the machine's own Claude Code config

Claude Code now withholds file writes that secretly point back at its own config, or that it can't fully check

**What**

Claude Code protects its own configuration files from being overwritten. This release adds two new reasons a file write can be blocked under that protection:

- The file you're writing to isn't obviously the Claude Code configuration, but actually resolves to it anyway, for example through a symlink (a file that's really just a pointer to another file).

- Claude Code couldn't fully check whether the target is its own configuration, because a link or directory involved couldn't be read, or because there were too many entries to check, so it withholds the write to be safe.

**Why**

This closes a gap where a write could reach Claude Code's own settings indirectly, and makes the tool err on the side of caution when it can't verify a file is safe to write, rather than risk silently corrupting its own configuration.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Skill/agent schema gains from_plugin field

An internal schema for skills and agents now has an optional from_plugin field

**Unclear.** It is unclear what from_plugin is used for or what user-visible behavior, if any, it enables.

**What**

A schema Claude Code uses internally to describe skill- and agent-like entities (packaged instructions and subagents that can be loaded and run) now includes an optional `from_plugin` field, alongside the existing `read`, `color`, and `summary` fields.

**Why**

The finding does not say what this field is used for, so it is not clear yet what it changes for someone using skills, agents, or plugins.

- Area: Skills
- Names: `from_plugin`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Plugin git-commit-SHA consistency lookup helper added

A new internal helper checks that every installed copy of a plugin points to the same git commit

**Unclear.** The finding does not say what feature or command actually calls this helper, so its user-facing effect is unclear.

**What**

Claude Code now has an internal helper that looks up all installed copies of a given plugin (optionally narrowed to a particular scope, such as a specific project or user setup). It compares the git commit each copy was installed from, and returns that commit only if every copy agrees. If the copies point to different commits, it returns nothing.

**Why**

Plugins can end up installed in more than one place, and this check lets Claude Code detect when those installs have drifted apart onto different versions instead of silently trusting a mismatched one.

- Area: Plugins
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New bridge tool event: bridge_work_pickup

Claude Code recognizes a new bridge tool event called bridge_work_pickup

**Unclear.** The finding does not say what triggers bridge_work_pickup or how it is surfaced to users.

**What**

The list of recognized event names for the bridge tool, which relays work between Claude Code and remote tooling, now includes a new event called `bridge_work_pickup`. This joins the existing `bridge_work_heartbeat` and `bridge_work_stop` events.

**Why**

This is an internal addition to how Claude Code tracks bridged work, so remote or background tasks can signal being picked up in addition to sending heartbeats or stopping.

- Area: Remote Tools
- Names: `bridge_work_pickup`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Auto-mode tool classification requires an explicit 'classifierAllowed' flag

Auto-mode tool classification now also requires an explicit classifierAllowed flag

**Unclear.** The finding does not say what changes for the user when a call fails this stricter check.

**What**

When Claude Code decides a tool call was picked automatically by its classifier (`auto-mode`), it now also checks a new `classifierAllowed` flag on the decision. This is in addition to the existing checks that the decision type is `classifier` and the classifier used was `auto-mode`.

**Why**

This tightens when a tool call is recognized as auto-classified, requiring an extra explicit signal before that classification is trusted.

- Area: Auto Mode
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Bash/tool dispatch now tracks a per-call 'offCriticalPath' status for MCP background calls

Tool dispatch now tracks whether an MCP call is off the main critical path

**What**

When Claude Code runs a tool call (including calls to MCP servers, which let Claude use external tools), it now computes an `offCriticalPath` flag. This flag is true when the call belongs to a background agent or a task that isn't part of the main flow of work. It's passed into the MCP call's watchdog (which monitors calls for problems) and into the logic that decides whether to run things in the background automatically.

**Why**

Knowing whether a call is off the critical path lets Claude Code treat background work differently from work the user is actively waiting on, which can affect scheduling and monitoring behavior.

- Area: MCP
- Names: `offCriticalPath`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New `spawn_arg_limit` diagnostic for E2BIG pre-spawn failures

Pre-spawn failures from argument-list-too-long are now tagged with a specific diagnostic

**What**

When Claude Code fails to start a process because the argument list is too long (an `E2BIG` error), it now tags the failure with `{ kind: "spawn_arg_limit" }` instead of throwing a generic pre-spawn error.

**Why**

This gives a clearer, specific reason when a command fails to launch because its arguments were too long, instead of a vague failure message.

- Area: Bash Tool
- Names: `spawn_arg_limit`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### macOS O_NOFOLLOW probing is now cached per-process

macOS symlink-safety probing is now cached instead of retried on every file open

**What**

On macOS, Claude Code opens files with a flag (`O_NOFOLLOW`) that prevents following symbolic links through the whole path, as a safety check. Previously it tried this on every single call and caught the error if the operating system rejected it. Now it remembers the result ('untried', 'works', or 'rejected') and skips retrying once it knows the flag is rejected by the current OS or filesystem.

**Why**

This avoids repeatedly attempting an operation known to fail, reducing unnecessary work on every file access on macOS.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Batch queue pendingCount now includes an 'urgent' sub-queue

Batch queue now has a separate 'urgent' lane counted in pending work

**What**

An internal batching queue used by Claude Code now has a separate 'urgent' lane alongside its normal pending queue. The count of pending items now includes both, so anything waiting in the urgent lane is counted as pending work too.

**Why**

This suggests certain queued work can now be prioritized ahead of the regular queue while still being tracked as outstanding work.

- Area: Message Queue
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New readsLinks field in agent generation record schema

New readsLinks field added to agent generation-tracking data

**Unclear.** The finding doesn't say what readsLinks represents or how it affects the comparison outcome.

**What**

A data structure used to track an agent's generation and sync state, which already had fields like `unshipped` and `basedOn`, now has an optional `readsLinks` boolean field. It's read to help decide provenance (where a piece of data came from) when comparing state between peers.

**Why**

This is an internal bookkeeping addition that helps Claude Code determine the origin of synced agent data more precisely.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Tool-announcement gating simplified: readsTranscriptRecord check dropped

Tool-announcement gating no longer requires a readsTranscriptRecord check

**What**

Claude Code processes 'name-only announcements' of tools (where only the tool's name is mentioned before full details are decided) based on a conversation state. The condition for processing these announcements previously required a `readsTranscriptRecord` flag to be set; that requirement has been dropped, so now only the `declaredToolsDecided` being false is checked.

**Why**

This simplifies the condition under which tool name announcements get processed, removing one of the two requirements that previously had to hold.

- Area: Tool Listing
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Extra retry condition added for extraBetas 400-error stripping

An extra condition now blocks retries when stripping a beta feature flag after a 400 error

**Unclear.** The finding doesn't say what the new check (Rrt) detects or what error cases it covers.

**What**

When a request fails with a 400 error and Claude Code considers removing a beta feature flag (`extraBetas`) and retrying, it now checks a second condition before deciding not to retry, in addition to the existing check.

**Why**

This adds another case where Claude Code will avoid retrying after this type of error, though the finding doesn't specify what that new condition detects.

- Area: Error Handling
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New 'forged' provenance check affects summary handling

Summary handling now also treats items with 'forged' provenance like already-summarized ones

**What**

A helper that decides how to treat a summary or text block now also returns true, meaning treat it the same as an already-summarized item, when the item's provenance (recorded origin) is `forged`. This joins existing checks used elsewhere to verify teammate messages.

**Why**

This lets Claude Code recognize and handle content marked as having 'forged' provenance consistently with content that's already been summarized, which matters for how teammate message verification is applied.

- Area: Teammates
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New artifact/frame URL matching regex

New regex matches artifact and frame links in text

**Unclear.** The finding doesn't say what uses this regex or what happens on a match.

**What**

Claude Code now has a regular expression that recognizes lines referencing artifact or frame links, such as "replacing: https://.../artifact/" or "source: .../frame/", matching either a UUID or a 22-character id.

**Why**

This lets Claude Code detect and act on these link patterns in text, though the finding doesn't say what happens once a match is found.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Teammates context wired into a permission/agent-related callback

Internal permission/agent callback now receives resolved teammates from team context

**Unclear.** The finding does not say what user-visible behavior this callback controls.

**What**

A callback related to permissions and agents now receives an added argument: the list of teammates resolved from the app's `teamContext`, passed alongside existing logic for whether permission prompts can be shown.

**Why**

This is internal plumbing. The evidence doesn't say what a reader would notice differently as a result.

- Area: Permissions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### tengu_bridge_placeholder_used_session event payload simplified

The tengu_bridge_placeholder_used_session telemetry event now sends no payload data

**What**

The `tengu_bridge_placeholder_used_session` telemetry event, which fires when a placeholder bridge session turns out to have been used and is swept away, now sends an empty payload instead of previously carrying a `v2: true` flag.

**Why**

This is an internal telemetry adjustment and isn't something a reader would notice while using Claude Code.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New telemetry: which plugin the hooks-worker heartbeat blames when wedged

Hooks-worker heartbeat failures now log which plugin is likely responsible

**What**

When the background worker that runs hooks (small scripts triggered by events) misses its heartbeat past a timeout, Claude Code now logs which plugin is most likely to blame, along with the evidence for that conclusion, before declaring the worker wedged (stuck).

**Why**

This makes it easier to diagnose which plugin caused the hooks worker to hang, instead of only knowing that something went wrong.

- Area: Hooks
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Background shell tasks now record which shell ran them

Background shell task records now note which shell executed the command

**What**

Records for background shell tasks (`local_bash`) now include a `shell` field naming which shell, such as bash or zsh, actually ran the command.

**Why**

This gives more precise bookkeeping about how a backgrounded command was executed, which can help when a command behaves differently depending on the shell.

- Area: Bash Tool
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Killed shell commands can now be flagged as having no real exit status

Force-killed shell commands are now flagged as having no real exit status

**What**

When a shell command has to be force-killed via a fallback escalation (sending `SIGKILL` after a normal stop attempt fails), its result now carries a `noExitStatus` field marking that the reported exit code isn't a genuine one reported by the process, but an inferred stand-in.

**Why**

This lets anything reading the result tell apart a command that actually reported its own exit code from one that was forcibly terminated, avoiding misleading conclusions drawn from a fake exit status.

- Area: Bash Tool
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Telemetry batching gains a dedicated 'urgent' queue drain

Telemetry batching gets a separate 'urgent' queue that drains independently

**What**

The internal telemetry event-batching system now keeps a separate `urgent` queue alongside its regular pending-events queue, with a new `takeUrgent()` method to drain it up to the usual batch-size and byte limits. The count of pending events now sums both queues when the batcher isn't closed.

**Why**

This lets certain telemetry events be sent with priority ahead of the regular batch, rather than being flushed in the same order as everything else.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Linked worktrees without a private admin dir are now refused at the git-exec layer

Uploading a linked git worktree without a private admin dir now fails immediately instead of running git

**What**

The hardened internal wrapper for running git commands during teleport bundle uploads now short-circuits to an immediate failure (empty output, exit code 126) when it detects a linked git worktree that doesn't yet have its private admin directory set up, rather than attempting to run git against it.

**Why**

This avoids running git commands against a linked worktree that isn't in a state where they could succeed, failing fast and predictably instead of producing a confusing error from git itself.

- Area: Git Worktrees
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New plugin-version telemetry field

Telemetry now records a plugin's marketplace version SHA when applicable

**What**

A new helper attaches a `plugin_version_sha` field to telemetry events whenever a plugin's source resolves to an entry in a marketplace, computed from that plugin's marketplace commit SHA.

**Why**

This lets telemetry distinguish which specific version of a marketplace plugin was involved in an event, useful for tracking issues tied to a particular plugin release.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Cross-session notify tracks whether a message originated from a plugin hook

Cross-session direct messages now record whether they came from a plugin hook

**What**

When the `send_message` tool sends a direct message to another agent, it now passes along whether the send was triggered by a plugin hook (`fromPlugin: r.hookCaller`), so the storage layer knows the message's origin.

**Why**

This lets Claude Code distinguish messages sent by a plugin's automated hook from ones sent directly, which could matter for filtering, auditing, or displaying message origin.

- Area: Messaging
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New 'host_config' refusal reason for restricted file reads

File-read refusals get a distinct 'host_config' reason instead of being lumped with others

**What**

When Claude Code refuses to read a file, it can now classify the refusal with a specific reason, `host_config`, instead of bucketing that case together with `read_denied` or `not_regular_file` as before. This reason is now also included among the refusal reasons treated as sensitive or blocked reads.

**Why**

Giving host-configuration-related refusals their own distinct category makes it possible to handle and report them differently from other kinds of denied file reads.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New unserved-layout git detection cases

Two new repo-layout cases are now recognized as unserved layouts

**What**

Claude Code's classification of git repository layouts that it can't properly serve now includes two additional cases, `git_in_reach` and `reach_unexamined`. Both are mapped to the existing `unserved_layout` category, joining previously recognized cases like submodules, custom git directories, and temp roots.

**Why**

This lets Claude Code correctly flag more kinds of repository layouts it can't fully work with, instead of treating them as unrecognized or mishandling them silently.

- Area: Git Integration
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Session-memory lock replaces cache-replace call

Session memory now uses an explicit lock instead of a cache-replace call

**Unclear.** The finding does not say what user-visible behavior, if any, this affects.

**What**

A session-memory function that previously called `replaceSessionCache` now instead acquires a lock via `.acquire()`, with a paired function releasing it via `.release()` at the appropriate point.

**Why**

Using an explicit lock instead of a cache-replace call helps prevent race conditions around session memory, making concurrent access to session state safer.

- Area: Sessions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New Windows path-spelling security check for network file reads

New Windows path-spelling check flags suspicious network file paths

**What**

When Claude Code checks permission to read a file from a trusted network directory on Windows, it now distinguishes a specific rejection reason called `suspicious_windows_spelling`, which carries the exact spelling variant of the path that triggered it. Previously this situation would have produced only a single generic rejection reason.

**Why**

A more specific rejection reason makes it clearer why a network file read was blocked, which should help in diagnosing cases where a path's spelling looks suspicious on Windows.

- Area: Windows
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New telemetry for skills-sync wait timeouts

New telemetry fires when waiting for skills to sync times out

**What**

A new helper races the process of listing available skills against a deadline. If the listing doesn't finish before that deadline, Claude Code now fires a telemetry event and reports the outcome as `timed_out` instead of `listed`.

**Why**

This gives visibility into cases where skills listing is slow enough to time out, which should help identify and diagnose delays in skills syncing.

- Area: Skills
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Login/onboarding flow reports whether the account picker is still 'fresh'

Login screen can now report whether the account picker is still untouched

**What**

The OAuth login component now accepts an `onFreshPickerChange` callback. It's called whenever the component's internal state settles back to idle without the user having progressed through login or setup, signaling to a parent component that the account picker hasn't been interacted with yet.

**Why**

This lets other parts of the login and onboarding flow know whether the account picker is still in its original, untouched state, which they can use to decide how to behave.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Plugin hooks loading drops the 'guardHeldByAdmin' admin-hold check

Plugin hooks loading no longer checks an admin-hold guard

**Unclear.** It's unclear what effect removing the guardHeldByAdmin check has on plugin hook loading behavior in practice.

**What**

When Claude Code filters which plugin hooks to load, the options it passes no longer include a `guardHeldByAdmin` field, which was previously computed via a helper function. The filter now only considers `hooksDisabled`, `managedOnly`, `allDisabled`, and `builtinsOnly`.

**Why**

Removing this check changes what conditions can affect whether plugin hooks load, though the finding doesn't specify the practical effect of dropping the admin-hold check.

- Area: Hooks
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Session journal publish no longer sends userEventUuids

Session journal publishing no longer includes userEventUuids

**Unclear.** It's unclear what practical effect removing userEventUuids from the journal payload has on session sync.

**What**

The internal function that encodes and publishes a session journal, used for syncing sessions across machines, no longer takes a `userEventUuids` parameter and no longer includes it in the encoded journal payload it sends.

**Why**

The finding doesn't specify why this field was dropped or what effect its absence has on session sync.

- Area: Session Sync
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New 'safety_monitor_blocked' recognized as a refusal condition

A new 'safety_monitor_blocked' API error is now treated as a refusal

**What**

The internal check that decides whether an API response counts as a refusal now also treats an API error of `safety_monitor_blocked` as a refusal, alongside the existing checks for a `refusal` stop reason and `dlp_request_denied`.

**Why**

This means responses blocked by a safety monitor are now handled the same way as other refusals, rather than being treated as some other kind of error.

- Area: Permissions
- Names: `safety_monitor_blocked`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact error-nagging exclusion list gains policy_fetch_failed / policy_route_missing

Artifact tool no longer nags about repeated calls that failed due to policy_fetch_failed or policy_route_missing

**Unclear.** placeholder

**What

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Outbound message queue gains an 'urgent' priority lane and backoff-owed tracking

Claude Code's outbound message queue now has a separate 'urgent' lane and tracks backoff time owed

**Unclear.** The finding does not say what determines whether a message is 'urgent' or how backoffOwedUntil affects retry timing.

**What**

Claude Code sends events (like usage and telemetry data) to Anthropic through an internal queue that retries failed sends. That queue now keeps two separate lists: the existing 'pending' list and a new 'urgent' list. The queue only considers itself fully drained once both lists are empty, and when draining finishes it resets a new internal timestamp called `backoffOwedUntil`.

**Why**

This is an internal change to how Claude Code manages retrying failed outbound sends. Separating out an 'urgent' lane suggests some messages can now be prioritized ahead of others, and tracking a backoff timestamp helps the queue know when it's still supposed to be waiting before retrying, rather than firing off retries too eagerly. Users are unlikely to notice this directly.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Remote permission-mode changes now tag their origin (person vs worker)

Remote permission-mode changes now record whether the person or the remote worker made the change

**Unclear.** The finding says this likely avoids echoing the user's own change back to them, but doesn't confirm what the tracking is used for.

**What**

When using Claude Code remotely, permission mode (the setting that controls how much Claude can do without asking first) can change from either side of the connection: the person, or the remote worker process. The code that handles these changes, `onPermissionModeChange`, now takes an origin value that says which side made the change. New tracking methods, `noteOwnPermissionModePush` and `noteOwnPermissionModeAnswer`, record permission-mode changes that were initiated locally.

**Why**

This is internal bookkeeping, but it likely keeps the interface from showing a confusing echo, such as displaying a permission-mode change back to the person who just made it themselves.

- Area: Permissions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### dialog-bridge local-only refusal fallback path reworked

Claude Code's fallback dialog for local-only refusals now goes through a different internal function with an explicit local-only flag

**Unclear.** Whether this internal rework changes anything a user would notice, or is purely a behind-the-scenes refactor, is not established by the evidence.

**What**

When Claude Code shows a fallback dialog after a refusal and no bridge (a connection to an external dialog handler) is available, it now routes that request through a different internal function than before, and explicitly passes a `localOnly: true` option that this code path did not pass previously.

**Why**

This is an internal plumbing change to how the local-only refusal fallback dialog is triggered. The finding does not say what user-visible behavior, if any, changes as a result.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Git operations now disable commitGraph and multiPackIndex

Git commands run by Claude Code now disable commitGraph and multiPackIndex

**What**

When Claude Code runs git commands internally, it now always adds `-c core.commitGraph=false -c core.multiPackIndex=false` to the invocation, on top of the flags it already appended.

**Why**

This turns off two git performance features (the commit-graph and multi-pack-index caches) for git operations Claude Code performs, which most likely avoids issues with stale or inconsistent caches during automated git operations.

- Area: Git Integration
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### 'hasPendingPrompt' replaces separate permission/user-dialog empty checks for idle-state notification

Idle-state notifications now use a single 'pending prompt' check instead of two separate ones

**Unclear.** The finding does not say what the new `promptLeftStanding` guard does beyond being part of this check.

**What**

The internal logic that decides whether to fire an idle/running state-change notification for a session used to separately check whether there were pending permission requests and pending user-dialog requests. It now uses one combined check called `hasPendingPrompt()`, along with a new `promptLeftStanding` guard.

**Why**

This is an internal consolidation of how Claude Code detects that a session is genuinely idle versus still waiting on the user, which should make idle notifications more consistent.

- Area: Terminal UI
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Rate-limit tracker exposes a public 'usage limit wait' signal

Internal rate-limit tracker gains a way to signal and observe 'waiting on usage limit' state

**What**

The internal component that tracks API rate-limit status gained two new methods, `beginUsageLimitWait()` and `emitUsageLimitWaitsChanged()`, letting other parts of Claude Code register that they are waiting on a usage limit and be notified when the set of things waiting changes.

**Why**

This is plumbing for coordinating behavior when Claude Code is waiting on a usage limit, though the finding doesn't specify what visibly changes for users as a result.

- Area: Rate Limits
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### plugin_suggest telemetry now records the trigger reason

Plugin-suggestion telemetry now records whether the suggestion was proactive or user-requested

**What**

The `plugin_suggest` telemetry event now includes a `trigger` field, recording whether a plugin suggestion was made proactively by Claude or in response to the user asking, mirroring the new `trigger` field added to the suggestion card itself.

**Why**

This lets plugin-suggestion behavior be analyzed by how the suggestion was triggered.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Denied path reason now carries a machine-readable code

Denied-path errors now include a machine-readable 'outside_scope' code

**What**

When Claude Code denies access to a file path because it falls outside the allowed scope, the denial object now includes a `code` field set to `"outside_scope"`, alongside the existing human-readable reason text.

**Why**

This makes it possible for tooling to programmatically detect this specific denial reason instead of having to parse the human-readable message.

- Area: Permissions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New coordinator notification kind alongside peer

A new 'coordinator' message kind joins 'peer' for notifications, both able to carry a plugin identifier

**Unclear.** The finding does not say what a coordinator is in this context or what triggers a coordinator-kind message.

**What**

A message-kind resolver that used to special-case only the `peer` kind now also handles a `coordinator` kind. Like `peer`, a `coordinator` message can carry an optional plugin identifier through to the resulting notification object.

**Why**

This lets notifications distinguish messages coming from a coordinator role, not just from peers, while still preserving which plugin the message relates to.

- Area: Terminal UI
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Plugin listing result now carries a trigger field

Plugin listing results now include a 'trigger' field alongside label, plugins, note, and counts

**Unclear.** The finding does not say what the trigger field represents or how it is consumed after being returned.

**What**

The function that builds a summary of a plugin or marketplace listing now returns a `trigger` field in its result, in addition to the existing `contextLabel`, `plugins`, `note`, and count fields.

**Why**

Carrying the trigger value through the listing result lets whatever consumes it know what prompted the listing, though the finding does not specify how it is used downstream.

- Area: Plugins
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Retry/backoff delay schedule introduced as explicit constant

A new explicit delay schedule (500ms to 60s) was added, likely for retries or reconnection

**Unclear.** The finding does not say which request or reconnection flow uses this schedule.

**What**

A new constant defines a schedule of delays in milliseconds: 500, 1500, 4000, 15000, and 60000. This looks like a backoff schedule used to space out repeated attempts, such as retrying a request or reconnecting.

**Why**

Having this as a named, standalone schedule suggests some retry or reconnection flow now waits progressively longer between attempts rather than retrying at a fixed or unspecified interval.

- Area: Internals
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New session-ingress/oauth token path constant

New internal constant bundles session-ingress and OAuth token file path resolution

**Unclear.** The finding does not say what sessionIngressTokenPath or oauthTokenPath are used for, or what problem this addresses.

**What**

A new object bundles a `sessionIngressTokenPath` and an `oauthTokenPath` together, along with a small helper that tests a value against a regular expression. This points to new or reorganized logic for locating token files used in cloud or session authentication.

**Why**

Grouping these paths together suggests the token-resolution logic for session ingress and OAuth was consolidated or newly introduced, though the finding does not describe the effect for users.

- Area: Auth
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Remote-tool approval calls now track a 'given up' state with more granular telemetry

Remote tool approval requests that time out now track a 'given up' state with detailed per-stage timing telemetry

**What**

When a remote tool call's approval request is abandoned because nothing responded in time, this is now explicitly recorded. New telemetry captures which input fields described the call, whether it was on the approval leg, and the dispatch epoch. New counters break timing down by stage: `queue_ms`, `post_ms`, `reply_wait_ms`, `total_ms`, the number of posts per leg, `ask_seat_wait_ms`, and `sent_without_ask_seat`.

**Why**

This gives much finer visibility into where a remote tool approval request stalls or gets abandoned, which should help diagnose slow or failed approvals for remote tool calls.

- Area: Remote Tools
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Speculative permission evaluation parameter threaded into tool call checks

Tool call permission checks now take a 'speculation' flag passed into the underlying rule evaluation

**Unclear.** The finding does not say what the speculation argument changes about the permission decision or when it is set.

**What**

The core function that decides whether a tool call is permitted now accepts a `speculation` argument, which is passed down into the classifier and host-allow-rule check that ultimately makes the decision.

**Why**

This lets permission decisions be evaluated speculatively, though the finding does not describe what changes about the decision or its outcome when speculation is set.

- Area: Permissions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Backpressure controller gains a separate 'urgent' queue

Backpressure message queue now has a separate 'urgent' lane alongside the normal pending queue

**Unclear.** The finding does not say what makes a message urgent or how the urgent queue is prioritized differently from pending.

**What**

The controller that manages backpressure and message withdrawal now tracks a second, `urgent` queue in addition to the existing `pending` queue. Withdrawing a message filters both queues, and closing the controller folds both into its in-flight and undelivered accounting.

**Why**

Separating urgent messages into their own queue suggests they can now be tracked and handled distinctly from ordinary pending messages, for example so they are not delayed behind normal traffic.

- Area: Message Queue
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Device binder enrollment now explicitly rejects BYOC and bridge environments

Device binder enrollment now explicitly refuses to proceed in BYOC and bridge environments

**Unclear.** The finding does not say what confirmReenroll controls or when it is set.

**What**

The function that prepares device binder enrollment now checks the kind of environment it's running in and refuses with an `environment` reason if that kind is `byoc` (bring your own cloud) or `bridge`. This is on top of its existing endpoint, pool, and correlation checks. It also now passes along a `confirmReenroll` flag.

**Why**

This prevents device binder enrollment from being attempted in environments where it isn't meant to run, giving a clear, specific reason instead of failing some other way.

- Area: Device Enrollment
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New telemetry: mcp_inline_tools, remote_control_entry, plugin_version_sha

Three new telemetry identifiers added: mcp_inline_tools, remote_control_entry, and plugin_version_sha

**Unclear.** The finding does not say what specifically each event or field records or when it fires.

**What**

Three new names were added to the known-telemetry allowlist:

- `mcp_inline_tools`, an MCP-related event

- `remote_control_entry`, a remote-control event

- `plugin_version_sha`, a redaction field

**Why**

Adding these to the allowlist means telemetry involving MCP inline tools, remote control entries, and plugin version hashes can now be recorded and handled properly (including redaction for the sha field), rather than being blocked or unrecognized.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Background task output tracking handles unlinked files as 'gone'

Background task output tracking now detects deleted-but-open files and reports them as 'gone' instead of erroring

**What**

When reading output from a background task, the code checks whether the file it's reading is still the same file it started with. It now specifically detects the case where the file has been deleted (link count of zero) while still open by its file descriptor, and reports a new `gone` status for that case instead of treating it as a generic identity-mismatch error.

**Why**

This gives a clearer, more accurate signal when a background task's output file has been deleted out from under it, rather than surfacing it as a confusing mismatch error.

- Area: Background Tasks
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Single-page artifact response now includes version/co-authoring metadata

Single-page artifact responses now include version, co-authoring, and type-locked info

**What**

When an artifact consists of a single page with no separately published files, the response to a file-list request (which previously just noted there's no file list to return) now also includes the artifact's `ver` (version), `cowritten`, and `typeLocked` fields.

**Why**

This gives more context about a single-page artifact directly in the file-list response, such as its version and whether it was co-authored or has its type locked, without needing a separate request.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### --configure-git hooksPath override simplified

The internal helper that sets git's core.hooksPath for --configure-git sessions was simplified, dropping symlink resolution

**What**

`--configure-git` sets up session-scoped git configuration, including an override for `core.hooksPath` (the setting that tells git where to look for hook scripts). The internal code that computes this override used to resolve symlinks; it now simply returns the configured `hooksPath` directly, or falls back to `/dev/null` if none is set.

**Why**

This is an internal simplification to how the hooks path override is computed. It should not change behavior for typical setups, but it removes the symlink-resolution step from the path.

- Area: Self-Hosted Runner
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New system-prompt section on where an Artifact page should keep its state

Artifacts system prompt adds guidance on where a page should keep its state and requires a functional check before handoff

**What**

The system prompt used when Claude builds Artifacts (self-contained pages Claude can generate and preview) gained two new sections:

- '## Where a page keeps its state' explains the choice between browser storage, the `artifact` capability, and the `db` capability for storing a page's data.

- '## Verify before you hand over the link' requires Claude to do one functional pass, previewing the page and checking any `db`/list and endpoint behavior, before handing over an Artifact that declares capabilities.

**Why**

This gives Claude clearer rules for choosing where an Artifact stores its data, and requires an actual check that the page works before it's handed to the user, catching broken Artifacts before the user sees them.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Model-effort resolution simplified, dropping 'honorLaunchPin' override option

Internal effort-resolution logic for model calls dropped its 'honorLaunchPin' override option

**Unclear.** Whether this changes any user-visible model effort behavior is not stated.

**What**

The internal function that resolves how much reasoning/turn effort a model call should use no longer accepts or checks a `honorLaunchPin` option or its associated launch-pin check. Effort is now resolved more directly, falling through from a hook-provided effort value, the current default, `turnEffort`, or a passed-in default.

**Why**

This is an internal simplification of effort resolution; the finding does not say what user-visible behavior, if any, this changes.

- Area: Effort
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New massDeleteHoldExposure helper for multi-store memory

New internal massDeleteHoldExposure helper computes exposure across shared and user memory stores during mass deletes

**Unclear.** What 'hold exposure' means for the user or how it affects a mass-delete outcome is not stated.

**What**

A new method on the memory-store manager, `massDeleteHoldExposure`, computes 'hold exposure' across both the shared multi-store and the user multi-store when a mass-delete of memory is requested, delegating the actual computation to a helper.

**Why**

The finding does not say what user-facing effect this has; it appears to be internal plumbing supporting mass-delete operations on stored memory.

- Area: Memory
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### HIPAA compliance-taint handling reworked in the restriction gate

HIPAA compliance restrictions are now checked separately against server-populated feature restrictions, instead of being folded in with generic hints

**Unclear.** What practical difference this makes for an account with HIPAA compliance settings is not stated.

**What**

The internal restriction-gate logic now special-cases the 'hipaa' compliance taint, checking it against server-populated feature restrictions rather than treating it like other generic compliance hints/taints.

**Why**

This changes how HIPAA-related restrictions are enforced internally, separating them from generic compliance handling so they're checked against server-configured feature restrictions specifically.

- Area: Compliance
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New env-derived telemetry flag: CLAUDE_CODE_HOST_SCHEDULED_RUN

Session telemetry now records whether a run was started by a host via a new CLAUDE_CODE_HOST_SCHEDULED_RUN environment variable

**What**

When a session starts, telemetry now records a boolean flag derived from a new environment variable, `CLAUDE_CODE_HOST_SCHEDULED_RUN`, indicating whether the run was scheduled by a host.

**Why**

This lets Claude Code distinguish host-scheduled runs from other session starts in telemetry.

- Area: Telemetry
- Names: `CLAUDE_CODE_HOST_SCHEDULED_RUN`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### toolDenialEndsTurn now propagated through tool result plumbing

A new toolDenialEndsTurn field can now make a denied tool call end the current turn

**Unclear.** Which denials set toolDenialEndsTurn, and what a reader would observe as a result, is not stated.

**What**

Tool-result messages now carry a `toolDenialEndsTurn` field alongside the existing `toolDenialKind` and `userFeedback` fields. When set, it's checked to short-circuit processing so a denied tool call ends the current turn.

**Why**

This gives Claude Code a way for certain tool denials to end the turn immediately rather than continuing, though the finding doesn't specify which denials trigger it.

- Area: Permissions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Hardened git exec now forwards caller-supplied config pins

Hardened git execution now lets callers inject their own git config environment variables via configPins

**What**

When Claude Code runs git with hardened settings, the environment variables now include any caller-supplied `configPins` in addition to the fixed `GIT_DEFAULT_REF_FORMAT` setting, letting callers inject their own git config environment variables ahead of the fixed one.

**Why**

This lets other parts of Claude Code customize git's configuration for a hardened git call without having to work around the previously fixed environment.

- Area: Git Integration
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Cloud directory sync gains a reread list parameter

claude --cloud directory sync gains a new 'reread' parameter for its container-snapshot sync

**Unclear.** What the reread parameter causes to happen during cloud directory sync is not stated.

**What**

The function that syncs a container snapshot's directory for `claude --cloud` now accepts a new `reread` parameter, defaulting to an empty list, alongside its existing options.

**Why**

The finding does not say what `reread` does functionally for a `--cloud` session; it appears to add a new input to the sync process.

- Area: Cloud Sync
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New outcome reasons added to upload/queue and remote-tools enums

Three internal telemetry enums gained new outcome values: lane_full, created_empty_unfilled, and remote_tools_reannounce

**What**

Three internal enums used for telemetry gained new members:

- an upload/lane outcome list gained `lane_full`

- a seeding/engine outcome list gained `created_empty_unfilled`

- the remote-tools telemetry type list gained `remote_tools_reannounce`

**Why**

These add new recordable outcomes for upload/queue handling and remote tools, letting telemetry capture cases that previously had no matching label.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### GetTask silently dropped from the worker-tools description list

The GetTask tool is now always excluded from the tools list described to spawned worker agents

**What**

The list of tools whose descriptions are shown to spawned worker agents (subagents that Claude Code hands work off to) now runs through a helper function before including `GetTask`. That helper is hard-coded to always return false, so `GetTask` is unconditionally left out of the worker tools description text, regardless of any other setting.

**Why**

Workers no longer see a description of `GetTask` in their available-tools context, which means they won't know to use it even if it would otherwise be applicable. Since the helper is hard-coded rather than conditional on real state, this exclusion applies to every worker in every session.

- Area: Agent Tool
- Names: `GetTask`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Plugin removal now detects same-named plugins across other scopes

Plugin removal now warns if another installed plugin shares the same name in a different scope

**What**

When removing a plugin that's scoped to a specific marketplace, Claude Code now checks whether another still-installed plugin, in a different scope, has the same name (ignoring capitalization). If so, that plugin's ID is included in the removal result as a `sharedDataDirPluginIds` entry.

**Why**

This appears to warn that deleting one plugin's files could also affect a differently-scoped plugin that shares its name, helping avoid accidentally breaking a plugin you didn't mean to touch.

- Area: Plugins
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Directory sync adds a 'reach_unexamined' refusal reason

Directory sync adds a 'reach_unexamined' reason for refusing to run git on an unreadable writable directory

**What**

When Claude Code resolves git configuration inside a synced checkout, it can now refuse to run git for a new specific reason: `reach_unexamined`, used when a writable directory reached through the checkout couldn't be examined. This is separate from the existing generic refusal reasons for unread or undigested paths.

**Why**

Giving this case its own distinct reason makes it clearer, when git is refused, whether the cause was an unreachable/unexamined directory versus other existing refusal conditions.

- Area: Directory Sync
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Edit/NotebookEdit checkPermissions runs an extra path check after the base decision

Edit and NotebookEdit permission checks now run an extra path check that can override an allow or ask decision

**What**

When Claude Code decides whether it has permission to run an `Edit` or `NotebookEdit` tool call, it used to return that decision directly. Now it only short-circuits immediately when the decision is an explicit deny; otherwise, it runs an additional check against stored path and spelling information, which can override what would have been an allow or ask decision.

**Why**

This adds an extra safeguard on top of the base permission decision, catching cases based on path details that the initial allow/ask decision alone wouldn't account for.

- Area: Permissions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Bash tool validateInput gets an added asynchronous host-side check

Bash tool input validation adds a second, host-side asynchronous check after the existing one

**What**

When Claude Code validates a `Bash` command before running it, it now runs an additional asynchronous check tied to the session's host, on top of the existing validation check. If this new check doesn't return a specific result, validation falls back to allowing the command as before.

**Why**

This adds another layer of validation for bash commands, letting host-specific context factor into whether a command is allowed to run.

- Area: Bash Tool
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Compaction guidance text now conditions the workshop/scratchpad/memory-tool caveat on a dream/consolidate context flag

Internal rename in the compaction prompt text that warns memory/workshop tools are unavailable during a 'dream'

**What**

The prompt text used during Claude Code's consolidation phase, which warns that certain memory, workshop, and scratchpad tools are unavailable during a 'dream', now checks a differently-named internal variable to decide whether to include that warning. The internal names used to build the warning's wording were also renamed, and a harmless empty-string addition was made to the text.

**Why**

This looks like an internal code cleanup rather than a behavior change; the same warning is shown under the same condition, just tracked and assembled under renamed variables.

- Area: Compaction
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New device-binding refusal reason: session's environment is not Anthropic-cloud

Cloud session device-binding adds a new refusal reason for sessions outside an Anthropic cloud environment

**Unclear.** Whether the `tengu_device_bind_skipped` gate is on for any account is unread, so it's unclear how this reading applies in practice.

**What**

When Claude Code tries to bind a cloud session to a device, it now explicitly refuses sessions of type `byoc` (bring-your-own-cloud) and `bridge` with a new reason: the session's environment isn't an Anthropic cloud environment. This joins the existing `pool`, `correlation`, and `endpoint` refusal reasons, is used to render the failure message shown to the user, and is logged with `reason: "environment"` in telemetry.

**Why**

This makes it explicit, rather than silent or ambiguous, when device binding fails because the session isn't running in an Anthropic-managed cloud environment.

- Area: Device Binding
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New skill-saving guidance for organization-gated saving

Claude now avoids explicitly telling users to save a generated file as a skill, since that depends on org settings it can't see

**What**

A new piece of guidance was added covering situations where Claude produces a file the user might want to save as a skill (a saved, reusable capability). It explains that whether the user is actually able to save it — either from the file card in the interface or by uploading it themselves — depends on organization-level settings that Claude cannot see. As a result, Claude is instructed to never tell the user outright to save it, whether in its reply text or in a caption.

**Why**

This avoids Claude confidently pointing users toward a save action that might not actually be available to them under their organization's settings, which would otherwise be confusing or misleading.

- Area: Skills
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Model picker now reads session/settings effort state

The model picker now factors in session and settings effort levels when preselecting a model

**What**

The component that lets you pick a model now looks at `sessionEffort` and `settingsEffortTable` from app state, in addition to the existing `ultracode` flag, when deciding which model option should be preselected.

**Why**

This keeps the preselected model in the picker consistent with the effort level set for the current session or in your settings, instead of only reacting to the `ultracode` flag.

- Area: Models
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Journal encoding no longer carries forward userEventUuids on laptop side

Laptop-side journal entries for live collaboration no longer carry forward userEventUuids

**Unclear.** The finding does not say what depended on the carried-forward userEventUuids or what problem dropping them fixes.

**What**

The `encodeLaptop` function, which builds a journal entry for live collaboration, used to copy over the passed-in `userEventUuids` array. It now always writes an empty array instead.

**Why**

This stops old event identifiers from being carried forward into new journal entries on the laptop side of live collaboration sessions.

- Area: Session Sync
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Live-collaboration replica state gains an 'unanswered' bucket

Live-collaboration replica tracking adds a new 'unanswered' bucket

**What**

The internal state that tracks live-collaboration replicas now includes an `unanswered` map, alongside the existing `replicas`, `unavailable`, `tooOld`, and `opening` buckets. It is cleared along with the others when the state is torn down.

**Why**

This gives live collaboration a distinct category for replicas that haven't responded yet, separate from ones that are unavailable or stale.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### mid_conversation_system opt-out model list simplified to a version comparator

Mid-conversation system prompt opt-out now uses a version comparison instead of a fixed model-name list

**What**

The check that decides whether the mid-conversation system prompt beta applies to a given model no longer lists out individual model names one by one (previously including names like `claude-opus-4-0`, `-4-1`, `-4-5`, `-4-6`, `-4-7`, and the corresponding Sonnet and Haiku 4.x names). It now does a single version comparison against `claude-opus-4-8`.

**Why**

Switching to a version comparison means new model versions on this side of the comparison are handled automatically, rather than needing each new model name added to a hardcoded list.

- Area: Models
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Scheduled-trigger task notifications restricted to host-scheduled runs

Scheduled-trigger task notifications now only fire from host-scheduled runs, not child or interactive sessions

**What**

A new notification builder for 'task-notification' and 'scheduled-trigger' events, which includes a sanitized `fireReason` field explaining why the notification fired, is now only used when the current process is a host-scheduled run. It is not used for child sessions or for sessions running under the interactive `claude-code` client.

**Why**

This prevents scheduled-trigger notifications from being sent in contexts where they don't make sense, such as from a spawned child session or an interactive terminal session.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Durable event uploader gets an 'urgent' fast lane with backoff

Event uploads gain an 'urgent' fast lane that skips ahead of delayed batch retries

**What**

The background uploader that batches and sends events now supports an urgent queue that jumps ahead of the normal batch queue. It has its own retry counter and its own exponential backoff window (`backoffOwedUntil`), so urgent sends don't get stuck waiting behind a slow batch's retry delay. Sends that immediately follow an urgent flush are tagged `followsUrgent`.

**Why**

This ensures time-sensitive events still get sent promptly even when the normal batch queue is backed off and retrying after a failure.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### $.ui action dispatcher generalized beyond 'press'

Plugin UI action lookup now works for any action, not just button presses

**What**

A helper used by Claude Code's plugin UI system to find a matching button now takes the specific action and tag being looked up, instead of being hardcoded to handle only `$.ui.press`. Error messages now name the actual action involved (for example `$.ui.press` versus another action) rather than always referring to a press. The helper also now returns the matched button itself, instead of triggering a press on it right away.

**Why**

This makes the lookup logic reusable for UI actions beyond button presses, and gives plugin authors clearer error messages that identify exactly which action failed to find a match.

- Area: Plugins
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New 'discover verdicts' cache (read/write chain)

New internal cache for 'discover verdicts' data added alongside the existing auth cache

**Unclear.** What 'discover verdicts' data is and what feature it belongs to is not stated in the finding.

**What**

Claude Code adds a new per-session cache, made up of a read cache (`discoverVerdictsRead`) and a write chain (`discoverVerdictsWriteChain`), following the same pattern as an existing auth cache. It's used to remember and serialize writes of some 'discover verdicts' data.

**Why**

The finding doesn't say what 'discover verdicts' refers to or what user-facing behavior this supports.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Unverified items always kept in compaction/dedup filter

Unverified items are now always kept when Claude Code deduplicates or summarizes

**Unclear.** What kind of items pass through this filter (and what 'verified' means for them) is not stated.

**What**

A filter function used during a deduplication/summary pass now always keeps an item when it is marked `isVerified === false`, in addition to keeping items that already have a summary attached.

**Why**

This prevents unverified items from being silently dropped during compaction or deduplication, though the finding doesn't specify what kind of items these are.

- Area: Compaction
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New file-sync end reason: created_empty_unfilled

New file-sync end reason 'created_empty_unfilled' added to cloud sync messaging

**What

- Area: File Sync
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New telemetry fields for git/file sync sessions

Claude Code's internal telemetry for git/file sync sessions now includes three new fields

**Unclear.** The finding does not say what data these fields actually capture or how they are used.

**What**

When Claude Code reports internal telemetry about sync sessions (the background process that keeps track of git and file state), the data it sends now includes three new optional fields: `servedLinked`, `firstUpload`, and `emptyUnreached`. These join the existing `endedEarlier` and `storageV5` fields already sent with this telemetry.

**Why**

This is internal diagnostic data used to understand how sync sessions behave; it does not change any user-facing behavior or require any action from users.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### allow_cobalt_plinth (Artifacts) permission now server-populated

The Artifacts permission policy can now be set by the server, not just locally

**What**

The permission policy for Artifacts (internal name `allow_cobalt_plinth`, which is denied under `hipaa` and `zdr` organization settings) is now marked `serverPopulated: true`. This is the same treatment already used for the Remote Control permission (`allow_remote_control`).

**Why**

Marking a permission as server-populated means its value can be set from the server side rather than relying only on local configuration. For Artifacts, this brings its permission handling in line with how Remote Control is already managed.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Swarm sandbox permission callback lookup has no in-bundle caller

An internal helper for checking pending sandbox permissions in swarms exists but appears unused so far

**Unclear.** It's unclear what this helper is intended for or whether it will be connected to other code in a future release.

**What**

The app code includes a new internal helper (referred to in the source as `xUr`) that checks whether a given entry exists in a `swarmPermissions.pendingSandbox` lookup, a data structure that tracks sandbox permission requests for swarms (groups of coordinated agents). This sits alongside existing helpers that register and resolve entries in that same lookup. Unlike those, this new checking helper does not appear to be called from anywhere else in the code that was inspected.

**Why**

Since the helper isn't wired up to any caller yet, it has no visible effect for people using Claude Code right now. It likely reflects groundwork for a feature still being built out, such as a way to check the status of a pending sandbox permission request in a swarm.

- Area: Swarm
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Compaction metadata now carries pre-compaction usage totals when available

Compaction metadata can now include the token usage totals from just before compaction ran

**What**

When Claude Code compacts a conversation (compressing earlier messages to free up context space), the metadata it records about that compaction can now include a `compactionUsage` field holding the token usage totals from just before compaction happened. This field is only added when the data is available, so it won't always appear.

**Why**

Having the pre-compaction usage totals attached to the compaction record makes it possible to see how much context was used right before a compaction was triggered, which is useful for understanding or debugging when and why compaction occurred.

- Area: Compaction
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New self-hosted-runner poll-interval override parser accepts signed duration strings

Claude Code can now parse signed duration strings like '-2.5s' for a self-hosted runner's health-poll interval

**What**

A new internal helper parses duration strings such as `5s` or `-2.5s` into milliseconds, then clamps the result to a minimum floor. It is used when computing how long a self-hosted runner waits between health polls, as a fallback for when the setting `pollIntervalOverrideMs` is not provided.

**Why**

This lets the runner's poll interval be configured or overridden using a simple duration string instead of raw milliseconds, while the floor clamp prevents an accidentally too-short or negative value from causing excessive polling.

- Area: Self-Hosted Runner
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Priority/backoff-skipping 'urgent' message path in the mailbox/event queue

Internal message queue gained an 'urgent' path that skips backoff delays and sends immediately

**Unclear.** The finding does not say what kinds of messages are actually marked urgent or what consumer relies on this path.

**What**

The internal queue that handles outbound messages and events gained an `urgent` option. Messages marked this way are pushed to a separate urgent list, end any active backoff (a delay used to slow down retries) early, and are sent right away, bypassing the normal batching that groups messages by queue size.

**Why**

This lets time-sensitive internal messages get delivered immediately instead of waiting behind normal queued traffic or a backoff delay.

- Area: Message Queue
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New tool-result field `toolDenialEndsTurn` for permission-stop aborts

Tool results aborted by a permission denial now carry a flag marking them as ending the turn

**What**

When a tool call is stopped specifically because permission for it was denied, the resulting tool-result message now includes a new field, `toolDenialEndsTurn`, set to true. A new helper scans backward through the conversation transcript and treats a message carrying this flag as marking the end of that turn, for purposes of classifying interruptions.

**Why**

This gives Claude Code a more precise way to recognize when a turn was cut short by a permission denial specifically, rather than by some other kind of interruption, which should make related behavior (like how the conversation resumes) more accurate.

- Area: Permissions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New `accountMemory` flag on MCP tool descriptors, feeding tool-result telemetry

MCP tools can now carry an internal 'accountMemory' flag that feeds into tool-result telemetry

**Unclear.** What accountMemory actually represents or controls beyond being passed into result-tracking is not stated.

**What**

Tools provided by MCP servers (Model Context Protocol, a standard for connecting external tools to Claude) can now carry a new internal `accountMemory` flag, defaulting to false and computed by a helper function. When true, it is stored on the tool's info and later used to adjust what gets recorded when that tool's result is tracked.

**Why**

This is internal plumbing that affects telemetry recording for MCP tool results; it has no direct user-facing behavior described in this change.

- Area: MCP
- Names: `accountMemory`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New handling for a `rate_limit_event` message type in the SDK/thin-client stream

SDK/thin-client streams now handle a new 'rate_limit_event' message type with sensitive fields stripped

**What**

The streaming code used by the SDK and thin client, which previously only had special handling for tool-result and user messages, now also recognizes a `rate_limit_event` message type. It validates the event's rate-limit info, strips out the `canUserPurchaseCredits` and `hasChargeableSavedPaymentMethod` fields, and passes the rest along. Invalid payloads are logged and discarded rather than passed through.

**Why**

This lets rate-limit information flow through the stream to consumers of the SDK/thin client while withholding billing-related details that aren't meant to be exposed there.

- Area: SDK
- Names: `rate_limit_event`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Mass-delete guard check across multiple memory stores, no confirmed caller in my slice

New guard checks for mass-deletion across multiple memory stores at once, not yet confirmed to be in use

**Unclear.** No confirmed caller for this function was found, so it's unclear when or whether it currently runs.

**What**

A new internal function checks a list of memory stores together, applying the same threshold used elsewhere to detect when too many files appear to have been deleted from a single store, but now across the whole set of stores at once. It reports back the threshold used, how many files are missing, and how many targets remain on disk.

**Why**

This appears to be a safety check meant to catch large-scale accidental deletion spanning multiple memory stores, though it isn't confirmed where or when it is actually called.

- Area: Memory
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Remote-session rate-limit-event adoption/settling machinery

Remote sessions now track and reconcile rate-limit events arriving via replay or live stream

**What**

The code that manages remote sessions now builds a rate-limit adoption object seeded from `seedRateLimitInfos`, and separately holds, pushes, and settles `rate_limit_event` messages depending on whether they arrived from replaying past events or from the live stream. It also adopts a fallback rate-limit signal if catch-up data gets truncated.

**Why**

This keeps rate-limit information accurate and consistent in remote sessions regardless of whether the events were seen live or reconstructed from replay, including a fallback for when replay data is incomplete.

- Area: Rate Limits
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Home-seed / dir-sync 'standing' hold flag on the first-send gate

File-sync's first-send gate gets a new 'standing' setting controlling whether a hold expires or persists

**What**

The file-sync 'seed gate,' which can hold back the very first outbound send of a file until a release or withdrawal decision is made, now has a `standing` flag in its configuration. Previously a hold was always time-boxed, limited to one hold per fixed time window. With `standing` set, one implementation of the gate removes that time-box entirely, while a related implementation instead forces the hold to keep persisting rather than expiring on its own.

**Why**

This changes whether a sync hold on a newly-created file clears itself automatically after a set time or stays in place until something explicitly releases it.

- Area: File Sync
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### The Agent tool description was rewritten

The Agent tool's description was rewritten with new guidance on when to delegate work to it

**What**

The description of the Agent tool (used to launch subagents, separate Claude instances that can work on a task independently) was rewritten. The new text says to reach for it "when the task matches an available agent type, when you have independent work to run in parallel, or when answering would mean reading across several files," framing delegation as a way to keep the conclusion rather than the raw file contents.

**Why**

This gives clearer guidance on when Claude should hand work off to a subagent instead of doing everything inline, particularly for tasks that would otherwise mean dumping a lot of file content into the main conversation.

- Area: Agent Tool
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### The main system prompt in the reminder-hook-pretool-block prompt was rewritten

The reminder-hook-pretool-block prompt was rewritten with new guidance on sticking to the requested scope of work

**What**

The system prompt text used in the reminder-hook-pretool-block context (shown when a pre-tool-use hook blocks a tool call) was rewritten. The new wording instructs doing ordinary work as asked rather than acting on speculation about intent, treating the requested scope as the deliverable, using judgment on ambiguity, raising real problems in a sentence or two before continuing, and finishing the whole task rather than reporting completion early.

**Why**

This shapes how Claude behaves when a hook has blocked one of its tool calls, pushing it to stay within the original request's scope and finish the task rather than narrowing, widening, or abandoning it.

- Area: System Prompt
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### The main system prompt in the reminder-read-dup prompt was rewritten

The reminder-read-dup prompt was rewritten with guidance to flag problems but keep working

**What**

The system prompt text used in the reminder-read-dup context (shown on a duplicate file read) was rewritten. The new wording says that if a real problem is found with the task as specified, Claude should state the concern in a sentence or two, then keep building: delivering the complete work under explicitly stated assumptions while flagging important factors for the user.

**Why**

This is guidance for how Claude should respond when it spots an issue with the task while re-reading a file, favoring flagging the concern and continuing over stopping or silently changing scope.

- Area: System Prompt
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### The main system prompt in the reminder-read-empty prompt was rewritten

The reminder-read-empty prompt was rewritten with guidance on leaving blocked parts of a task explicit

**What**

The system prompt text used in the reminder-read-empty context (shown when a read turns up an empty file) was rewritten. The new wording says that if part of the task's scope is blocked or problematic, Claude should finish every other part in full and explicitly say what it left out and why, since scaling the work down is the user's call, not Claude's.

**Why**

This tells Claude not to quietly drop or shrink part of a task when it hits a blocker on an empty file, but to complete everything else and flag the gap clearly.

- Area: System Prompt
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### The main system prompt in the reminder-read-offset prompt was rewritten

The reminder-read-offset prompt was rewritten with guidance on handling ambiguity like a careful colleague would

**What**

The system prompt text used in the reminder-read-offset context (shown when a file read uses an offset) was rewritten. The new wording says to interpret ambiguity the way a careful colleague would: make routine judgment calls independently, and only check in with the user when different readings of the task would lead to materially different work.

**Why**

This guides how much Claude should ask versus decide on its own when a task is ambiguous, aiming to cut down on unnecessary check-ins while still flagging genuinely consequential ambiguity.

- Area: System Prompt
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### The main system prompt in the reminder-skill-run prompt was rewritten

The reminder-skill-run prompt was rewritten with guidance to act on the actual request rather than speculation

**What**

The system prompt text used in the reminder-skill-run context (shown when a skill is run) was rewritten. The new wording says to do ordinary work as asked, acting on the actual request rather than on speculation about what lies behind it.

**Why**

This steers Claude to take a skill invocation's request at face value rather than trying to infer and act on some broader unstated intent.

- Area: System Prompt
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### The main system prompt in the reminder-todo-nag prompt was rewritten

The reminder-todo-nag prompt was rewritten with guidance not to narrow, widen, or transform the requested scope

**What**

The system prompt text used in the reminder-todo-nag context (shown as a nudge to update the to-do list) was rewritten. The new wording states that the requested scope is the deliverable, and that Claude should not quietly narrow, widen, or transform it.

**Why**

This reinforces that Claude should stick to what was actually asked for when nudged about its to-do list, rather than drifting the scope of the task in either direction.

- Area: System Prompt
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### The main system prompt in the reminder-toolsearch-deferred prompt was rewritten

The reminder-toolsearch-deferred prompt was rewritten with guidance to finish the whole task before reporting done

**What**

The system prompt text used in the reminder-toolsearch-deferred context (shown when a deferred tool needs to be looked up via ToolSearch) was rewritten. The new wording says to finish the whole task, not just the easy parts, and to report completion only when fully done.

**Why**

This pushes Claude to complete a task in full, including after it has had to pause to look up a deferred tool, rather than reporting it as finished prematurely.

- Area: System Prompt
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Selectable list reducer gains a 'scroll-viewport' action for wheel/programmatic scrolling

Selectable lists gained a scroll-viewport action for mouse-wheel and programmatic scrolling

**What**

The internal logic behind Claude Code's selectable lists now handles a `scroll-viewport` action, which shifts the visible window of list items by a given amount while keeping track of which item is focused, even if it moves out of view. This is separate from moving focus with the up/down arrow keys.

**Why**

This allows list scrolling, such as with a mouse wheel, to move independently of keyboard navigation while still keeping the selected item correctly tracked.

- Area: UI Components
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Routine version/build metadata bump

Routine build version metadata updated to 2.1.280

**What**

The standard `VERSION`, `BUILD_TIME`, and `GIT_SHA` build identifiers were updated across multiple bundled entry points for this release.

**Why**

This is routine release bookkeeping with no functional effect.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Windows shell-name hint no longer hardcodes the PowerShell/Bash tradeoff wording

The Windows shell hint text pointing out PowerShell vs Bash syntax differences is now built from a separate string

**Unclear.** The finding does not say whether the wording or behavior of the hint actually changed for users, only how it is assembled internally.

**What**

On Windows, Claude Code shows a hint about which shell is active, including a note that PowerShell is the primary shell but that each shell (PowerShell, Bash, etc.) takes its own command syntax. That explanatory text is now pulled from its own string constant and a different helper function, rather than being written directly into the hint code.

**Why**

This is an internal restructuring with no described change in what the hint says or when it appears.

- Area: Windows
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Git remote-name parsing simplified/changed

Git's bracketed remote-name parsing was simplified, dropping a separate 'named remote' detection step

**Unclear.** Whether this changes any parsing outcomes, or is purely a code simplification with the same results, is not stated.

**What**

The code that parses bracketed remote names out of git config-style text no longer has a separate `isNamedRemote` check (which looked for a `remote.` prefix). It now directly returns the lowercased name together with a quoted flag.

**Why**

This is an internal simplification of git config parsing. The finding does not indicate any change in what remote names are recognized or how they are handled afterward.

- Area: Git Integration
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### git diff-tree logic for change detection factored into shared helper

Git diff-tree change detection logic moved into a shared internal helper

**What

- Area: Git Integration
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### New no-arg wrapper for disarming the startup wedge watchdog

Added a small helper that safely calls Claude Code's startup-wedge watchdog disarm method

**What**

Claude Code has an internal "startup wedge watchdog" that detects when the app gets stuck during startup. This release adds a small wrapper function that calls the watchdog's existing `disarmStartupWedgeWatchdog` method through an optional-chained call, so it's safe to invoke even if the underlying server object isn't set up yet.

**Why**

This is an internal code-organization change with no visible effect on how Claude Code behaves; the stuck-startup detection itself already existed.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Scrollbar indicator component added for a list panel

Added a scrollbar indicator component for list panels that shows only when content overflows

**What**

Claude Code adds a new component that draws a vertical scrollbar using pipe characters, with a "thumb" sized and positioned based on how many items are visible, the total item count, and the panel's height. It only appears when the content is too long to fit in the visible area.

**Why**

This gives users a visual cue of their position within a long list and how much more content there is to scroll through.

- Area: UI Components
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Bearer token extraction helper added

Claude Code adds an internal helper to strip the "Bearer " prefix from an Authorization header

**Unclear.** The finding does not say where this helper is used or what feature it supports.

**What**

A small new helper function extracts the raw token from an Authorization header by stripping off the literal "Bearer " prefix that precedes it.

**Why**

Authorization headers for token-based authentication are commonly formatted as "Bearer ". This helper lets internal code pull out just the token part for further use.

- Area: Auth
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Git config/gitmodules-style parser rewritten to a callback-based streaming form

Claude Code's internal git config/.gitmodules parser now streams results through callbacks instead of returning a list

**Unclear.** The finding does not say what user-facing behavior, if any, this parser rewrite enables or fixes.

**What**

An internal function that reads git config-style files (such as `.gitmodules`) was rewritten. It used to scan the text and hand back an array of matched remote URLs all at once. Now it instead calls back into supplied `header`, `entry`, and `malformed` functions as it processes each line, and it no longer returns a value at all.

**Why**

This is an internal implementation change to how Claude Code reads git configuration data, not something a user configures directly. Processing line by line as it goes, rather than building up and returning a full list, means callers can react to each config entry (or each malformed line) as it's found.

- Area: Git Integration
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Bundled model reference doc hash updated

Claude Code's bundled model reference file was refreshed with a new content hash

**Unclear.** What specific content changed in the model reference document is not known, only that the file's hash-derived name is new.

**What**

Claude Code ships a bundled reference document listing the models it can use. In this release, the file's name changed to reflect a new content hash (`models-b6cb6bd6.md.zst`), which means the underlying document was refreshed with new content.

**Why**

This keeps the model reference Claude Code relies on internally up to date, though the finding does not specify what information in the document changed.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### File-read path switched to explicit resource disposal (await using)

File reading now closes file handles automatically using JavaScript's explicit resource management

**What**

When Claude Code reads a file's content, character encoding, or line-ending style, it now opens the file using the `await using` syntax. This is a JavaScript feature for explicit resource management, meaning the file handle is automatically and reliably closed once the operation finishes, rather than being closed manually in the code. The actual work of reading and decoding the file has also been moved into a dedicated helper function instead of being handled inline.

**Why**

This is an internal reliability improvement: automatic cleanup of file handles reduces the chance of resource leaks if an error occurs partway through reading a file. It should not change what Claude Code shows you, only make file reading more robust under the hood.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Vim-mode footer hint no longer receives an explicit row width

Vim-mode footer hint no longer gets an explicit row width

**Unclear.** It's unclear what visual or behavioral effect dropping the explicit rowWidth has on the footer.

**What**

The footer component that displays the vim-mode indicator and hints no longer computes and passes a `rowWidth` prop. Previously this was derived by subtracting the width of the vim-mode label from an incoming `rowWidth` value.

**Why**

The finding doesn't specify how this affects the footer's appearance or layout in practice.

- Area: Terminal UI
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Session-trash directory check refactored to take a list of paths

Session-trash directory-check function now takes an explicit list of paths instead of deriving them internally

**What**

The internal function that verifies session trash paths are plain directories now takes a `checked` array of paths passed in directly, rather than deriving them itself from `commonDir` and `trashDir`.

**Why**

This is an internal refactor that makes the function's inputs explicit rather than computed internally; the finding does not indicate any change in what gets checked.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### settings.js MCP-servers-forward config field alignment fixed (whitespace only)

Whitespace-only formatting fix near the settings.js skills array check, no behavior change

**What**

A formatting-only change was made near the `skills` array check in `settings.js`. No functional change was detected.

**Why**

This is a cosmetic fix with no effect on behavior.

- Area: Settings
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

## Removed

### Session polling config: legacy single-session poll-interval fields removed

Session polling config drops the old single-session poll-interval settings, keeping only the multisession ones

**What**

The configuration schema for how Claude Code polls for session liveness no longer includes the older `poll_interval_ms_not_at_capacity` and `poll_interval_ms_at_capacity` fields, along with the validation rule that required either heartbeat or at-capacity polling to be set. What remains are the `multisession_*` equivalents and `non_exclusive_heartbeat_interval_ms`.

**Why**

This removes now-unused legacy configuration in favor of the multisession polling settings that replaced it, simplifying the configuration surface for anyone inspecting or setting these values.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Model launch-effort pinning flags removed from client config

Three model 'launch-effort pinning' config fields were removed from the default client settings

**Unclear.** The finding does not explain what launch-effort pinning did or what removing these fields changes in practice.

**What**

The default client configuration store no longer includes three fields: `unpinOpus47LaunchEffort`, `unpinOpus48LaunchEffort`, and `unpinFable5LaunchEffort`.

**Why**

These fields controlled some form of model "launch-effort pinning" behavior for specific models; their removal means that mechanism no longer has a client-side config toggle.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### 'y'/'n' keyboard shortcuts removed from confirmation dialogs

'y' and 'n' keyboard shortcuts no longer confirm or cancel dialogs by default

**What**

Confirmation dialogs no longer bind the `y` and `n` keys to "yes" and "no" by default. Only `enter` (confirm) and `escape` (cancel) remain bound.

**Why**

Users who relied on pressing `y` or `n` to answer confirmation prompts will need to use `enter` or `escape` instead, or rebind the keys themselves.

- Area: Terminal UI
- Names: `y`, `n`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### MCP server management menu loses the 'Restart' option

The MCP server detail menu in Claude Code no longer has a Restart option, only Remove and Back

**What**

The interactive menu you see when you select a server in Claude Code's MCP (Model Context Protocol, a way for Claude Code to connect to external tools and data sources) server management screen used to offer three actions: Restart, Remove, and Back. The Restart option is now gone, leaving just Remove and Back.

**Why**

If you were used to restarting a misbehaving MCP server directly from this menu, that shortcut is no longer there.

- Area: MCP
- Names: `Restart`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Opus 4.1 removed from the offered model list

Opus 4.1 removed from the list of offered models

**What**

The model catalog entry for `claude-opus-4-1-20250805` ("Opus 4.1"), previously offered on Bedrock and Vertex in the overflow section, has been removed entirely.

**Why**

Opus 4.1 is no longer offered as a selectable model in Claude Code through those providers.

- Area: Models
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Transcript summary line no longer shows a REPL count

The turn summary line no longer reports how many times the REPL tool was used

**What**

Claude Code shows a short summary line after each turn, like "read N files · listed N directories · ran N shell commands." That line used to include a "REPL'ing" or "REPL'd N times" entry when the REPL tool (a tool that runs code interactively and shows results) was used during the turn. That entry has been removed entirely.

**Why**

The summary line still covers other tool usage, but REPL activity no longer shows up in it, so you won't see a count of REPL uses in that rollup anymore.

- Area: Transcript
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### REPL usage counter removed from tool-usage tracking

Internal usage tracking no longer counts REPL tool calls separately

**What**

An internal usage-tracking counter object dropped its `replCount` field, which used to count uses of the REPL (the interactive code-execution tool), alongside other fields like `searchCount`, `readCount`, `listCount`, and several memory-related counts.

**Why**

This is an internal telemetry change; it does not affect what Claude Code can do, only what usage statistics it records.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Usage-stats replCount field removed

Claude Code's usage-tracking data no longer includes a replCount field

**What**

An internal usage-statistics object that previously always included a `replCount` field set to `0` no longer sets that field at all.

**Why**

This is an internal telemetry change; since the field was always `0`, removing it shouldn't change any behavior a user would notice.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Removed fixed polling-interval constants

Two fixed polling-interval settings were removed from a multisession/heartbeat config

**Unclear.** What, if anything, replaces these two removed polling-interval constants is not stated.

**What**

Two configuration constants, `poll_interval_ms_not_at_capacity` and `poll_interval_ms_at_capacity`, have been removed from a configuration object that still keeps its other multisession and heartbeat interval settings.

**Why**

The finding doesn't say what replaces these fixed polling intervals, so it's unclear what governs polling timing now in their place.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Removed the bridge API's sendPermissionResponseEvent call

The bridge API's sendPermissionResponseEvent call, used for some IDE integrations, has been removed

**What**

An internal method called `sendPermissionResponseEvent`, which sent a permission-response event to Claude Code's bridge API (a channel used for some external/IDE integrations), has been deleted. It also used to log the request and response bodies of that call; that logging is gone too.

**Why**

This removes a code path that some external or IDE integration may have relied on for permission-response events. Readers building on the bridge API should check whether their integration used this event.

- Area: IDE Integration
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Legacy skills manifest repair path removed

Skills sync no longer repairs a malformed manifest with a legacy schema fallback; it now just fails

**What**

When syncing skills, if a manifest file failed to parse against the current schema, the code used to fall back to a legacy schema parser and repair the manifest, logging `skills_sync_legacy_manifest_repaired`. That repair path has been removed: a manifest that fails the current schema now simply returns `null` instead of being salvaged.

**Why**

A manifest that would previously have been silently patched up under the old format will now be treated as unreadable instead. This means older or malformed skills manifests may stop working where they used to be auto-repaired.

- Area: Skills
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5
