# Claude Code v2.1.275

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

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

This build carries 54 gated additions that stay out of reach. The largest is a new post-turn memory system: a 'memory' settings layer plus an MCP tool for writing, reading, appending to, and deleting notes across turns, held behind the CLAUDE_CODE_POST_TURN_MEMORY environment variable. Plugin marketplaces gain npm as a source, with pip, uv, cargo, github, and gh reserved but not usable yet, and npm-direct plugin installs sit behind their own flag. Also present but inactive: a plugin API method ui.panes for listing a plugin's own UI panels, the ability to park and resume an interrupted background agent instead of just stopping it, kitty-protocol terminal image rendering detection, a startup promo system with a limit-wall "claim credit" option, and logic for defaulting plain claude runs to cloud sessions that is currently hardcoded off.

Several of those cloud and memory features have a usable counterpart today. Cloud sessions by default is now a real flag that can silently route plain claude invocations to the cloud, and the new 'memory' settings layer ships with replace, append, and insert edit modes. Remote control can now push a model or effort-level change into a running session, and a SubagentStop hook event joins the existing SubagentStart. Plugin hooks gain a $.prompt.read API for reading prompt-box text and cursor position, plus new session.end and session.measure lifecycle events; deep links can trigger a direct plugin install via claude://install-plugin, and /plugin adds install-from-source and npm-aware installs. Subagents are now capped at 20 concurrent runs by default, adjustable with CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS, and a new --project-config-root flag lets a host pin the project directory separately from the working directory.

Among 47 fixes, account-level memory storage has been removed and now errors instead of working. Transcript loading repairs malformed or unreadable rows instead of failing outright, and oversized tool, binary, or hook output that can't be saved to disk now shows a truncated preview rather than being silently cut. Remote sessions no longer clear every in-progress tool indicator when an unrelated message arrives, and answering a permission prompt from outside the session now counts as a denial. Grep failures get distinct errors for oversized or failed ripgrep output, and artifact network errors now explain that outbound HTTPS on port 443 is required.

## 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.

### Post-turn memory: new 'memory' settings layer and MCP memory tool with read/write/append/delete, gated by CLAUDE_CODE_POST_TURN_MEMORY

A new 'memory' settings layer and MCP memory tool let Claude write, read, and edit notes across turns

**What**

Claude Code's settings system now includes a new layer called `memory`, added to the existing list of layers (`managed`, `user`, `project`, `local`). Alongside it, a new internal tool exposes memory operations: `memory_write`, `memory_read`, `memory_str_replace`, `memory_append`, and `memory_delete`. The whole feature is gated by the environment variable `CLAUDE_CODE_POST_TURN_MEMORY`; when it isn't set, the related post-turn memory writing logic stays inactive. Write operations support three modes: `replace`, `append`, and `insert`.

**Why**

This lays groundwork for Claude to persist notes or state after a turn finishes and read them back later, using a dedicated settings layer and a small set of file-like operations, though it only activates when `CLAUDE_CODE_POST_TURN_MEMORY` is set.

- Area: Memory
- Names: `CLAUDE_CODE_POST_TURN_MEMORY`, `memory_write`, `memory_read`, `memory_append`, `memory_delete`
- Tier: Nothing to try yet
- Useful: 5/5
- Signal: 5/5
- Present in the build but not switched on

### New 'advisor' tool gated behind a disable env var and first-party/entitlement check

A new 'advisor' tool is available, controllable via the CLAUDE_CODE_DISABLE_ADVISOR_TOOL environment variable

**What**

Claude Code has a new internal tool called "advisor". Its availability can be turned off by setting the `CLAUDE_CODE_DISABLE_ADVISOR_TOOL` environment variable to `1`, which also disables the `/advisor` command, ignores any configured `advisorModel`, and makes the `--advisor` flag a no-op (accepted but without effect, so scripts that pass it keep working). Otherwise, using it requires a first-party Anthropic account and an internal entitlement check.

**Why**

This gives users and organizations a way to opt out of the advisor tool entirely, while otherwise restricting it to eligible accounts.

- Area: Advisor
- Names: `CLAUDE_CODE_DISABLE_ADVISOR_TOOL`, `/advisor`
- Tier: Use it now
- Useful: 5/5
- Signal: 4/5

### npm-hosted plugin marketplaces (behind a new gate)

Claude Code can now install plugins hosted on the npm registry, gated behind a new flag

**What**

Plugin installs can now come from the npm registry, not just from git repositories or claude.ai. Install records now carry npm-specific provenance (`npmVersionSpec`, `npmResolved`, `npmIntegrity`, `npmRegistry`), and the `/plugin install` command recognizes a `plugin@marketplace` spec that resolves to an npm package, routing it to a dedicated npm-install flow. A new `--registry <url>` flag lets you point the install at a specific registry instead of your local npm configuration.

This path is controlled by a gate called `tengu_plugins_npm_marketplace`. If it's off for an account, installing a plugin marketplace directly from an npm package (using a `<package>@npm` spec) fails outright with a message saying that installing plugins straight from npm is not enabled for the account. Separately, if a plugin's install record has no integrity hash to check the download against, Claude Code refuses to load it.

**Why**

This opens a new distribution channel for plugins that doesn't depend on git or claude.ai, while the integrity check protects against loading a downloaded plugin that can't be verified as untampered.

- Flag `tengu_plugins_npm_marketplace`: Not enough to say (read for one account on one subscription tier against v2.1.275; 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
- Names: `--registry`, `/plugin install`
- Tier: Nothing to try yet
- Useful: 5/5
- Signal: 4/5
- Present in the build but not switched on

### Cloud sessions by default: plain `claude` invocations can be silently routed to the cloud

Plain `claude` commands can now be silently routed to a cloud session by default under a new flag

**Unclear.** Whether cloudSessionsByDefault is on for any given account is decided server-side and not stated by this finding.

**What**

Claude Code now checks, at startup, whether it should default a plain `claude` invocation to a cloud (remote) session instead of running locally. This is controlled by a new `cloudSessionsByDefault` setting combined with checks that the user did not pass flags like `--resume`, `--connect`, or `--ssh`. When this applies, the session is switched to run remotely even though nothing on the command line asked for that. Passing a new `--local` flag opts out and is recorded as a decline.

**Why**

Users relying on plain `claude` to always start a local session should be aware that, depending on this setting, a plain invocation could instead start a cloud session. The `--local` flag is available to force a local session explicitly.

- Area: Cloud Sessions
- Names: `cloudSessionsByDefault`
- Tier: Use it now
- Useful: 4/5
- Signal: 4/5

### Cloud-sessions-by-default gating logic added but currently hardcoded off

New logic for defaulting CLI runs to cloud sessions exists but is currently hardcoded off

**Unclear.** Whether or how this gating logic is currently enabled for any users is not stated; the finding describes it as present but not yet wired to take effect.

**What**

Claude Code has added internal logic that decides whether a CLI invocation should default to running as a cloud session, based on a `cloudSessionsByDefault` setting and the absence of explicit flags like session, resume, continue, teleport, connect, SSH, worktree, or remote control. The logic can currently resolve to "none", "declined", or "applied", and if applied, the session id defaults to an empty string.

**Why**

This groundwork isn't active yet, so it has no effect on current behavior, but it signals that Claude Code may default some invocations to cloud sessions in the future.

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

### Interrupted background agents/tasks can be 'parked' and resumed instead of just stopped

Interrupting a background agent now 'parks' it for resuming instead of stopping it outright

**Unclear.** The gate `tengu_zinc_harbor` is currently reading off for this site's account and for the anonymous baseline, and no reading has been taken under this release yet, so it's unclear whether this parking behavior is active.

**What**

When a user interrupts Claude Code while background agents or the main session (acting as a sub-agent) are running, they are no longer always stopped. Instead, they can now be "parked": their progress is preserved and they can be resumed later by sending a message. The interruption notification now distinguishes parked agents from stopped ones.

**Why**

This means interrupting running background work doesn't necessarily throw away its progress; it can be picked back up later instead of having to start over.

- Flag `tengu_zinc_harbor`: Off in both readings (read for one account on one subscription tier against v2.1.275; 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: Background Tasks
- Tier: Nothing to try yet
- Useful: 4/5
- Signal: 4/5
- Present in the build but not switched on

### New plugin API method ui.panes with no permission check, wired end-to-end but never called by anything else in the bundle

New plugin API method ui.panes lets plugins list their own UI panels, with no permission check

**Unclear.** The finding shows the method wired into the dispatch table and SDK but not called elsewhere, so what a plugin author would use it for in practice is unclear.

**What**

A new method, `ui.panes`, was added to the plugin runtime API. It returns the list of UI panes (panels) that belong to the calling plugin, including each pane's id, title, and whether it's shown, focused, or placed. The plugin SDK now exposes this as `panes()`. Unlike the similar `ui.open`, `ui.close`, `ui.scroll`, and `ui.focus` methods, `ui.panes` has no permission check attached to it.

**Why**

This gives plugin authors a way to inspect their own panes' state, though nothing else in Claude Code currently calls it, so its practical use isn't yet visible.

- Area: Plugin API
- Names: `ui.panes`
- Tier: Nothing to try yet
- Useful: 4/5
- Signal: 4/5
- Present in the build but not switched on

### npm-sourced plugin marketplaces added; several other sources reserved for future use

Plugin marketplaces can now source plugins from npm; pip/uv/cargo/github/gh sources are reserved but not yet usable

**What**

Plugin marketplaces can now use `npm` as a real source, letting you install plugins from an npm registry using the form `<package>@npm`. Several other source names — pip, uv, cargo, github, and gh — are also now recognized as reserved names, but they are not yet available for actual use.

**Why**

This gives plugin authors and users a working way to distribute and install plugins through npm today, while signaling that support for other package ecosystems is planned.

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

### Plugins can now be installed directly from the npm registry

Plugins can now be installed directly from the npm registry

**What**

Claude Code can now install a plugin directly from the npm package registry by resolving a package name and version, downloading and verifying the package's integrity (checksum), and safely unpacking its contents, rejecting symlinks, device files, path traversal attempts, and oversized files along the way. If this capability is disabled for an account, Claude Code shows a message explaining that installing plugins from npm (using `<package>@npm` syntax) isn't enabled.

**Why**

This gives another distribution path for plugins, letting them be published and installed through the existing npm ecosystem rather than only through other plugin sources, while guarding against malicious or malformed packages during install.

- Flag `tengu_plugins_npm_marketplace`: Not enough to say (read for one account on one subscription tier against v2.1.275; 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: 5/5
- Signal: 3/5
- Present in the build but not switched on

### Deep links can now install plugins directly (claude://install-plugin)

Deep links can now trigger a direct plugin install, not just opening the app

**What**

Claude Code's deep-link scheme (`claude://`) now supports an `install-plugin` action alongside the existing `open` action. It requires a `plugin` parameter, validated against a strict name format, and accepts an optional `marketplace` parameter that can be a GitHub owner/repo, an `https://` URL, a git SSH URL, or an npm-scoped package form (`@scope/name@npm`). A `#` character in the link must now be percent-encoded as `%23` when it's part of a marketplace git reference; raw `#` is rejected.

**Why**

This lets a link (for example shared in documentation or a website) install a specific plugin directly, rather than only opening Claude Code.

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

### New --project-config-root CLI flag reroutes project scope across the app

A new --project-config-root flag lets a host pin Claude Code's project directory separately from the working directory

**What**

A new, hidden CLI flag, `--project-config-root`, lets a host application point Claude Code at a project configuration root directory that's different from the current working directory. This directory is then used for discovering `CLAUDE.md`, loading settings, finding skills directories, resolving `.mcp.json`, locating scheduled tasks, and setting the `CLAUDE_PROJECT_DIR` environment variable for plugins, among other things. It's meant for cases where a host starts a session inside a worktree copy of the real project.

The value must be an absolute local path to an existing, listable directory, and can't be a network location. Several features are explicitly unavailable when this flag is set, since there's no single well-defined project directory to act on:

- durable scheduled tasks

- project-scope MCP server changes

- project-scope workflow saves (this now also logs a telemetry event when attempted)

- moving a session to the background (a background copy wouldn't retain the flag, so it would use the wrong working folder's hooks and settings)

- relaunching a background-agent view onto a newer build, since the relaunch would drop the flag; a manual update attempt is refused with an explicit error instead

- the `--routine` option, which is explicitly refused when `--project-config-root` is used

The background/left-arrow shortcut also now checks for this override before proceeding and blocks the action if it's set, logging a `tengu_left_arrow_blocked` event with the reason `project-config-root`.

**Why**

This lets a host application safely separate "where Claude Code is running from" from "what counts as the project," while making sure features that assume a single, stable project folder fail clearly instead of behaving unpredictably.

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

### New plugin hook API: $.prompt.read

New plugin hook API lets plugins read the current text and cursor position in the prompt box

**What**

A new plugin hook method called `prompt.read` returns the current contents of the prompt input box (the text field where you type to Claude), including the text and cursor position, or an empty box if none is currently active.

- `prompt.fill`, which lets a plugin or hook programmatically fill in the prompt box, now accepts a `mode` argument (`replace`, `append`, or `insert`) defaulting to `replace`, controlling how the new text combines with what's already there.

**Why**

This gives plugins more control over the prompt box: they can now read what's currently typed before deciding what to do, and can append or insert text instead of always overwriting it.

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

### New plugin/session lifecycle hook events session.end and session.measure

Two new lifecycle events, `session.end` and `session.measure`, added for plugins and hooks

**Unclear.** The finding does not say what `session.measure` actually measures or when it fires.

**What**

Claude Code added two new lifecycle events, `session.end` and `session.measure`, to the set of events that plugins and hooks (scripts that run automatically at specific points) can respond to. These join existing session-related events like `session.compact` and `session.attach`. The new events are wired through the schema, an internal raiser mechanism, and real call sites that emit them during a session.

**Why**

This gives plugins and hooks more points in a session's lifecycle to hook into, specifically when a session ends and when some kind of measurement occurs.

- Area: Hooks
- Names: `session.end`, `session.measure`
- Tier: Use it now
- Useful: 4/5
- Signal: 3/5

### New settings layer 'memory' and edit modes replace/append/insert

Settings gained a new 'memory' layer plus replace/append/insert edit modes

**Unclear.** How the new `memory` layer and the replace/append/insert edit modes are actually exposed or used isn't stated.

**What**

Claude Code's settings system organizes configuration into layers (previously managed, user, project, and local). This release adds a fifth layer called `memory`. Separately, a new list defines edit operation modes for settings: `replace`, `append`, and `insert`, along with an error message shown when an invalid mode is used.

**Why**

The new `memory` settings layer and the structured edit modes suggest more granular control over how memory-related settings are stored and modified, though the finding doesn't specify which commands or UI expose this yet.

- Area: Settings
- Names: `replace`, `append`, `insert`
- Tier: Use it now
- Useful: 4/5
- Signal: 3/5

### Team memory sync can now hold local-only files through a broken manifest instead of dropping them

Team memory sync now holds onto local-only files instead of dropping them when its sync record is broken

**What**

Team and organization shared-memory sync now has a "held" state. If a memory store's local folder loses its usable record of what's already been synced (its `.memory-sync` manifest becomes untrustworthy), Claude Code no longer discards or overwrites the local memory files. Instead it keeps them on disk, tracks them in a `heldLocal` list, and notifies the user that "Memory sync for the ... memory store is off for now." When sync recovers, it reconciles which held files were edited, deleted, or already appeared on the server, tells the user sync "is back on," and records a new `tengu_team_mem_rejoin` telemetry event.

**Why**

This protects local memory edits from being silently lost when sync state gets corrupted, and gives a clear signal to the user about when sync has paused and resumed.

- Flag `tengu_typed_koala`: On for this account, and not off by default (read for one account on one subscription tier against v2.1.275; 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: Team Memory
- Tier: You'll notice
- Useful: 4/5
- Signal: 3/5

### In-terminal image rendering (kitty graphics protocol) capability detection added

Claude Code can now detect and use in-terminal image rendering via the kitty graphics protocol

**What**

Claude Code now detects a new terminal capability called `kittyGraphics`, which allows images to be rendered directly inside the terminal using the kitty graphics protocol (a standard originally from the kitty terminal, also supported by ghostty). This detection:

- Checks the terminal's name against an allowlist of kitty and ghostty terminals, including a minimum kitty version

- Is disabled by default inside `tmux` or `screen`

- Is turned off entirely for background worker sessions

- Can be forced on via an environment variable

Under the hood, Claude Code's rendering layer (Ink) gained a new `Image` render type separate from the existing `Raster` type, along with supporting code to transmit images to the terminal in chunks, manage image slots, and retransmit images after the terminal is resized or resumed.

**Why**

This lays the groundwork for Claude Code to display actual images in supported terminals rather than only text-based or raster placeholders, on terminals that support the kitty graphics protocol.

- Area: Terminal Rendering
- Names: `kittyGraphics`
- Tier: Nothing to try yet
- Useful: 4/5
- Signal: 3/5
- Present in the build but not switched on

### Installed (non-built-in) plugins' hooks modules gated behind a new rollout flag, off by default

Hooks modules for installed (non-built-in) plugins now require a rollout flag, off by default

**What**

A plugin's hooks module (JavaScript code that runs on specific events, such as `functionHooks`) is now skipped for every installed plugin unless the `tengu_plugin_hooks_modules` rollout flag is turned on. Built-in plugins are exempt and continue to load their hooks modules regardless. When a plugin's hooks module is skipped, Claude Code logs why. The behavior can also be forced on directly with the `CLAUDE_CODE_ENABLE_FUNCTION_HOOKS` environment variable.

**Why**

This restricts JavaScript-based plugin hooks to built-in plugins by default while the feature rolls out, so installed third-party plugins won't run function-based hooks unless explicitly enabled.

- Flag `tengu_plugin_hooks_modules`: Not enough to say (read for one account on one subscription tier against v2.1.275; 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
- Names: `CLAUDE_CODE_ENABLE_FUNCTION_HOOKS`, `tengu_plugin_hooks_modules`
- Tier: Nothing to try yet
- Useful: 4/5
- Signal: 3/5
- Present in the build but not switched on

### Plugin install can now target npm packages directly, behind a flag

Plugin install can now pull straight from npm with a new --registry option, gated behind an account flag

**Unclear.** Nothing has been read yet about whether the `tengu_plugins_npm_marketplace` gate is switched on for any account.

**What**

`claude plugin install` can now recognize a spec suffixed with `@npm` (for example `name@npm`, `@scope/name@npm`, or `name@1.2.3@npm`) and install the package directly from an npm registry, skipping the usual plugin marketplace system entirely. A new `--registry` option lets you point at a specific registry, and it must be given as a valid `http` or `https` URL.

This whole capability is gated behind an account-level flag; installing without access to it shows a message that the feature is not enabled for the account.

**Why**

This would let plugins be distributed and installed as ordinary npm packages instead of requiring a marketplace entry, but since the feature is gated behind an account flag, most users won't see it yet.

- Flag `tengu_plugins_npm_marketplace`: Not enough to say (read for one account on one subscription tier against v2.1.275; 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
- Names: `@npm`, `--registry`
- Tier: Nothing to try yet
- Useful: 4/5
- Signal: 3/5
- Present in the build but not switched on

### Remote-control SDK-host lane can push model and effort picks into a live session

Remote control can now change the model or effort level of a running session

**What**

Two new capabilities, `applyModelPick` and `applyEffortSeed`, are now wired into the remote-control layer that connects a running session to a remote client or server. These let a remote client push a model change or an effort-level (reasoning effort) selection into a live session, with handling for cases where the requested change is refused and doesn't take effect.

**Why**

This lets someone controlling a Claude Code session remotely change which model it's using or how much reasoning effort it applies, without needing direct access to the session itself.

- Area: Remote Control
- Names: `applyModelPick`, `applyEffortSeed`
- Tier: Nothing to try yet
- Useful: 4/5
- Signal: 3/5

### Kitty terminal image protocol probing wired in but unresolved for most users

Claude Code now probes terminals for kitty's image-display protocol, though most users see no effect yet

**Unclear.** The finding does not say what feature will actually use terminalImages or when detection stops defaulting to pending.

**What**

Claude Code now actively probes the terminal it's running in to see whether it supports the kitty graphics protocol, a way for a terminal to display images directly. This adds a new capability entry, `kittyGraphics`, alongside existing checks like `extendedKeys`, `synchronizedOutput`, and `kittyKeyboard`, and the app now stores the decoded replies from that probe. A new `terminalImages` store keeps track of images so they can be resent or cleared when the screen redraws.

Detection defaults to "not asked yet" and stays pending unless forced with the `CLAUDE_CODE_FORCE_TERMINAL_IMAGES` environment variable.

**Why**

This is groundwork for showing images inline in supported terminals, but since detection defaults to pending for most users, it has no visible effect yet unless forced on.

- Area: Terminal Rendering
- Names: `kittyGraphics`
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### New "send now" keybinding interrupts the in-flight turn to submit the queue

A new "send now" keybinding submits your queued input immediately, cutting off the response still streaming in

**Unclear.** The finding does not say what key combination triggers this action.

**What**

A new keyboard action called `chat:sendNow` lets you send whatever is currently queued up right away. If Claude is still streaming a response when you use it, that response gets cut off (aborted) so your queued message can go out immediately.

**Why**

This gives you a way to jump the queue when you don't want to wait for the current turn to finish before your next input is sent.

- Area: Terminal UI
- Names: `chat:sendNow`
- Tier: Use it now
- Useful: 4/5
- Signal: 2/5

### New /plugin install --marketplace flag to install-and-add a marketplace in one step

/plugin install now takes a --marketplace flag to add the marketplace source and install the plugin in one step

**What**

The `/plugin install` command now supports a `--marketplace` flag: `/plugin install <plugin> --marketplace <source>`. This adds the plugin's marketplace source first and then installs the plugin, instead of requiring you to add the marketplace separately beforehand.

**Why**

This removes a manual step when installing a plugin from a marketplace you haven't added yet. Claude Code can activate the plugin as part of the install; the install summary tells you whether it did, or whether you need to run `/reload-plugins`.

- Area: Plugins
- Names: `/plugin install --marketplace`
- Tier: Use it now
- Useful: 4/5
- Signal: 2/5

### New /plugin install-from-source and npm-aware marketplace flows

/plugin gains install-from-source and can install npm-published plugins directly

**What**

The `/plugin` command (which manages Claude Code plugins) gained new install flows:

- an 'install-from-source' action that routes to add-marketplace, asking for confirmation with the plugin and its link origin

- a 'usage-error' fallback that routes back to the plugin menu instead of failing outright

- install now recognizes a `plugin@npm` spec and short-circuits directly to an npm-install path

**Why**

This makes it easier to install plugins straight from a source or from npm without going through extra steps, and handles usage mistakes more gracefully by returning to the menu instead of erroring out.

- Area: Plugins
- Names: `/plugin install`
- Tier: Use it now
- Useful: 4/5
- Signal: 2/5

### Subagent concurrency cap enforced by default, with a kill switch and CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS env var

Subagents now hit a default cap of 20 concurrent runs, adjustable via CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS

**What**

Claude Code now refuses to launch another subagent (a separate Claude instance spawned to work on a sub-task) once 20 are running at the same time by default. Trying to go over the limit returns a message telling the user to raise it. The cap can be changed with the `CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS` environment variable, which accepts a positive whole number in plain digits; anything else is ignored, so this setting can raise or lower the cap but can't be used to turn it off entirely.

**Why**

The environment variable and the counting behind it already existed; what's new is that the limit is now actively enforced, so runaway or accidental fan-out of subagents is stopped rather than left to grow unbounded.

- Flag `tengu_amber_kestrel`: Not enough to say (read for one account on one subscription tier against v2.1.275; 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: Subagents
- Names: `CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS`
- Tier: Use it now
- Useful: 4/5
- Signal: 2/5

### SubagentStop hook event

A SubagentStop hook now fires when a subagent finishes, alongside the existing SubagentStart hook

**What**

Hooks are user-configured scripts that run automatically at specific points in Claude Code's operation. The internal hook-event handling now treats `SubagentStop` the same way it already treats `SubagentStart`, which means a Stop-style hook can now fire when a subagent (a separate Claude instance handling a sub-task) finishes, not just when one is spawned.

**Why**

This gives users a way to run a hook specifically when a subagent completes its work, complementing the existing `SubagentStart` hook that fires when one is spawned.

- Area: Hooks
- Names: `SubagentStop`
- Tier: Use it now
- Useful: 4/5
- Signal: 2/5

### Artifact list/read responses now expose per-artifact edit ('writer') access for shared artifacts

Shared artifacts can now be edited by people given edit access, not just read

**What**

When listing or reading artifacts (documents Claude creates and shares, like code or reports), Claude Code now reports whether a shared artifact is editable ('writer' access) for the person viewing it. Shared artifacts with edit access can now actually be updated, where previously all shared artifacts were read-only regardless of permissions.

**Why**

This lets people collaborate on a shared artifact when they've been explicitly given edit rights, instead of everyone but the owner being stuck with a read-only copy.

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

### Artifact publish: file-not-found handling gains restore-from-Artifact recovery

Claude Code can now restore a missing Artifact file from its last published version

**What**

If the file backing a previously published Artifact goes missing, for example because a session resumed on a different machine or its temporary files were cleared, Claude Code can now detect this and restore the last-published version of the file to disk so it can be re-edited and re-published. Distinct messages are shown depending on whether the file can be read, is blocked, or is gone entirely.

**Why**

Previously a missing backing file would likely have blocked further edits to a published Artifact. This recovery path lets work continue without losing the published content.

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

### Artifacts can be published by someone with write (not just owner) access

Artifacts can now be published by anyone with write access, not only the owner

**What**

Publishing or writing to an artifact you don't own is now allowed without an extra prompt, as long as you have writer or owner access to it, the change isn't going public, and the artifact wasn't shared with you via another organization. This is tracked through new `canWrite` and `invitedByOtherOrg` fields, and the artifact URL tool's description was updated to say an artifact must be one the person owns or was given edit access to (shown as 'writer').

**Why**

This lets collaborators who've been given write access to an artifact actually publish changes to it, instead of that ability being limited to the original owner.

- Area: Artifacts
- Names: `canWrite`
- Tier: You'll notice
- Useful: 4/5
- Signal: 2/5

### Instruction-file (CLAUDE.md/AGENTS.md) discovery reworked for nested project roots

CLAUDE.md/AGENTS.md discovery reworked to walk parent folders and dedupe files in nested projects

**What**

The built-in mechanism that loads project instruction files (`CLAUDE.md` and `AGENTS.md`) was substantially rewritten. It now resolves the session's root folder and walks up through parent folders to find nested instruction files, then de-duplicates the combined list of project, local, user, and memory files by both file path and trimmed content.

**Why**

This should make instruction-file loading more reliable in projects with nested folders that each have their own `CLAUDE.md` or `AGENTS.md`, avoiding duplicate or missed instructions.

- Area: Project Config
- Names: `CLAUDE.md`, `AGENTS.md`
- Tier: You'll notice
- Useful: 4/5
- Signal: 2/5

### Hooks can be disabled per-agent via settingsHooksOff

A new settingsHooksOff option can disable all hook execution for a given agent or subagent run

**Unclear.** The finding doesn't say what user-facing setting or scenario sets `settingsHooksOff`, so how a user would trigger this isn't clear.

**What**

Several internal functions responsible for assembling and running hooks (user-configured scripts that run at specific points, including agent-context hooks) now check for a new `settingsHooksOff` option. When it's set to `true`, they short-circuit and skip running any hooks entirely for that agent or subagent run.

**Why**

This provides a way to fully disable hook execution for a specific run, which is useful for situations where hooks shouldn't fire, such as isolated or internal subagent invocations.

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

### Marketplace add gains an opt-in strict name-collision refusal

Marketplace add gets an opt-in refuseNameCollision option to stop silent overwrites

**What**

The logic behind adding a marketplace now accepts an options object with a `refuseNameCollision` setting. When it's turned on, trying to add a marketplace whose name already exists but points to a different source now throws an error instead of silently overwriting the existing entry.

**Why**

This prevents accidentally replacing an existing marketplace's source under the same name when the stricter option is used.

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

### New "limit wall" promo banner system, tied to five-hour rate limits

A new dismissible promo banner can appear when you hit the five-hour usage limit

**What**

Claude Code has a new dismissible promotional banner tied to hitting the five-hour rate limit (the 'limit wall'). Clicking it opens a claim page, either in the browser or via a desktop path, and if the underlying configuration can't be reached, it shows the message "This offer isn't available right now." The banner's appearance, dismissal, and clicks are all tracked with their own telemetry events.

**Why**

This gives Claude Code a way to surface offers or promotions to users at the moment they run into rate limits, though whether and how it appears depends on server-side rollout.

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

### New --local CLI flag recognized alongside --brief/--remote-control/--rc

Claude Code's CLI argument parser now recognizes a new --local flag

**Unclear.** What `--local` controls or enables is not shown by the evidence.

**What**

The list of recognized CLI flags now includes `--local`, alongside existing flags like `--brief`, `--remote-control`, and `--rc`.

**Why**

The finding does not say what `--local` does; it only shows that argument parsing now recognizes it.

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

### New env var CLAUDE_CODE_PARKED_PERMISSION_WAIT_MS with 2000ms fallback

New CLAUDE_CODE_PARKED_PERMISSION_WAIT_MS env var sets a 2 second default wait for parked permissions

**What**

A new environment variable, `CLAUDE_CODE_PARKED_PERMISSION_WAIT_MS`, controls a wait time used in logic around "parked" permissions and resuming a turn. If it isn't set, it defaults to 2000 milliseconds (2 seconds). It appears alongside other related environment variables: `CLAUDE_CODE_RESUME_INTERRUPTED_TURN`, `CLAUDE_CODE_ADOPT_UNDERIVABLE_PARKED_PERMISSION`, and `CLAUDE_CODE_PARKED_STOP_RETIRES`.

**Why**

This gives more control over timing in the logic that resumes interrupted turns and handles permission requests that were left pending ('parked'), building on the existing `CLAUDE_CODE_RESUME_INTERRUPTED_TURN` recovery behavior, which was previously narrowed to remote sessions and fixed to report unfinished background tasks after a local `claude -p --resume`.

- Area: Permissions
- Names: `CLAUDE_CODE_PARKED_PERMISSION_WAIT_MS`, `CLAUDE_CODE_RESUME_INTERRUPTED_TURN`, `CLAUDE_CODE_ADOPT_UNDERIVABLE_PARKED_PERMISSION`, `CLAUDE_CODE_PARKED_STOP_RETIRES`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### New model-source category 'settings_env_default' for ANTHROPIC_DEFAULT_*_MODEL env vars

Model source attribution gains a settings_env_default category for ANTHROPIC_DEFAULT_*_MODEL variables

**What**

Claude Code now recognizes environment variables matching the pattern `ANTHROPIC_DEFAULT_[A-Z]+_MODEL`. When the model-attribution mode is set to `env`, the model's source is now reported as `settings_env_default` instead of falling through to the remap, agent, or settings logic that previously handled it.

**Why**

This gives a more accurate and specific label for why a particular model was selected when it comes from one of these default-model environment variables, rather than lumping it in with other attribution paths.

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

### Plugin API: ui.log gains a `to` destination field

Plugin ui.log gains a to field to route output to the transcript or a debug-only log

**What**

The `ui.log` operation, which plugins use to write log output, now accepts a `to` parameter that chooses where the text goes: either the normal visible UI log ("transcript") or a debug-only log line. Previously, `ui.log` always appended to the visible UI log.

**Why**

This lets plugin authors send diagnostic or debug output to a separate debug log instead of cluttering the visible transcript that users see.

- Area: Plugin API
- Names: `ui.log`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### Plugin test engine now exposes a UI-render client harness (`ui.mount`/`act`)

Plugin test engine used by `claude plugin test` gains a UI-render test harness with mount/act/release methods

**What**

The plugin-testing engine used by `claude plugin test` now includes a `clients` object for testing plugin user interfaces directly. It provides `record`, `mount`, `act` (covering drawing, key presses, pointer input, posting, advancing, and unmounting), and `releaseAll` methods. When a plugin's test sends a `ui.render` operation, the engine now feeds the resulting render tree into this new recorder, and shutting down the test engine now also releases all mounted UI clients.

**Why**

This gives plugin authors a way to simulate and drive a plugin's rendered interface within `claude plugin test`, rather than only being able to inspect render output passively.

- Area: Plugin Testing
- Names: `ui.mount`, `act`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### Scheduled/autonomous-loop task wakeups can be disabled per component instance

Scheduled task wakeups, including /loop, can now be disabled per component instance

**What**

The component responsible for scheduled tasks, which handles `/loop`, cron-style scheduled prompts, and teammate task notifications, now accepts a `disabled` setting. When set, it skips all of its scheduling behavior, including firing handlers, randomized timing jitter, and extra routine cron tasks.

**Why**

This lets scheduled-task behavior be turned off for a given instance of the component, which is useful in contexts where scheduled wakeups shouldn't run.

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

### Slash-command drafts can now be filled by insertion or append, not just full replace

Text can now be appended or inserted into the input box draft, not just fully replaced

**What**

The internal mechanism plugins and hooks use to fill in the input box's draft text gained a mode option. Previously it only replaced the entire draft; now it can also `append` text to the end of the current draft or `insert` text at the cursor position. A companion function to read the current draft text and cursor position was also added.

**Why**

This lets plugins and hooks add to or insert into what's already typed in the input box, instead of only being able to overwrite it entirely.

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

### Sub-agent spawn budget switched from a fixed total+concurrency cap to a single, env-configurable concurrency cap

Sub-agent spawning now limits only concurrent spawns, with the limit configurable instead of hardcoded

**What**

The `$.agent.spawn` hook API previously blocked new sub-agent spawns once a fixed lifetime total was reached, on top of a fixed concurrency limit. That lifetime cap is gone. Now only a concurrency cap remains (how many spawns can run at the same time), and its value is computed rather than a fixed constant. A refused spawn now reports 'refused: ${w} spawns are running at once'.

**Why**

Removing the lifetime total means sub-agents are no longer capped by how many have been spawned in total, only by how many are running simultaneously, and that limit can now vary instead of being a single fixed number.

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

### Text renderer gains a `monochrome` prop that strips color

Text rendering now supports a monochrome mode that strips out color

**What**

The core text-rendering component used to draw terminal output, along with the markdown and syntax-highlighting renderer built on top of it, now accepts a `monochrome` setting. When turned on, it clears any color from the text before displaying it, so the output uses only plain, dim, or italic styling with no color codes.

**Why**

This makes it possible to render output without color, which is useful for terminals or contexts that don't support ANSI colors, or where colored output is undesirable.

- Area: Terminal Rendering
- Names: `monochrome`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### Two new passthrough environment variables: CLAUDE_CODE_DISABLE_ATTRIBUTION_CROSS_REPO and CLAUDE_CODE_SDK_HAS_OAUTH_REFRESH

Two new environment variables are now recognized: CLAUDE_CODE_DISABLE_ATTRIBUTION_CROSS_REPO and CLAUDE_CODE_SDK_HAS_OAUTH_REFRESH

**Unclear.** What CLAUDE_CODE_DISABLE_ATTRIBUTION_CROSS_REPO actually does, and whether it changes CLAUDE_CODE_SDK_HAS_OAUTH_REFRESH's existing behavior, isn't stated.

**What**

Claude Code now recognizes and passes through two additional environment variables: `CLAUDE_CODE_DISABLE_ATTRIBUTION_CROSS_REPO` and `CLAUDE_CODE_SDK_HAS_OAUTH_REFRESH`. The former is added to the general list of recognized environment variables, and the latter appears in an SDK-related context.

**Why**

The finding doesn't say what effect either variable has beyond being recognized, so no further behavior can be stated.

- Area: Env Vars
- Names: `CLAUDE_CODE_DISABLE_ATTRIBUTION_CROSS_REPO`, `CLAUDE_CODE_SDK_HAS_OAUTH_REFRESH`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### New keybindings to send a message immediately

Two new key combos, ctrl+x ctrl+s and ctrl+enter, now send a chat message immediately

**What**

Two new key chords were added to the chat keymap, both mapped to the `chat:sendNow` action: `ctrl+x ctrl+s` and `ctrl+enter`. These join the existing `enter` and `ctrl+x enter` bindings that already send a message.

**Why**

This gives users more ways to send a message immediately, without changing the behavior of the existing bindings.

- Area: Terminal UI
- Tier: Use it now
- Useful: 4/5
- Signal: 1/5

### CLAUDE_CODE_POLL_EVENTS gate simplified — extra guard conditions removed

CLAUDE_CODE_POLL_EVENTS alone can once again switch on poll-event delivery

**What**

The function that decides whether Claude Code uses poll-based event delivery previously required two additional internal conditions to be true on top of the `CLAUDE_CODE_POLL_EVENTS` environment variable. Those extra conditions have been removed, so the function now only checks `CLAUDE_CODE_POLL_EVENTS`.

**Why**

This reverses a prior change that had required the SDK or streaming-input entry path to separately confirm that event ingress was wired before the environment variable would take effect. Now, setting `CLAUDE_CODE_POLL_EVENTS` is sufficient on its own again.

- Area: Poll Events
- Names: `CLAUDE_CODE_POLL_EVENTS`
- Tier: Use it now
- Useful: 2/5
- Signal: 2/5

### $.model.complete maxTokens is now validated against the actual model's output ceiling, not a fixed global cap

$.model.complete's maxTokens limit now matches each model's real output ceiling instead of one fixed number

**What**

The hook API's `$.model.complete` previously rejected any `maxTokens` value above a single hardcoded limit of 8192, regardless of which model was being used. It now looks up the actual output ceiling for the specific model being called (still capped globally at a larger number) and rejects requests that exceed it with 'maxTokens ${s} is past what ${w} can produce in one reply (${O})'.

**Why**

Models that can produce longer replies than 8192 tokens are no longer artificially capped, while models with smaller limits are still protected from requesting more than they can actually return.

- Area: Plugin API
- Names: `maxTokens`
- Tier: Use it now
- Useful: 3/5
- Signal: 1/5

### '/plugin install' gains explicit --marketplace disambiguation

'/plugin install' gets an explicit --marketplace flag with clearer error messages and autocomplete

**What**

The `/plugin install` command (part of `/plugin`, which manages Claude Code plugins) now has explicit support for a `--marketplace <source>` flag, also usable as `--marketplace=<source>`, to specify which marketplace to install a plugin from. It now gives clear usage errors when the source is missing, when the wrong number of arguments is given, or when a plugin name already embeds its own `@<marketplace>` suffix alongside the flag.

- Typing `plugin install <name>` without a marketplace flag, where the name matches a known plugin that has no marketplace set, now offers a `--marketplace` autocomplete suggestion to add the source.

**Why**

This makes it clearer and less error-prone to specify exactly which marketplace a plugin should be installed from, especially when a plugin name could be ambiguous.

- Area: Plugins
- Names: `/plugin install`
- Tier: Use it now
- Useful: 3/5
- Signal: 1/5

### 'icon' field replaces deprecated 'favicon' in artifact publish, with new writer-access disclosure on read/list

Artifact icon field replaces the deprecated favicon parameter, and read/list now shows write access

**What**

The artifact tool's `favicon` parameter is now deprecated; Claude no longer uses it and relies instead on a new `icon` field, which takes a single generic word rather than an emoji. Separately, artifact `read` and `list` results now disclose whether the current reader has write ('writer') access to the artifact.

**Why**

The `icon` field replaces an inconsistent, emoji-based way of setting an artifact's icon. Disclosing writer access on `read` and `list` lets Claude know whether it's allowed to republish updates to a shared artifact before attempting to do so.

- Area: Artifacts
- Names: `icon`
- Tier: Use it now
- Useful: 3/5
- Signal: 1/5

### Artifacts tool: 'favicon' parameter deprecated in favor of 'icon'

Artifacts tool replaces the emoji 'favicon' field with a required, plain-word 'icon' field

**What**

The Artifacts tool no longer uses the `favicon` parameter, which previously took one or two emoji. It's replaced by a new `icon` parameter, which takes a single descriptive word (like chart, calendar, recipe, code, or map) instead of an emoji, and explicitly disallows product or brand names.

- `favicon` is now deprecated; supplying it returns an error telling you to use `icon` instead, rather than validating it as an emoji

- `icon` becomes required the first time a page is published, where `favicon` used to be optional

- `icon` is described as controlling the artifact's browser-tab icon

**Why**

This changes how Artifacts publishers specify a tab icon: instead of picking an emoji, they now describe the icon's concept in one plain word, and omitting it will fail on first publish since it's now required.

- Area: Artifacts
- Names: `icon`
- Tier: Use it now
- Useful: 3/5
- Signal: 1/5

### Artifacts: multi-file upload and asset-copy actions documented

Artifacts tool can now upload several files at once or copy assets from another artifact

**What**

The artifacts tool (used to build and publish files like documents or small apps) now supports two new ways to bring in files:

- `file_paths`: upload several local files as assets in one call, instead of one at a time with the existing `file_path`.

- `copy_from`/`asset_ids`: copy assets directly from another artifact on the server, without re-uploading them.

**Why**

This saves time when an artifact needs multiple assets, or needs assets that already exist in a different artifact, since they no longer have to be uploaded one by one or re-fetched locally first.

- Area: Artifacts
- Tier: Use it now
- Useful: 3/5
- Signal: 1/5

### New 'Add marketplace?' confirmation prompt with y/n gate

Claude Code now shows an 'Add marketplace?' confirmation before adding a plugin marketplace

**What**

When adding a plugin marketplace through a confirm-style flow (for example, from a plugin recommendation), Claude Code now shows a new confirmation screen titled `Add marketplace?` before the marketplace is actually added. It displays the resolved source, an optional warning if a version is pinned, and asks for a yes/no answer before proceeding.

**Why**

This gives you a chance to review what's being added and where it comes from before a marketplace source is registered, instead of it being added silently.

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

### New keyboard action: send queued input immediately

New keyboard action sends a queued message immediately instead of waiting

**Unclear.** Whether sendQueuedNow is bound to a specific key or keyboard shortcut is not stated.

**What**

A new action, `sendQueuedNow`, is available alongside the existing `submitEmpty` action. Both now share a common internal accessor. `sendQueuedNow` immediately sends whatever command is currently queued up, firing a telemetry event called `input_send_now_key`, separate from the event `submitEmpty` fires.

**Why**

This gives a way to force a queued message to send right away instead of waiting for it to go out on its own, likely via a dedicated keyboard shortcut.

- Area: Terminal UI
- Names: `sendQueuedNow`
- Tier: Use it now
- Useful: 3/5
- Signal: 1/5

### New self-hosted-runner drain grace: SELF_HOSTED_RUNNER_POST_TURN_SETTLE_MS

Self-hosted runners now wait briefly after a turn finishes before shutting down, so results aren't lost

**What**

When a self-hosted runner is told to drain (stop accepting new work and shut down), it now treats a turn that just finished as still "in flight" for a short grace period, until the session process confirms to the server that the turn has actually ended. This period is controlled by a new environment variable, `SELF_HOSTED_RUNNER_POST_TURN_SETTLE_MS`, which defaults to about 2 seconds. The runner's startup log now reports this setting as `post-turn-settle`.

**Why**

Without this grace period, a runner shutting down (via `SIGTERM`, the signal used to stop a process) right after a turn appears complete could lose that turn's result before it was fully reported. This change closes that small window so results aren't silently dropped during a drain.

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

### Terminal now supports ctrl+c copy-of-selection inside the resume/session-picker screen, active only in fullscreen mode

Ctrl+C now copies selected text within the session resume/picker screen, but only in fullscreen mode

**What**

A new wrapper around the resume-conversation and session-picker screens (the "Loading conversations…" and "Resuming conversation…" views) adds support for copying selected terminal text with ctrl+c (or super+c on some systems). Pressing it while text is selected copies that selection, or clears the copy if it was already copied. This behavior is only active when the terminal is running in fullscreen mode.

**Why**

This lets users copy text they've selected while browsing or resuming past sessions, something that previously wasn't wired up on that particular screen, though only when running in fullscreen mode.

- Area: Terminal UI
- Tier: Use it now
- Useful: 3/5
- Signal: 1/5

### artifact tool: upload_asset accepts multiple files in one call

Artifact upload_asset can now upload multiple files in a single call

**What**

The `upload_asset` action, part of the artifact tool, can now accept a `file_paths` list to upload several files at once, in addition to the existing single `file_path` option. A separate handler processes these batch uploads, and a new error, `asset_upload_pin_mismatch`, appears if an upload that was approved as a batch is retried as a single file (or the other way around).

**Why**

This saves repeated `upload_asset` calls when adding multiple assets to an artifact at once, and the new error guards against a mismatch between what was approved and what actually gets uploaded.

- Area: Artifacts
- Names: `upload_asset`, `file_paths`
- Tier: Use it now
- Useful: 3/5
- Signal: 1/5

### upload_asset gains a multi-file mode

The artifact upload tool can now upload several local files at once

**What**

The `upload_asset` artifact tool now accepts a `file_paths` array, letting several local files be uploaded into one artifact in a single call, alongside the existing single-file `file_path` option. When multiple files are uploaded, Claude Code now shows a readable summary like "3 files · "a.png", "b.png", 1 more" instead of listing them individually.

**Why**

This saves multiple round trips when adding several assets to an artifact at once, and the summary keeps the upload confirmation readable even with many files.

- Area: Artifacts
- Names: `file_paths`
- Tier: Use it now
- Useful: 3/5
- Signal: 1/5

### 32-command-per-plugin registration cap removed

Plugins can now register more than 32 slash commands

**What**

Plugins that register slash commands using functionHooks used to hit a hard limit of 32 commands per plugin. Trying to register a 33rd command failed with an over_limit error. That limit and the check enforcing it have been removed entirely.

**Why**

Plugin authors can now register as many commands as they need without running into an arbitrary registration ceiling.

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

## New Features

### Forked agent runs can report token usage per-request

Forked agent runs can now report token usage as it streams in, not just at the end

**What**

When Claude Code runs a forked agent (a subagent branched off to do a separate task), it can now report token usage incrementally through a new `onRequestUsage` callback as responses stream in, in addition to the final total usage it already reported.

**Why**

This lets code that manages forked agents track token consumption in near real time rather than waiting until the run finishes.

- Area: Subagents
- Names: `onRequestUsage`
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 2/5

## Improvements

### Artifacts: new 'source restore' read path and Artifact Types catalog

New backend support for restoring a published Artifact's source and reading Artifact Types

**What**

A large new module adds the ability to read back the published source of an Artifact (a piece of generated content Claude Code can publish, such as a document or app) through a new `artifact_source_restore` path. It reports detailed reasons when this fails, including permission checks, blocked outbound network access, organization mismatches, read timeouts, version lag, and warnings when another writer has changed the content.

Alongside this, new plumbing supports "Artifact Types": reading a type's catalog entry, its instruction file, and the content of individual files within it via `artifact_type_link_read`. This is tied to a feature state called `frozenArtifactTypes`.

**Why**

This lays groundwork for Claude Code to fetch back and inspect previously published Artifacts and their type definitions, with clearer error messages when that read fails.

- Flag `tengu_cobalt_plinth_moss`: On for this account, and not off by default (read for one account on one subscription tier against v2.1.275; 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: Artifacts
- Tier: You'll notice
- Useful: 3/5
- Signal: 3/5

### Reminders can now carry attached media, not just text

System reminders inserted into a conversation can now include attached media, not just text

**What**

Reminders — short system-generated notes inserted into the conversation, either attached to something the user typed or as their own standalone message — can now carry a `media` array of attachments alongside their text.

**Why**

This allows reminders to include images or other media content rather than being limited to plain text.

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

### Poll events can now carry media (images/PDFs)

Poll events delivered to agents can now include media like images or PDFs

**What**

The delivery loop that passes poll events (updates delivered to teammates or agents) to their recipients was rewritten. It now attaches a `media` array to delivered content whenever an event carries media, restricted to base64-encoded images (JPEG, PNG, GIF, or WebP) or PDF documents.

**Why**

This lets poll-event delivery carry images and PDFs along with the text of an update, rather than text only.

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

### Artifacts read/list now reports and enforces writer vs viewer access

Artifact read/list actions now report and enforce whether you have edit access, not just view access

**What

The `read` action on an artifact now states in its result whether the person has edit access to it (marked as "writer"), and if so, names the local file that backs a re-publish. The `list` action now explains that a shared artifact can only be updated in place if the person has edit access, as determined by a `read` call; otherwise Claude must publish a separate, new artifact instead of updating the existing one. `list` also now notes that artifacts shared from another organization may not appear in the listing at all.

**Why**

This prevents Claude from trying to update a shared artifact it doesn't actually have permission to edit, and makes clear when a fresh, separate artifact needs to be published instead.

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

### Turn handoff can now carry a memory_context line

Turn handoffs between agents can now carry an optional memory_context line

**What**

When one turn hands off to another (for example, between agents), the handoff validation logic now looks for an optional `memory_context` field in the handoff data. If it's present, valid, and its identifier isn't already in use, Claude Code attaches a `cowork_memory_context` memory line, including its version and content, to the accepted handoff. If the `memory_context` is malformed or conflicts with an existing one, it's logged and the turn simply proceeds without it rather than failing.

**Why**

This lets relevant memory context travel along with a handoff between turns or agents, while failing safely (by just dropping the invalid data) if that context turns out to be malformed, so a bad memory_context doesn't block the turn from completing.

- Area: Turn Handoff
- Names: `memory_context`
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 2/5

### New MCP connection failure diagnostics: error_code enum surfaced to hosts

MCP server connection failures now report a specific error code explaining why

**What**

When a connection to an MCP server (Model Context Protocol, used to connect Claude Code to external tools and data) fails, the status output now includes an `error_code` field giving a specific reason, such as a rejected claude.ai login token, a rejected first-party Anthropic credential, or a connection that's pending approval.

**Why**

This makes it clear why an MCP connection is failing, such as needing to sign in again, instead of just showing a generic failure with no explanation.

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

### New telemetry gate for OpenTelemetry header-helper failures

New warning notification when the OpenTelemetry headers helper fails, pointing to /status

**What**

Claude Code now shows a dismissible warning notification, visible for 30 seconds, when the `otelHeadersHelper` fails. This helper generates rotating [OpenTelemetry](/docs/en/monitoring-usage#dynamic-headers) headers using a command you supply. The warning tells you that telemetry is not being exported and to check `/status` for details.

**Why**

Without this warning, a failing headers helper could silently stop telemetry export with no visible sign. The notification makes the failure noticeable and points to `/status` to investigate further.

- Flag `tengu_quirky_teacup`: Not enough to say (read for one account on one subscription tier against v2.1.275; 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: Telemetry
- Names: `/status`
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### Artifact write auto-approval for routine, private, own-org writes

Routine, private writes to your own org's artifacts can now skip the approval prompt

**What**

Claude Code's permission logic for writing to artifacts (files or outputs Claude creates) has a new automatic-approval path. A write is now approved without asking the user when all of the following are true:

- it's a routine write

- the artifact is not public

- the caller already has write access

- the write wasn't invited by another organization

This applies even when the turn wasn't started by a human.

**Why**

This cuts down on unnecessary approval prompts for writes that are low-risk and entirely within the user's own organization, while writes involving other organizations or public artifacts still go through the normal ask path.

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

### Offline/fallback model catalog switches ccr/ccd default model from Sonnet 4.6 to claude-opus-5

Fallback model list now defaults 'ccr' and 'ccd' to claude-opus-5 instead of Sonnet 4.6 when the live catalog is unreachable

**What**

Claude Code ships a signed, static backup list of models to use if it can't fetch the live model catalog. In this release, the default model for two of the listed surfaces, 'ccr' and 'ccd', changed from `claude-sonnet-4-6` to `claude-opus-5`. The 'cc' surface entry was already set to `claude-opus-5` and is unchanged.

**Why**

If Claude Code ever falls back to this offline catalog, users on the 'ccr' and 'ccd' surfaces will now get `claude-opus-5` by default instead of `claude-sonnet-4-6`.

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

### Artifact list/read results now report per-artifact writer access instead of an org-wide 'shared' bucket

Artifact permissions now check per-artifact edit access instead of whether you belong to the artifact's organization

**What**

The descriptions for the `list` and `read` artifact tools changed how they describe permissions. Previously, an artifact showed a favicon in listings and could only be updated by someone in the same organization as its owner. Now, reading an artifact directly reports whether the current user has "writer" access to it, and only that per-artifact writer access, not organization membership, determines whether Claude can republish someone else's artifact.

**Why**

This makes sharing more precise: someone can be given edit rights to a specific artifact without needing to belong to the same organization as everyone else who can edit it.

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

### Artifact write consent now distinguishes edit-access-by-another-org from ownership

Artifact write permissions now separate editor access granted by another org from actual ownership

**Unclear.** The finding does not say what the different treatment actually looks like for the user.

**What**

Artifact permission logic gains two new fields, `invitedByOtherOrg` and `canWrite`, computed by probing the artifact's role and mode. These feed directly into the write-consent decision, so Claude Code can now tell apart an artifact you own from one where someone in a different organization gave you editor access.

**Why**

This lets Claude Code apply different consent handling when writing to an artifact you don't fully own but were invited to edit by another org, rather than treating all editable artifacts the same way.

- Area: Artifacts
- Names: `invitedByOtherOrg`, `canWrite`
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### Cross-organization artifact asset copying, with new consent gate

Copying assets between artifacts across organizations now requires explicit approval

**What**

Artifacts (Claude Code's generated documents/apps) can copy assets from one artifact into another. This copy action now recognizes when the source artifact belongs to a different organization than the destination, and handles it explicitly:

- Copying from a public artifact outside your organization now shows a specific approval prompt before proceeding.

- Copying from an artifact shared directly from another organization shows a similar, separate approval prompt.

- If the destination artifact belongs to another organization, the copy is refused outright, with a message explaining that assets can only be copied into artifacts in your own organization.

- If the server doesn't yet support cross-organization copying, the tool now gets a distinct error telling it not to retry, instead of failing unclearly.

- Artifacts shared from another organization aren't yet listed automatically, so the user needs to supply the link directly.

This builds on the permission-rule checks already added for artifact copying: a new consent mechanism specifically for cross-organization copies now sits alongside it, so a human must approve before an outside-organization copy proceeds.

**Why**

This closes a gap where assets could move between organizations' artifacts without anyone being asked, giving users an explicit checkpoint before content crosses an organizational boundary.

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

### Cross-organization artifact reads now tracked and flagged as untrusted input

Content read from another organization's artifact is now explicitly flagged as untrusted

**What**

Claude Code now tracks, per tool use, whether the user has consented to reading artifacts belonging to another organization. When content from such an artifact (either shared directly from another organization, or a public artifact from outside the user's organization) is included, it's now given an explicit warning label instructing that it be treated as untrusted input.

**Why**

This reduces the risk of content from outside an organization being treated as trustworthy instructions or data by default, similar to how other external content is already handled.

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

### Working-directory anchors now support multiple session working directories, not just one

Path validation for publishing and reading artifacts now accounts for multiple session working directories, not just one

**What**

Claude Code validates file paths against a set of allowed "anchor" locations, such as the current working directory, when checking where artifacts can be published or read from. Previously this logic assumed a single working directory plus a scratchpad. It now works from a general list that also includes any additional configured working directories, each labeled by kind (`cwd`, `dir`, or `scratchpad`). Error messages about disallowed paths now list all of the session's working directories instead of just one.

**Why**

Sessions that work across more than one directory get accurate validation and clearer error messages instead of being checked against only a single assumed location.

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

### Project-scope MCP server and scheduled-task edits blocked under --project-config-root

Sessions started with --project-config-root can no longer edit project-scope MCP servers or create durable scheduled tasks

**What**

When a session is started with the `--project-config-root` flag, Claude Code now blocks two things:

- adding or removing project-scope MCP servers (connections to Model Context Protocol tool servers)

- creating durable scheduled tasks

Both now throw an error directing the user to use the local or user scope instead.

**Why**

This prevents project-scope changes that wouldn't make sense or wouldn't be reliably saved when the session's project config root has been overridden, pointing users to a scope that will work correctly instead.

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

### Sandboxed shebang/interpreter reach-checking now understands per-interpreter safe-flag grammars

Sandbox checks now recognize safe argument flags for many more scripting-language interpreters

**What**

When Claude Code's sandbox checks whether a script invoked via a shebang line (the `#!/usr/bin/...` line that names an interpreter) is safe to run, it now uses a large table of argument grammars specific to each interpreter, including bash, dash, zsh, node, Rscript, osascript, fish, tclsh, wish, python, perl, ruby, awk, sed, php, csh, expect, and make. Previously this check was simpler and less permissive.

**Why**

Scripts that invoke a recognized interpreter with known-safe flags can now be judged safe more accurately, rather than being treated conservatively across the board.

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

### Security hardening for git/ssh URL credential and host obfuscation

Claude Code now detects hidden or spoofed hosts in git/ssh/http(s) URLs and redacts credentials from them

**What**

A set of new URL-parsing checks now looks for tricks that can hide or spoof the real destination of a git or ssh URL, such as a percent-encoded '@' (`%40`), a backslash, or IPv6-bracket formatting used to disguise the host. These checks feed into two things: redacting any embedded credentials before a URL is shown, and deciding whether a URL should be trusted.

**Why**

Malicious repositories or links sometimes disguise a URL so it looks like it points to a trusted host when it actually points somewhere else, potentially exposing credentials. This hardens Claude Code against that kind of spoofing.

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

### New cross-organization restriction on copying artifact files during publish

Publishing an artifact now blocks copying files from another organization's artifact unless ownership is confirmed

**What**

When publishing an artifact that copies files from another artifact via a `files` map, Claude Code now checks whether the source artifact belongs to a different organization. If it does and that ownership can't be confirmed, the whole publish is rejected with a new error. Separately, publishing is now explicitly denied outright when the destination artifact itself belongs to a different organization.

**Why**

This closes off a way that content could be copied across organization boundaries without proper ownership checks, protecting artifacts from being published into or sourced from an organization that shouldn't have access to them.

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

### Artifact publish: type-locking and 'routine republish' skip-ask logic

Artifact publishing now enforces type-locking and skips re-asking for routine republishes

**What**

The permission check run before publishing an Artifact now looks at the Artifact's type-lock and capabilities before deciding whether to ask for confirmation. Once an Artifact is type-locked, changing its `contract` or type is denied outright with a dedicated error message.

A new `routineRepublishedPaths` set and `routineUnasked` flag track republishes that are already known to be routine, so redeploying something that was already published routinely no longer prompts for confirmation again.

**Why**

This prevents accidentally changing a published Artifact's locked type, while also cutting down on repeated confirmation prompts for routine, already-approved republishes.

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

### Git-related environment variables and CLI flags now get pattern-matched for hardening

Claude Code now scans environment variables and git flags for tricks that redirect where git actually operates

**What**

Claude Code now checks environment variables and command-line flags for signs that something is trying to secretly redirect git operations or hijack the shell. This includes:

- Git environment variables like `GIT_DIR` and `GIT_WORK_TREE`, which can point git at a different repository or working folder than expected

- Shell variables like `CDPATH`, `PATH`, and `IFS` that can be abused to change how commands behave

- Git flags such as `--git-dir`, `--separate-git-dir`, `--namespace`, `core.worktree`, and `includeif.` that redirect where git reads its config or working tree, including shortened (abbreviated) forms of `--separate-git-dir` and `--working-directory`

This builds on earlier work (cloud file sync opening files through directory handles so a swapped symlink can't redirect a write) by extending the same kind of suspicion to git-specific environment variables and flags rather than just `GIT_DIR` and `GIT_WORK_TREE`.

**Why**

These variables and flags are legitimate git features, but an attacker who controls a repository or its config could use them to make git read or write files outside the folder you think you're working in. Catching them closes off a way that a malicious repo could quietly redirect Claude Code's git commands.

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

### Path checks for local-dir/owner-repo args now detect network-location symlinks

Directory and repo path arguments are now checked for symlinks that sneak in a network location

**What**

When Claude Code is given a path as a local-directory or owner/repo argument and needs to check it (via `stat`), it now does more validation first:

- It outright rejects Windows device-namespace paths (those starting with `\\?\` or `\\.\`), since these can't be safely checked for symlinks

- For other paths, it walks the chain of symlinks (the ancestry of links) to see if the path passes through a symlink pointing to a network location, or to a link target that can't be read

If either case is found, it refuses the path with a specific error instead of proceeding.

**Why**

A symlink pointing to a network location could let a path argument silently redirect Claude Code to read from or interact with a remote location instead of the local one you intended. Rejecting these cases up front avoids that kind of surprise redirection.

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

### New coordinator-only Bash guardrail restricting to verified read-only commands

A new guardrail restricts the coordinator role to read-only, verified Bash commands

**What**

A new check now restricts how the Bash tool can be used when invoked by "the coordinator" (a coordinating role in Claude Code). In that role, a Bash call:

- Must be verifiably read-only, checked using an AST-based (syntax-tree-based) command classifier

- May only pass the `command`, `description`, and `timeout` parameters

- Cannot use `run_in_background`, `cd`, `pushd`/`popd`, or bypass the sandbox

Anything that doesn't meet these rules is forced into a refused or ask-for-permission path, with an explicit message explaining why.

**Why**

This keeps the coordinator role from running commands that change state, move between directories, or escape sandboxing, limiting it to commands whose read-only nature can be verified rather than just assumed from their text.

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

### In-process ('script') tool calls can now trigger fork-agent availability and get plan/dontAsk fork restrictions

Forking a subagent from an in-process tool call is now blocked in plan and dontAsk permission modes

**What**

When a subagent (a secondary Claude instance handling part of a task) is launched from an in-process, tool-triggered call rather than a direct user action, Claude Code now checks the parent's permission mode. If the parent is in `plan` mode or `dontAsk` mode, forking a new agent is refused with a message explaining that the fork would otherwise run without the parent's restriction, and suggesting starting a fresh context instead.

**Why**

This closes a gap where a tool-triggered fork could bypass the stricter permission restrictions of `plan` or `dontAsk` mode, since a forked agent wasn't previously bound by the mode its parent was running under.

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

### REPL sandbox now scopes filesystem-looking strings to workspace roots instead of scanning code for imports

REPL sandbox check now matches file paths against workspace roots instead of scanning code for import statements

**What**

A helper function used by the REPL (the interactive code-execution environment) sandbox no longer inspects input as JavaScript looking for `require`/`import`-style statements to block with a "sealed vm context" error. Instead, it treats the input as a file path: it expands `$HOME` or `~` prefixes, normalizes the path, and checks whether it falls under one of the configured workspace roots, returning true or false instead of throwing an error.

**Why**

This changes the sandbox's filtering from code-pattern detection to path-based scoping, which is a more direct way to decide whether a given path is inside allowed workspace boundaries.

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

### Skill/command execution now restricted to composer or bridge message origins

Skills and slash commands now only run when triggered from the composer or a bridge message

**Unclear.** The finding does not say what other origins previously could trigger execution or what the placeholder text says.

**What**

Running a command (`command.run`) or a skill (`skill.prompt`) now checks where the request came from. It only actually executes if it originates from the composer (the message input box) or a bridge message; otherwise it returns a placeholder message instead of running.

**Why**

This restricts skill and command execution to trusted origins, preventing them from being triggered from other, less expected sources.

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

### plugin.command.run character-limit check silently removed

Plugin command.run no longer rejects overly long arguments, only logs their length

**What**

The check that runs before a plugin's `command.run` operation executes used to reject the call with an error if its arguments exceeded a maximum length. That rejection has been removed: the check now only records the argument length for telemetry (internal usage tracking) and always allows the call to proceed.

**Why**

Plugin commands with very long arguments that would previously have been blocked can now run instead, since the length limit is no longer enforced, only measured.

- Area: Plugin API
- Names: `command.run`
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### Gateway sign-out now revokes OAuth tokens on the gateway

Signing out now revokes your OAuth tokens on the gateway server, not just locally

**What**

When you sign out of a gateway (a login/authentication server Claude Code connects through), Claude Code now tries to revoke both your session token and, if present, your identity provider's refresh token directly on the gateway. It finds the right endpoint to call by looking up the gateway's `.well-known/oauth-authorization-server` metadata. If that lookup or the revocation call fails, Claude Code logs the failure and falls back to simply ending the session on your local machine.

**Why**

Previously, signing out only cleared credentials locally, so a stolen or leaked token could potentially still be used elsewhere. Actively revoking the tokens on the server closes that gap when the gateway supports it.

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

### Artifact publish no longer requires a favicon

Publishing an artifact no longer requires a favicon, only a file path

**What**

Publishing an artifact used to require both a `file_path` and a favicon, failing with errors like "file_path and favicon are required to publish" or "favicon required to publish" if either was missing. Now only `file_path` is required. Along with this:

- The read-back result for a published artifact no longer includes a favicon field

- The code that fetched or derived a favicon, and threw an error when one couldn't be resolved, has been removed

- The HTML-page publish error message dropped its favicon requirement entirely

- The eval-report publisher now sends an empty favicon plus a new `icon` field instead of an emoji favicon

**Why**

This removes a requirement that could block publishing an artifact over something as minor as a missing icon.

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

### Command-from-link confirmation dialog added

Claude Code now asks for confirmation before running a command that came from a link

**What**

When a command is triggered from a link rather than typed directly, Claude Code now shows a confirmation prompt: "Run this command?", displays the command itself, and warns "Nothing runs until you answer. Only run commands from links you trust." The command only executes after the user answers yes or no.

**Why**

This stops a link from silently running a command on your behalf, giving you a chance to review it first and reducing the risk of a malicious or unexpected link triggering something you didn't intend.

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

### Artifact reads now append a Share menu summary describing who can access the artifact

Reading an artifact now includes a summary of who can access it based on its Share menu settings

**What**

When Claude Code reads an artifact (a generated document, app, or file shown in a side panel) that the user owns and that isn't locked to a specific type, the result now includes a plain-language summary drawn from the artifact's Share menu. This summary notes things like:

- whether a public link is unavailable

- whether the user's plan and organization allow sharing

- whether inviting people outside the organization by email is turned on or off

**Why**

This gives Claude visibility into an artifact's actual sharing and access settings, so it can accurately describe or reason about who can see or use it.

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

### Artifact read responses now carry a share-menu payload for owners

Reading an artifact as its owner now returns sharing-menu options in the response

**What**

When an artifact is read by its owner, the response can now include a `shareMenu` object listing which read access modes can be assigned to others, filtered from what the server allows. It may also include `externalSharing` and `externalInvites` flags, derived from permission data already returned when Claude Code starts up.

**Why**

This gives the owner-facing artifact view the information it needs to present sharing options directly, without a separate lookup.

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

### Audio playback: per-session play-count cap removed, only concurrency cap remains

Audio playback no longer caps the total number of plays per session, only how many can play at once

**What**

The `$.audio.play` helper used to enforce two limits: a total number of plays allowed per session, and a limit on how many sounds could play at the same time. The per-session total-plays cap has been removed, along with its internal tracking. Only the concurrent-plays limit remains.

**Why**

Sounds that were previously refused after a session played too many of them will now keep playing, as long as too many aren't overlapping at once.

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

### Multi-file asset uploads get a new progress/result summary view

Uploading multiple files at once now shows a per-file progress and result summary

**What**

When a tool call uploads a batch of files instead of just one, Claude Code now shows a dedicated summary view: a line reporting how many of the total files uploaded successfully, followed by a per-file status list. Each file is marked with its resulting URL, or flagged as "not attempted" or "failed".

**Why**

Batch uploads previously had no dedicated display; this gives a clear, itemized view of which files succeeded, failed, or were skipped.

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

### Artifact listing now merges externally-shared artifacts from a second source

Artifact listings now also include artifacts shared with you from an external source, merged with your own

**What**

When Claude Code lists artifacts, it now also queries a second source of externally-shared artifacts (unless the listing scope is explicitly "mine") and merges those results in, marked as shared and external, with duplicates by slug removed. Whether the listing was truncated now also accounts for this second source running out of results.

**Why**

This lets artifact listings surface artifacts that were shared with you from outside your own set, rather than only your own artifacts.

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

### claude.ai MCP connector listing now includes 'additional installs' and sorts collisions by creation time

claude.ai MCP server listing now includes 'additional installs' and handles their sorting and fallback separately

**What**

When Claude Code fetches the list of MCP servers (Model Context Protocol tool connections) hosted on claude.ai, it now requests additional installs as well (`include_additional_installs=true`). Servers flagged as additional installs are collected separately, sorted by creation time, and appended after the primary de-duplicated list. If this extended request fails with certain HTTP errors, it retries once against the plain endpoint without additional installs, and this retry doesn't count against the main retry budget.

**Why**

This surfaces MCP servers that were previously left out of the listing, while keeping the listing reliable if the extended request fails.

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

### Docs artifact type now requires the first-party Claude Docs connector

The 'Docs' artifact type now requires the first-party Claude Docs connector to be attached

**What**

Claude Code now blocks use of the 'Docs' artifact type unless the first-party Claude Docs connector is attached to the session. If it isn't attached, Claude is shown a message telling it to create a page instead of starting from that type.

**Why**

The Docs artifact type only works when it can pull content through the Claude Docs connector, so this check stops Claude from attempting something that would fail and steers it toward a working alternative instead.

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

### Comments on artifacts shared from another org are now read-only, including resolve

Comments on artifacts shared from another organization can no longer be resolved from Claude Code, not just replied to

**What

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

### otelHeadersHelper failures are now typed and telemetered

otelHeadersHelper failures now carry a specific error type and are reported to telemetry

**What**

When `otelHeadersHelper` (a user-supplied command that generates rotating [OpenTelemetry](/docs/en/monitoring-usage#dynamic-headers) headers) fails, Claude Code now records exactly why. Errors are classified into one of eight kinds: timeout, bad exit code, killed, failed to spawn, empty output, invalid JSON, output that isn't an object, or a non-string value inside it. Each failure is reported through a new event, `tengu_otel_headers_helper_failed`, that includes the failure kind and exit code, and is also broadcast so anything watching can react to it. The helper is now also fetched in the background ahead of time rather than only on demand.

**Why**

This makes it much easier to diagnose why a custom OpenTelemetry header command isn't working, since the failure is now categorized instead of surfacing as a generic error.

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

### Design system saves now report which files were written vs. removed

Design system saves now report exactly which files were written and which were removed

**Unclear.** What the gating condition controls, and when files_written/files_removed appear versus not, isn't stated.

**What**

When a design system (styling and component setup used for artifacts) is saved, the response can now include two lists: `files_written`, giving each file's path and sha256 checksum, and `files_removed`, giving each removed file's path. This is gated behind a condition in the code, so it may not apply in every case.

**Why**

This gives a precise, verifiable record of what a design-system save actually changed on disk, rather than just a success confirmation.

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

### Artifact sharing-level explanations added for publish/present flows

Claude can now explain an artifact's exact sharing level in detail when asked

**What**

A new function generates a detailed, role-specific explanation of an artifact's sharing state, whether it's private, shared within an organization, shared with specific people, or public via a link, or unknown. Claude is instructed to relay this explanation to the user when relevant, and each explanation ends with a reminder that Claude cannot change the sharing setting itself, that has to be done from the page's Share menu.

**Why**

This lets Claude give a clear, accurate answer when asked who can see a shared artifact, while making clear it can't act as a substitute for the Share menu.

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

### Live artifact version notifications now tracked per-agent

Notifications about a newer live artifact version are now tracked per agent, not just once overall

**What**

Previously, Claude Code tracked whether a user or agent had been told about a newer live version of an artifact with a single yes/no flag per artifact. Now it tracks a set of agent IDs that have already been told, so when multiple teammates or agents are working concurrently, each one gets notified independently about the same version update instead of only the first one. A new telemetry signal also fires when a reported version appears to be ahead of the local clock.

**Why**

This fixes a case where, in a session with multiple concurrent agents, only the first agent to see a live artifact update would be told about it, leaving the others unaware.

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

### Artifact type listing flags unfillable Docs-connector types

Listing artifact types now flags when Docs-type artifacts can't be filled in without the Docs connector

**What**

When `list_types` returns core Docs-type artifacts but the Claude Docs connector isn't attached to the current session, the result now includes an explanatory note that these types can't currently be filled in, based on a new `docs_unfillable` check.

**Why**

This tells the user or Claude up front why a Docs artifact type is listed but unusable, instead of only finding out when trying to actually create one.

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

### Remote Control REPL bridge now relays queued notifications

Remote Control sessions started via the REPL bridge can now receive queued notifications

**What**

When a Claude Code session is bridged to Remote Control (the feature that lets you control a session from another device), it now wires up a new `onQueuedNotification` callback. This lets notifications that were queued up reach the app and the session while the bridge is active, alongside the existing handling for inbound messages.

**Why**

Previously, queued notifications weren't being delivered into bridge-attached sessions. This ensures those notifications reach a session controlled remotely, the same way they would in a normal local session.

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

### Self-hosted runner: some context-source repos may now be exempt from silent skip-on-not-found

Self-hosted runners now check a per-source "required" setting before silently skipping missing context repos

**What**

When the self-hosted runner encounters a problem with a context-source repository, such as a missing branch reference, a failed checkout hook, or an access-denied error, it decides whether to silently skip that source or treat it as an error. Previously this decision was based only on whether the source had a matching entry in `push_targets`. Now it also checks whether that source is explicitly marked as `required`; sources marked this way are no longer silently skipped.

**Why**

This means a repo that's genuinely needed for the run will now surface a problem instead of being quietly ignored, while other context sources can still be skipped as before.

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

### Artifact comment threads gain an "outside your organization" access note and reply lockout

Artifact comment threads now flag out-of-organization participants and block Claude from replying on their behalf

**What**

When Claude Code processes comment threads on an artifact or document, it now tracks a second set of accounts representing organization membership. When a commenter is marked as "outside your organization," the access explanation now clarifies that this means the server recorded that person as invited from another organization. Additionally, when a thread is flagged this way, Claude is instructed not to reply to or resolve the thread directly; instead it must answer within the session and tell the user the answer can't be posted to the thread from there.

**Why**

This prevents Claude from acting on comment threads involving people outside the organization in ways that might not be appropriate, while still letting the user get an answer through the session itself.

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

### Artifact publish results now report whether the icon was accepted

Artifact publish results now say whether the icon you set was actually accepted

**What**

When publishing an artifact, the result text now includes a note about the icon's status: whether the `icon` was accepted, was dropped by the server, fell back to the older `favicon` emoji style, or was never sent in the first place.

**Why**

This gives clearer feedback about whether a requested icon actually took effect, instead of leaving it unclear why a published artifact might not show the icon that was set.

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

### Artifact publish results can now nudge the model to preview before publishing

Artifact publish results can now prompt the model to preview a file before it goes live

**What**

Artifact publish results can now include a `previewHint` flag. When set, the result text tells the model that the file hasn't been previewed yet this session, and suggests using the `preview` action to catch layout or loading problems before viewers see them, since certain capability calls only work once the artifact is actually published.

**Why**

This nudges the model to check its work with a preview before publishing, reducing the chance that broken layouts or load errors reach an artifact's viewers.

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

### Adding a marketplace by link now needs an explicit confirm step

Adding a plugin marketplace from a link now shows an explicit confirmation step

**What**

Adding a marketplace by link, whether via `/plugin marketplace add <path/url>` or by installing a plugin whose source is a link, now carries a `confirmAdd` payload. The add-marketplace screen automatically shows a confirmation view when this value isn't already set but the request originated from a link.

**Why**

This adds a confirmation step before a marketplace is added from a link, giving users a chance to review before Claude Code trusts and adds a marketplace sourced this way.

- Area: Plugins
- Names: `/plugin marketplace add`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### New cross-organization warning label on Artifacts

Artifacts from another organization now get an explicit untrusted-content warning shown to the model

**What**

When an Artifact (a generated file or piece of content shown alongside a conversation) belongs to a different organization than the current user, or is a public artifact from outside the user's organization, Claude Code now appends a bracketed warning to its description: that it belongs to another organization and its content should be treated as untrusted input.

**Why**

This tells the model explicitly not to blindly trust content in cross-organization artifacts, reducing the risk that instructions or data embedded in someone else's artifact get treated as trustworthy by mistake.

- Flag `tengu_cobalt_plinth_sedge`: Off by default, switched on for this account (read for one account on one subscription tier against v2.1.275; 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: Artifacts
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Sandbox/BYOC git helper hard-disables SSH when GIT_ALLOW_PROTOCOL=none

Git subprocesses now fully block SSH when GIT_ALLOW_PROTOCOL is set to 'none', closing a bypass

**What**

When Claude Code's sandbox or BYOC (bring-your-own-cloud) git helper sets `GIT_ALLOW_PROTOCOL` to `"none"` to disable git network protocols, it now also adds extra git arguments and forces `GIT_SSH_COMMAND` to `"false"`.

**Why**

Previously, setting `GIT_ALLOW_PROTOCOL` to `"none"` didn't fully stop git from still reaching out over SSH, leaving an apparent bypass of the protocol restriction. This closes that gap so disabling git protocols actually blocks SSH access too.

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

### MCP/connector name resolution in Artifacts pages gets fuzzy-match suggestions

Artifact pages now get a fuzzy-match suggestion when a connector name in the manifest doesn't match any session connector

**What**

When an Artifact's page manifest (`page.json`) references an MCP connector name that doesn't match any connector actually available in the session, Claude Code now searches for the closest matching name and includes it as a suggestion in the warning message, instead of just reporting a failure.

**Why**

This helps developers building Artifact pages quickly spot and fix typos or naming mismatches in connector references, since the warning now points toward the exact spelling that viewers expect.

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

### Multi-file reads now set aside files protected by edit-safety rules

Multi-file reads now split out files protected by edit-safety rules to read them individually

**What**

When reading multiple files at once, Claude Code now checks each file against its file-edit safety rules, which protect things like git internals, hooks, tool and agent settings, and shell profile files. Files that match these protections, have suspicious names, or are links pointing outside the working scratchpad are set aside and read one at a time instead of being bulk-read with the rest.

**Why**

This keeps sensitive or unusual files from being silently swept into a bulk read, ensuring they get individual handling consistent with the same rules that already protect them from unsafe edits.

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

### Gateway login only trusts same-origin OAuth revocation endpoints

Gateway login now only trusts OAuth revocation endpoints on the same origin as the gateway

**What**

When Claude Code logs in through an enterprise gateway and discovers its OAuth (login/authorization) endpoints, it now checks that the advertised `revocation_endpoint` (the URL used to invalidate a token on sign-out) is on the same origin as the gateway URL itself. If it isn't, Claude Code ignores it and logs a warning.

**Why**

Using a revocation endpoint from a different origin than the gateway would be a security risk, since it could let an untrusted server intercept token revocation. When the check fails, sign-out will no longer revoke the token, so administrators should watch for the warning if this happens.

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

### "You" message row dims while awaiting a model response

Your own messages now dim while Claude is still responding to them

**What**

The row showing a message you sent now dims its text to a muted, inactive color while a response is still in flight or the message is queued, instead of always displaying at full brightness.

**Why**

This makes it easier to see at a glance which of your messages are still being answered versus already settled.

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

### New 'confirm account' step in Cloud gateway login flow

Cloud gateway login now asks you to confirm your account before applying organization settings

**What**

When signing in through a trusted custom login gateway used for Claude Code Cloud, there's now an extra step after sign-in completes. It shows the email address that was signed in and asks the person to confirm it's the right account, with a "Yes, continue" or "No, go back" choice, plus a saving/loading state while the confirmation is processed.

**Why**

This step happens before the organization's settings are applied to the machine, so it gives a chance to catch a sign-in to the wrong account before those settings take effect.

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

### Usage-limit check can now be answered from a locally cached snapshot instead of hitting the endpoint

Checking your usage limit can now be answered from a recent cached value instead of a network request

**What**

Before checking how much of your usage limit you've used, Claude Code now first looks at a recently cached local snapshot. If that snapshot is less than 60 seconds old and no newer usage information has come in since, it answers from that cached value and skips calling the server entirely, logging a message noting how old the snapshot was.

**Why**

This avoids unnecessary network requests when the usage information is already known to be fresh, making usage checks faster and lighter without affecting accuracy.

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

### Ink renderer now holds frames back when stdout output is backlogged

Terminal UI now delays drawing new frames when output to the terminal is backed up

**What**

The terminal interface's frame-pacing logic now checks how much output is still queued to be written to the terminal. If that backlog gets too large, it holds off scheduling the next frame and retries after a short delay, instead of always redrawing on a fixed time schedule regardless of how much output is waiting.

**Why**

This should prevent the terminal display from piling up redraw work when output is already struggling to keep up, keeping the interface more responsive during heavy output.

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

### Artifact 'shared from another organization' text now distinguishes writer role

The warning for artifacts shared from outside your org now says specifically if you can edit them

**What**

When Claude explains that an artifact (a file or piece of content Claude created and shared) came from a different organization, the message now tells you more precisely what kind of access you have. If you have write access, the message now says so explicitly, calling out that the content is untrusted third-party content authored outside your org, rather than using a generic label that didn't distinguish writers from viewers.

**Why**

Knowing whether you can only view or also edit an externally-sourced artifact helps you judge how much to trust it and what risk comes with it, since content from outside your organization should be treated as untrusted.

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

### SKILL.md edits tell Claude which tool saves the change

Claude now tells you exactly how a SKILL.md edit will (or won't) actually get saved

**What**

When Claude is about to write or edit a `SKILL.md` file (the file that defines a skill), it now works out and communicates the right way to actually save that change. Depending on the situation, Claude will:

- Use a dedicated save tool if one is available

- Call a tool that proposes the change for you to approve

- Send you the file so you can save it yourself

- Tell you plainly that the change isn't saved, if none of the above is possible

It also warns you if the file lives in the folder that holds synced copies of your account's skills, because edits made there don't actually get saved and can be silently overwritten the next time your skills sync.

**Why**

Without this, you could edit a skill file, think the change stuck, and then lose it, either because there was no real save path or because a background sync overwrote it. This makes it clear up front whether your edit is actually going to persist.

- Area: Skills
- Names: `SKILL.md`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Plugin dependency install refuses to run bun when a bunfig.toml is present

Plugin dependency installer now refuses to run bun if a bunfig.toml file is found

**What**

When Claude Code installs a plugin's dependencies, it used to just run `bun install`. Now, before doing that, it checks whether a `bunfig.toml` configuration file sits next to the lockfile. If it finds one, it skips the install entirely and shows an explicit security message instead of running bun.

**Why**

A `bunfig.toml` file can load and run code during installation through bun's `install.security` scanner feature. Since a plugin's dependency folder could contain a `bunfig.toml` crafted by someone else, running bun automatically could execute unexpected code. Skipping the install in that case avoids running code you didn't ask for.

- Area: Plugins
- Names: `bunfig.toml`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Bridge REPL can relay a queued notification from another session as a user frame

The bridge REPL can now relay a queued notification from another session as if it were that session's own message

**Unclear.** The finding does not say what produces a `queued_notification` message or what user-visible effect the relayed message has.

**What**

The bridge (a communication channel used by the REPL, or interactive command loop) now recognizes a new incoming message type called `queued_notification`. When one arrives, it is re-delivered as if it were a regular user message belonging to the other session it references. If no notification buffer is configured to hold it, the message is instead logged and dropped.

**Why**

This allows notifications generated in one session to be surfaced inside another session's conversation flow, rather than being lost when there's nowhere to route them.

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

### Message restore/edit can now merge drafts from multiple prior messages

Restoring a message draft can now merge in drafts from several earlier messages at once

**What**

The function that restores a message's draft (`restoreMessageSync`) now accepts an optional list of extra messages. When provided, it rebuilds the draft's text and any pasted content from all of those messages combined with the target message, and concatenates their text together, instead of restoring only a single message's draft.

**Why**

This allows a restored draft to combine content from multiple prior messages at once, rather than being limited to whichever single message is being restored.

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

### Artifact URL 'update in place' now allows granted editors, not just owners

Artifact 'update in place' now works for editors given write access, not just the owner

**What**

When updating an artifact in place using its `url`, the tool used to require that the artifact belong to the user. Now it also accepts an artifact the user was merely given edit access to, shown internally as the 'writer' role.

**Why**

This means artifacts shared with edit permission can be updated by the person they were shared with, not only by whoever originally created them.

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

### Hooks modules must now be 'named like code'

Plugin hook modules must now use a recognized code file extension or they won't load

**What**

For plugins, the `module` field in `hooks.json` (the file that registers a plugin's hooks, which are scripts that run at specific points in Claude Code) must now point to a file with a recognized code file extension, and every file it imports from the plugin must too. Files with other extensions are rejected and simply not loaded, and a specific error message now lists which extensions are valid.

**Why**

This catches misconfigured or mistyped plugin hook files early, with a clear error instead of a silent failure to load.

- Area: Hooks
- Names: `hooks.json`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### 'none' project-instructions mode now keeps org-managed CLAUDE.md

'none' project-instructions mode now keeps org-managed CLAUDE.md instead of dropping everything

**What**

The `projectInstructions` setting controls which instruction files Claude Code loads for a project. Its `none` mode has changed: it now only drops the project's own instruction file and your personal one. An organization's managed `CLAUDE.md` and memory still get loaded even when `none` is selected.

**Why**

Previously `none` dropped the organization's managed instructions too. Now organization-level instructions always apply regardless of this setting, so a user picking `none` to skip project-specific instructions won't accidentally lose org-wide policy.

- Area: Project Config
- Names: `projectInstructions`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Advisor selection now explains how a mid-conversation change applies

Picking an advisor mid-conversation now explains when the change will actually take effect

**What**

The advisor tool lets a second model weigh in on Claude's work at key moments. When you change the advisor model setting partway through a conversation, Claude Code now shows a note explaining when that change actually applies. For example, it will tell you if the API already refused to use an advisor for this turn, or if the current conversation already locked in a different advisor model or tool setup.

- Advisor tool changes (additions or removals) can now be surfaced later in a turn, using a new `advisor_tool` transcript entry and an `advisorToolChanges` flag, similar to how late tool additions are already announced.

- The mechanism that decides whether to re-render tool information for an advisor model now also checks for tools being removed, not just added.

**Why**

This clears up confusion about why switching the advisor model mid-conversation doesn't always take effect immediately, and makes sure tool changes tied to a deferred advisor are still shown even when they arrive late in a turn.

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

### Edit/Write results now warn when the file is inside a synced skill folder

Editing a file inside your synced skills folder now warns Claude the change isn't actually saved

**What**

When Claude edits or creates a file that happens to sit inside the folder holding synced copies of your account skills (reusable instruction sets Claude can call on), the edit or write result now includes a warning. It tells Claude that the change isn't saved to the account and could be overwritten the next time skills sync, and points it toward using a proper save action, a `propose_tool` call, sending the file to the user, or telling the user outright that the change wasn't saved.

**Why**

Without this, Claude could edit a file in that folder and assume the change was permanent, when in fact the next sync could silently wipe it out. The warning steers Claude toward actually persisting changes to your account skills correctly.

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

### Artifact styling instructions differ when fonts are already on disk

Artifact styling instructions now check for fonts already on disk before telling Claude to fetch them

**What**

When Claude Code prepares styling instructions for building an artifact (a generated file such as a webpage), it now checks whether any of the system's files look like font files. If so, the instructions say fonts are already on disk and explicitly forbid fetching fonts from named web addresses. Otherwise, it keeps the previous instruction to obtain font files only through the Artifact tool.

**Why**

This avoids telling Claude to fetch fonts from the internet when suitable font files are already available locally, which should make artifact styling more reliable when fonts are already present.

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

### GitHub-shorthand normalization applied when adding a marketplace from a git URL

Adding a marketplace from a GitHub git URL now normalizes it to GitHub shorthand form

**What**

When adding a plugin marketplace, a new helper now normalizes the source entry: if the source type is `github`, it normalizes the repository string; if the source type is `git` and the URL actually points to a GitHub repository, it rewrites the entry to use `source: "github"` with the shorthand repo name instead of keeping it as a raw git URL.

**Why**

This means marketplaces added by pasting a plain GitHub git URL get stored in the same normalized shorthand form as ones added directly as GitHub sources, keeping marketplace entries consistent regardless of how they were added.

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

### Improved /desktop failure messages

/desktop now gives clearer error messages when it can't open Claude Desktop

**What**

The `/desktop` command (which continues the current session in the Claude Code Desktop app) now shows clearer error text when something goes wrong:

- the too-old-version message is now shorter: "Claude Desktop ${version} is too old. Update to ${version} or later."

- the open-failure message now states the specific reason and what to do next: "Couldn't open Claude Desktop (${detail}). Open Claude Desktop and run /desktop again."

**Why**

Instead of a generic failure, users now get a concrete reason and a clear next step when `/desktop` can't launch or connect to Claude Desktop.

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

### CA-cert troubleshooting message now lists concrete env vars

SSL certificate error message now lists the specific env var to check per tool

**What**

The TLS/certificate troubleshooting message now names the specific flag or environment variable relevant to each tool that might be involved in a certificate error: `--cacert`, `SSL_CERT_FILE`, `NODE_EXTRA_CA_CERTS`, `REQUESTS_CA_BUNDLE`, `AWS_CA_BUNDLE`, `DENO_CERT`, `CARGO_HTTP_CAINFO`, `PIP_CERT`, `GIT_SSL_CAINFO`, `BUNDLE_SSL_CA_CERT`, `HEX_CACERTS_PATH`, and `NIX_SSL_CERT_FILE`.

**Why**

Certificate errors can originate from many different tools (curl, Node, Python, Deno, Rust's cargo, git, Ruby's bundler, Elixir's hex, or Nix), each with its own way of pointing to a trusted certificate. Listing the exact variable for each makes it much faster to find and fix the right one instead of guessing.

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

### New attestation-failure reason surfaced to users: 'unattested_request'

New error reason 'unattested_request' shown when a linked device can't be vouched for

**What**

Remote Control and device-linking error messages now include a new reason code, `unattested_request`, shown when a machine's account requires sender attestation (proof of where a request came from) and the service was unable to vouch for the caller.

**Why**

This gives a clearer, specific explanation when a device-linking or remote-control request fails because it couldn't be verified, instead of a generic error.

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

### Gateway account email shown in status (non-demo)

Status/diagnostics view now shows the gateway account's email when logged in via gateway, outside demo mode

**What**

When you're authenticated through 'gateway', the status or diagnostics view now also prints that gateway account's email address. This does not happen when running in demo mode.

**Why**

It makes it easier to confirm which account you're actually authenticated as when using a gateway login.

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

### Artifacts gain 'external organization' sharing metadata

Artifacts shared in from another organization now show that origin with dedicated metadata and UI text

**What**

Artifacts (generated files or outputs shared within Claude Code) now carry extra sharing metadata when shared in from outside your own organization: an `external` flag and a `role` on shared artifacts, a derived `invitedByOtherOrg` field, and an `external_listed` response flag. The interface now shows the text '(from another organization)' for artifacts shared this way.

**Why**

This makes it clear when an artifact you're viewing was shared in from a different organization than your own, rather than looking like it came from within your own org.

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

### Module resolution now also tries .mts/.cts for .mjs/.cjs

Import resolution now also tries .mts and .cts file extensions for .mjs and .cjs imports

**What**

When resolving an import path, Claude Code's module resolver now also tries a `.mts` file if the import ends in `.mjs`, and a `.cts` file if it ends in `.cjs`. This joins the existing mapping that tries `.tsx` for a `.jsx` import.

**Why**

This lets imports resolve correctly to TypeScript source files (`.mts`, `.cts`) even when the import specifier uses the compiled JavaScript extension (`.mjs`, `.cjs`).

- Area: Elsewhere
- Names: `.mts`, `.cts`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Artifact error messages distinguish cross-org shared/public artifacts

Artifact error messages now distinguish public-outside-org artifacts from ones shared from another organization

**What**

When an artifact's publish target is gone or ownership needs to be described, Claude Code now separately identifies two cases: an artifact that is public but belongs to a different organization than the user's, versus one that was specifically shared with the user from another organization. For the latter, a new explanation is added noting that access may have been withdrawn by its owner.

**Why**

This gives clearer, more accurate error messages when an artifact becomes inaccessible, helping distinguish a general cross-organization visibility issue from a revoked share or lost edit access.

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

### Artifact asset copy_from now supports cross-org destinations with a retry probe

Artifact `copy_from` now supports copying across organizations and retries once if the destination isn't found yet

**What**

The `copy_from` action, used to copy assets between artifacts, now supports copying across organizations in some cases. It checks organization membership and probe state to determine whether a cross-organization copy is allowed (`crossOrgOk`), and blocks the copy with a specific error if the destination artifact is outside the user's organization and not allowed. If the first copy attempt fails because the destination isn't found yet and hasn't been probed, Claude Code now automatically retries once with a fresh probe.

**Why**

This makes copying assets between artifacts more reliable when the destination artifact is newly created or not yet visible, while still enforcing organization boundaries where required.

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

### Quickstart flow now handles a missing Docs connector explicitly

Artifact quickstart now explains clearly when no Claude Docs connector is attached

**What**

When starting a new artifact of type 'document' without a first-party Claude Docs connector attached to the session, Claude Code now shows a dedicated explanation that a Docs artifact can only be filled in through that connector, and suggests making a plain page instead. The general list of available artifact types also now notes this caveat, and adjusts its "No published Artifact types" message to "No other published Artifact types" when the Docs connector is the reason.

**Why**

This makes it clearer why a Docs-type artifact isn't available in a given session, instead of leaving the user to guess why that option is missing.

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

### Scratchpad file uploads gain a dedicated font-file category and case-insensitive name collision check

Scratchpad file uploads now have a separate font-file limit and block case-only duplicate names

**What**

When uploading files to the scratchpad (the attachment area for files you give Claude), fonts are now recognized as their own file category based on extension or content type. Fonts get their own byte-size and file-count limits (rejecting uploads with more than a set number of fonts), separate from the existing 8MB-per-file and total file-count caps that already applied to other files.

Uploads are also now checked for name collisions that differ only by letter case (after normalizing the filename); a file with the same name as an existing one except for capitalization is rejected.

**Why**

This prevents font uploads from silently exceeding size budgets meant for other file types, and stops uploads from creating two files whose names differ only by case, which can cause confusion or conflicts on case-insensitive filesystems.

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

### Ripgrep spawn helper rewritten with streaming truncated buffers and richer failure handling

Internal ripgrep process runner rewritten for streaming output and clearer failure types

**What**

The internal component that runs ripgrep (used to power search/grep) was rewritten. Output from the search process is now collected with a streaming buffer instead of simple string concatenation, there is a new error path for when writing to the process's input fails, and failures are now reported with distinct error types depending on the cause: file-not-found, an internal range error, or a generic spawn failure.

**Why**

This is mostly an internal reliability change. It should make search and grep failures more consistent and better labeled, though it is largely invisible to end users beyond clearer error messages when something goes wrong.

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

### Worktree image-cache cleanup added to the retention sweep

Stale image caches in git worktrees are now cleaned up during retention sweeps

**What**

Claude Code's periodic cleanup process now scans each session's git-worktree cache folders for old `images` subfolders and removes any older than a cutoff age. This replaces older, more generic placeholder cleanup logic, and the results (what was removed, and any errors) now show up in the same summary as the existing history and session cleanup.

**Why**

This keeps cached images from git worktrees from accumulating and taking up disk space indefinitely.

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

### New 'script' activity indicator in tool-use summaries

Turn summaries can now show a 'script' activity indicator alongside bash, read, and other categories

**Unclear.** The finding does not say what condition triggers the 'script' indicator or what kind of activity it represents.

**What**

When Claude Code finishes a turn, it prints a short summary line of what happened (for example, how many files it read or shell commands it ran). That summary can now include a new 'script' category showing a 'working' indicator, alongside the existing bash, read, list, mcp (external tool connections), agent, and repl (interactive code execution) categories.

**Why**

This gives a more complete picture of what a turn actually did, so script-related activity shows up in the summary instead of being invisible.

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

### Hook-command relative-script risk detection greatly expanded

Claude Code now detects many more ways a hook script could break if run from a different folder

**What**

Claude Code can warn when a hook (a shell command that runs automatically at certain points, configured via plugins or settings) implicitly depends on the folder it's launched from, which can make it fail when run elsewhere. This detection was substantially expanded:

- it now strips hidden NUL bytes before decoding the script

- it recognizes more shells: `ash`, `ksh`, `mksh`, `rbash`, and `fish`

- it separates the shebang line (the `#!/bin/...` line that names the shell) from the rest of the script for more accurate analysis

- it adds a check specific to the `csh` shell for `set path = (...)` lines that contain relative or `.` (current directory) entries

- it detects relative file includes pulled in via `make include` or `awk @include`

**Why**

Hooks that quietly rely on the current working directory can fail unpredictably when Claude Code runs them from a different location. Catching more of these cases means more accurate warnings before a hook silently breaks.

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

### Hook working directory and program-path resolution now respect --project-config-root

Hooks now honor --project-config-root when resolving their working directory and paths

**What**

When Claude Code runs a hook, it needs to know the project's root folder, both to set the `CLAUDE_PROJECT_DIR` environment variable passed to the hook and to decide the hook's working directory when one isn't explicitly set (`spawnCwd`). These resolutions now check the launch-time `--project-config-root` override first, before falling back to the previous project-root logic.

**Why**

This makes hook behavior consistent with the `--project-config-root` flag, so hooks run and resolve paths relative to the project root you actually specified rather than a default location.

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

### Large hook additionalContext entries can now be persisted to disk instead of truncated inline

Oversized hook context is now saved to a file instead of being cut off

**What**

Hooks can return extra context text (`additionalContext`) that gets added to what the model sees. When a single hook's context text is too large for its allotted space, Claude Code now writes the full text to disk and passes along a reference to that file plus a truncated preview, instead of simply cutting the text short and discarding the rest.

**Why**

Previously oversized context was hard-truncated and the rest lost. Saving it to disk means the full content isn't discarded, even though only a preview is shown inline.

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

### New "prompts awaiting model" tracking surfaces queued-but-undelivered user input

Claude Code now tracks queued messages that haven't reached the model yet, including ones queued behind the current one

**Unclear.** The finding doesn't say whether or how this tracking is surfaced visually to the user beyond the internal state.

**What**

Claude Code now keeps track of prompts you've queued (typed and sent while a previous message was still being handled) that haven't actually reached the model yet. This tracking clears once the model starts responding to that prompt. A related addition tracks and can display the list of prompts queued up behind the one currently being processed.

**Why**

This groundwork lets Claude Code more accurately show you what's queued and waiting versus what's actually being worked on, reducing confusion about whether your queued input has been picked up yet.

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

### Subagent statusLine scripts can now run against an overridable project root

Subagent status line scripts can now resolve their project directory from an overridable root

**What

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

### Gateway login now shows an account-confirmation step with truncated email before saving credentials

Login now shows a confirmation screen with your truncated email before saving your credentials

**What**

The device-authorization login flow (used for gateway login) now includes a new "confirm account" step. It displays your email address, truncated if too long, before the authentication token is actually saved, and it blocks pressing Escape while the save is in progress. The flow also now stores a `revocationEndpoint` on the saved credentials when the identity provider advertises one.

**Why**

Showing the account before committing credentials lets you confirm you're logging into the right account, and blocking Escape mid-save avoids interrupting the process partway through.

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

### New IP-allowlist reason surfaces in model catalog fetch failures

Model list failures now show a specific reason when an org's IP allowlist blocks the request

**What**

When fetching the list of available models fails, Claude Code can now identify a third specific cause: the organization's IP allowlist rejecting the request ("ip_restricted", surfaced as an HTTP 403 with code "ip_not_in_allowed_range"). This joins the two previous failure reasons (no organization on the route, and a credential that can't read), each with its own log message and telemetry reason.

**Why**

This makes it clearer, both in logs and telemetry, when a model list failure is caused by an organization's network IP restrictions rather than some other credential or routing problem.

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

### Artifact gallery now merges externally-shared frames into the list

The artifact gallery now also shows artifacts shared with you from outside your own list

**What**

The part of Claude Code that loads the list of artifacts (files or outputs generated and saved during a session) now fetches an additional set of results and merges in any artifacts that were shared with you but aren't already in your own list. These merged-in items are marked as shared and external, and carry a role field.

**Why**

This means the artifact gallery can now surface work that others have shared with you, not just artifacts you created yourself, so you no longer have to look elsewhere to find shared items.

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

### Logout now revokes/cleans up enterprise gateway auth state

Logging out now also revokes and cleans up enterprise gateway authentication state

**What**

When logging out, if the current authentication method is an enterprise gateway, Claude Code now waits up to 5 seconds for any in-flight gateway calls to finish, invalidates the cached credentials, and looks up the stored gateway configuration to run a cleanup step on it before continuing with the rest of logout.

**Why**

This ensures logging out fully revokes enterprise gateway credentials instead of leaving stale gateway auth state behind, and avoids cutting off requests that were already in progress.

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

### New queued-notifications rendering UI with per-origin labeling

Queued notifications now display with labels showing where each one came from

**What**

Queued notifications (messages waiting to be shown) now render with labels that identify their origin:

- notifications from a GitHub webhook are labeled 'github'

- notifications from a scheduled trigger are labeled 'scheduled trigger'

- notifications from another Claude session sending a message are labeled 'claude session'

Each notification shows a summary, body text, and an 'inbound:' badge. When there are more notifications than can be shown, a footer reads 'more N notifications still queued'.

**Why**

This makes it easier to tell at a glance where an incoming notification came from and how many more are waiting, instead of seeing an undifferentiated list.

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

### Artifact publish now returns icon/favicon change status flags

Publishing an artifact now reports whether its icon was dropped, sent, or auto-derived as a favicon

**What**

When you publish an artifact (a shareable page or file Claude creates), the publish result now includes new status fields: `iconDropped`, `icon`, and `faviconSent`. These tell you whether an icon you set was left out, sent as given, or used to automatically generate a favicon (the small icon shown in a browser tab).

**Why**

This makes it clear after publishing exactly what happened to the icon you chose, instead of leaving it ambiguous whether an icon request was honored.

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

### artifact read: falls back to reading it as a frozen artifact type link on a 404

Reading an artifact that 404s now falls back to returning its type declaration if it's a frozen artifact type

**What**

When reading an artifact page or file returns a 404 (not found) error, Claude Code now checks whether the requested URL actually refers to a 'frozen artifact type' (an entry in a type catalog). If it does, it returns that type's declaration and instructions instead of just reporting the 404 as a failure. This applies to both the page `read` action and the single-file `read_file` action.

**Why**

This avoids a misleading failure when the URL was never a live artifact page in the first place but a reference to a known artifact type, giving useful information instead of a plain error.

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

### OAuth metadata gains a revocation_endpoint and sign-out revocation flow

MCP OAuth sign-out now revokes tokens via a discovered revocation_endpoint

**What**

The specification for Claude Code's MCP OAuth gateway (the part that handles logging in to Model Context Protocol servers that require authentication) now documents reading a `revocation_endpoint` from the authorization server's metadata. On sign-out, it sends a standard RFC 7009 revocation request for the bearer token, and for the refresh token too if one was issued. For clients that signed in before their server started advertising this endpoint, the metadata is re-checked so revocation still works.

**Why**

This means signing out of an MCP server can now properly invalidate its tokens on the server side, rather than just discarding them locally, closing a gap for servers and clients that connected before this behavior existed.

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

### Artifact type-reading tool output now reports whether the type file was actually read

Artifact type tool output now shows whether the type file was actually read

**What**

When Claude Code displays the result of a tool call that reads an artifact's type, it now checks a new `type_file` field in the result. If present, it shows either "read `<path>` of artifact type" or "did not read `<path>` of artifact type", depending on whether the file was actually read.

**Why**

This gives a clearer, more honest account of whether the type information came from an actual file read or not.

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

### Remote-control bridge clears post-turn summary/recap metadata when a new turn starts

Remote Control clears the previous turn's summary and recap as soon as a new turn starts

**What**

When a session controlled remotely transitions into a "running" state (meaning a new turn has started), the bridge now proactively tells the remote client that the `post_turn_summary` and `recap` (the end-of-turn summary data shown after a turn finishes) are null, and runs an additional cleanup step.

**Why**

This prevents a remote client from continuing to show summary or recap information left over from the previous turn once a new turn has already begun.

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

### db_read / db_write tool errors now carry richer diagnostic detail

db_read and db_write tool errors now include extra diagnostic detail like error code, reason, and slug

**What**

When the artifacts `db_read` or `db_write` tool encounters an error, the error message shown now includes additional detail such as the error code, reason, and slug, rather than just passing along the server's raw error text.

**Why**

The extra context makes it easier to understand why a database read or write inside an artifact failed, instead of seeing only a generic server message.

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

### `file_paths` disabled for scripted/SDK callers

Batch file uploads via file_paths are now blocked when called from a non-interactive script

**What**

When an artifact upload is triggered from a non-interactive script (rather than a normal interactive session), passing multiple files at once via `file_paths` is now rejected. In that context, only one `file_path` per call is allowed.

**Why**

This keeps scripted or SDK-driven callers from batching multiple file uploads in a single call, forcing them to upload files one at a time instead.

- Area: Artifacts
- Names: `file_paths`
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Publish responses can now report a dropped icon

Artifact publish results now report if an icon was dropped from the payload

**What**

The result returned after publishing an Artifact now includes an `iconDropped` field, indicating when an icon or favicon was stripped out of the publish payload, similar to the existing `deadlineDropped` field.

**Why**

This lets whoever consumes the publish result know that the icon didn't make it into the published output, rather than that information being silently lost.

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

### claude.ai MCP server fetch now requests additional installs, with fallback

Fetching claude.ai MCP servers now also requests additional installs, falling back if that's rejected

**What**

When Claude Code fetches the list of MCP servers (external tool/data connections) associated with your claude.ai account, it now adds `include_additional_installs=true` to the request. If the server refuses that parameter, Claude Code falls back to the plain request without it, and logs the refusal.

**Why**

This lets Claude Code pick up additional installed MCP servers when the server supports the new parameter, while staying compatible with servers that don't yet recognize it.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Subagent file-report note wording changed for zero-directory runs

Subagent file-report note now distinguishes zero-directory runs from restricted-but-listed file access

**What**

When a subagent (a Claude Code task delegated to a separate agent) finishes, its tool results include a note about which files it's allowed to claim as its own work. This note now has different wording depending on the situation: if no save directories are configured at all, it says the subagent produced "no files during this run"; if saves are restricted but some files are still trustworthy, it now says the subagent may claim "only the files this note lists or counts."

**Why**

This makes the file-attribution note more precise, so it's clearer whether a subagent had no file output at all versus limited, specifically listed file output.

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

### Working-directory read summary distinguishes multi-directory sessions

File-read summaries now say 'working directories' plural for sessions spanning more than one

**What**

When Claude Code reports how many files it read from outside the current folder, the message now checks a new `elsewhereBeyondCwd` flag. If a session has more than one working directory, the message says "the session's working directories" in the plural, instead of "the working directory" in the singular.

**Why**

This makes the summary accurate for sessions that span multiple working directories, rather than implying there is only ever one.

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

### Bulk file upload support for artifact asset uploads

The artifact tool's upload_asset can now describe uploading a list of multiple local files at once

**Unclear.** The finding shows the description change implying multi-file support, but doesn't confirm the underlying upload mechanism itself changed.

**What**

The description Claude sees for `upload_asset`, part of the Artifact tool, now distinguishes between uploading a single local file and uploading a list of several local files, phrased as "a list of N local files." This follows earlier work that expanded which file types (adding stylesheets and scripts) could be uploaded as assets.

**Why**

This suggests `upload_asset` can now handle multiple files in one call rather than requiring a separate call per file, which would make attaching several assets to an artifact more efficient.

- Area: Artifacts
- Names: `upload_asset`
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### File-history backup restore now deduplicates concurrent copy operations by backup filename

Restoring file-history backups now avoids duplicate copy operations for the same backup file

**What**

When Claude Code restores file-history backups for a resumed session, it now keeps track of in-flight backup-copy operations, keyed by the backup file's name. If multiple messages reference the same backup file at once, they now share a single copy operation instead of each triggering a redundant copy.

**Why**

This avoids unnecessary duplicate work when restoring a resumed session, which is more efficient and reduces the chance of conflicting concurrent copies of the same backup file.

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

### Artifact read-tool now stamps a 'save source of artifact' note

Reading an artifact's saved source file now notes it only counts as viewed once fully read

**What**

When Claude reads the file that is the saved source of an artifact, the Read tool result now attaches a note like "This file is the saved source of artifact ... at version ...", stating that this version only counts as viewed once every line of it has been read.

**Why**

This stops Claude from treating a partial read of an artifact's source file as if it had seen the whole thing, which matters since decisions about an artifact's current state depend on knowing its full, current contents.

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

### Background monitor tool description clarifies cwd with --project-config-root

Background monitor tool docs now note that --project-config-root changes the working directory it reports

**What**

The background-monitor tool's built-in description now explains that when a host application sets `--project-config-root`, that path becomes the effective working directory (the folder a command is considered to run in) for the session, instead of just saying the command runs in the session's working directory.

**Why**

This is a documentation clarification for the tool itself, so anything reading that description (including Claude) understands where commands are actually running when a host has overridden the project root.

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

### Simplified 'file not found' artifact error message, drops markdown-sibling suggestion

Artifact 'file not found' error message simplified, no longer offers to build an HTML page from a markdown sibling

**What**

The helper that builds the "file not found" hint for artifacts was simplified. It now either returns a short "Did you mean X?" suggestion, based on filename similarity or a matching `.html`/`.htm` sibling file, or returns nothing at all. The previous, longer message text and the special-case suggestion to auto-author an HTML page from a markdown sibling file have been dropped.

**Why**

This makes the "file not found" message shorter and more focused on a direct filename suggestion, removing a more elaborate but narrower behavior around markdown-to-HTML suggestions.

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

### Sandbox status output now reports Bash auto-allow state

sandbox status command description now mentions it reports Bash auto-allow state

**What**

The description for the `sandbox status` command was updated to say that it prints the Bash auto-allow setting, in addition to the enabled state, source, strict mode, and filesystem policy it already reported.

**Why**

This makes it clearer from the command's own description that checking sandbox status also tells you whether Bash commands are set to auto-allow.

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

### New watch-brief live-subscription status message

New status text explains when a live subscription doesn't apply to a session

**What**

When a tool call is a "watch brief" (`watchBrief === true`) and its live subscription type is `publish_context`, Claude Code now shows a specific status message instead of a generic one: "Live subscription: none in this kind of session (see the earlier publish result); not an error."

**Why**

This clarifies that the absence of a live subscription in this situation is expected behavior, not a failure, so it shouldn't be mistaken for a bug when publishing artifacts.

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

### Parked permission requests retired in transcript on new input

Pending permission requests are now cleaned up if new input arrives before they're handled

**What**

If a permission request (a prompt asking you to approve a tool call) is still waiting and hasn't been picked up yet, and new input arrives while the session isn't shutting down, Claude Code now explicitly retires that pending request in the conversation transcript, and records how long it sat waiting before being retired.

**Why**

This avoids leaving stale, unanswered permission requests hanging around in the transcript when the conversation has already moved on, and gives visibility into how long such requests went unhandled.

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

### auto-allow-bash-if-sandboxed setting surfaced in diagnostics with its source

Diagnostics now report whether autoAllowBashIfSandboxed is on and where that value came from

**What**

A settings snapshot used for diagnostics and telemetry now reports whether the `autoAllowBashIfSandboxed` setting is enabled, along with where that value was set from: `unsupported`, `policy`, `default`, or `settings`.

**Why**

This makes it easier to see, when diagnosing a session, whether bash commands are being auto-allowed because they're sandboxed, and whether that behavior comes from a policy, a default, or the user's own settings.

- Area: Sandbox
- Names: `autoAllowBashIfSandboxed`
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Claude Test plugin: runner agent now explicitly named, clearer failure guidance

claude-test plugin's runner agent is now explicitly named, with a clearer error for a common failure

**What**

The built-in `claude-test` plugin's background runner agent definition now has an explicit `name: runner` field. Its error message for when the browser helper hasn't loaded yet was also replaced: instead of a generic fallback message, it now gives a static, more actionable error that names a likely cause, having another enabled plugin also named `claude-test`.

**Why**

This makes it easier to diagnose a common failure mode, a duplicate non-built-in plugin also called `claude-test` conflicting with the built-in one, instead of just seeing a vague 'not loaded yet' message.

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

### Env var passthrough allowlist grows: AWKPATH, AWKLIBPATH, DEVELOPER_DIR

Environment variable passthrough list adds AWKPATH, AWKLIBPATH, and DEVELOPER_DIR

**What**

The list of environment variables Claude Code considers safe to pass through (alongside existing ones like `GNUMAKEFLAGS`, `MFLAGS`, and `MAKEFILES`) now also includes `AWKPATH`, `AWKLIBPATH`, and `DEVELOPER_DIR`.

**Why**

This lets commands run by Claude Code correctly inherit these variables, which matter for tools like `awk` (which uses `AWKPATH`/`AWKLIBPATH` to find its scripts) and Apple's developer toolchain (which uses `DEVELOPER_DIR`), instead of having them stripped from the environment.

- Area: Env Vars
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Dangerous-env-var regex now flags NLSPATH and DEVELOPER_DIR

Claude Code now flags NLSPATH and DEVELOPER_DIR as potentially hijacking environment variables

**What**

Claude Code checks environment variables for ones that could hijack a command by pointing it at attacker-controlled code or libraries. That check now also catches `NLSPATH` and `DEVELOPER_DIR`, in addition to the existing `LD_`, `DYLD_`, `GCONV_PATH`, and `PYTHON`-prefixed variables.

**Why**

`NLSPATH` and `DEVELOPER_DIR` can be abused the same way as the variables already covered, so flagging them closes a gap in the safety check that warns about risky environment variable usage.

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

### New bash risk explanation for `env -P`

Claude Code now explains the risk of running env -P with a relative directory

**What**

Claude Code's bash command safety analyzer, which explains why a command might be risky before it runs, now has a specific explanation for `env -P`: when given a relative directory, the program `env` runs is looked up starting from the directory you launched the command in, not from a fixed location. This joins existing explanations for commands that wrap other commands or run without a fixed shell, like `parallel`, `script`, `su`, and `sudo`.

**Why**

This helps you understand why `env -P` with a relative path is flagged, since it means the actual program executed depends on where you happen to be standing when you run the command.

- Area: Bash Tool
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### New decision_reason_code telemetry field and blockedPath on deny

Permission-deny messages for out-of-directory file access now include the blocked path

**What**

When Claude Code denies a request to read or write a file outside the allowed directory, the resulting message now includes a `blockedPath` field with the specific path that was rejected. Separately, a new `decision_reason_code` field was added to a telemetry schema, joining the existing `decision_reason` and `decision_reason_type` fields.

**Why**

Including the actual blocked path makes it clearer why a permission was denied, and the added telemetry field gives more structured detail for diagnosing permission decisions.

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

### File extension map extended: .cjs, .mts, .cts

File extension detection now recognizes .cjs, .mts, and .cts

**What**

The map used to detect a file's language from its extension now includes `.cjs` (mapped to JavaScript) and `.mts` and `.cts` (both mapped to TypeScript), alongside the existing `.jsx`, `.js`, and `.mjs` entries.

**Why**

This lets Claude Code correctly recognize these CommonJS and TypeScript module file extensions wherever the language is used, such as syntax highlighting or file-type-aware behavior.

- Area: Elsewhere
- Names: `.cjs`, `.mts`, `.cts`
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Command queue draining now accounts for 'stale' classifier screening on submitted prompts

Queued prompts now stop batching together once a stale screening result is detected

**What**

When Claude Code drains a queue of pending prompt messages to send them together, it now checks each one's "screening" status (a classifier check run when the prompt was submitted). If a queued message's screening is considered stale, the queue now stops accumulating further messages at that point, rather than always draining the entire run of same-mode messages as before.

**Why**

This avoids batching a prompt whose classifier screening is out of date together with other queued prompts, which could otherwise let a stale screening result apply to messages it wasn't actually checked against.

- Area: Message Queue
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Resumed observer agents get a scoped tool surface via agentToolScope

Resumed observer-mode agents now get an explicit, scoped set of tools instead of inheriting the parent's

**What**

When an agent is resumed in observer mode, Claude Code now passes an explicit `agentToolScope` pointing at that agent's own resolved definition, rather than following the path where it would inherit its parent's tool set.

**Why**

This gives resumed observer-mode agents a tool surface tied to their own definition, distinct from whatever tools their parent session had available.

- Area: Subagents
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New helper renders type_file read results with an 'unread' state

A new helper formats describe_type results for files that are unread or unreadable

**What**

A new function handles the case where a `describe_type` result includes a type file. It now distinguishes between a file that is unread or unreadable, showing a reason for that, and a file with normal readable content, before falling back to the previous formatting behavior for other cases.

**Why**

This gives a clearer, explained result when a type file can't be read, instead of presenting it the same way as normally readable content.

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

### Conversation forking now preserves 'memory-mode' records

Forking a conversation now carries over its 'memory-mode' records too

**What**

When a conversation is forked (branched into a new session), Claude Code now also copies over any 'memory-mode' records from the original session into the new forked transcript, tagged with the new session's ID. This happens in both ways a fork can be created. It's in addition to the content and working-directory carryover that already happened during a fork.

**Why**

This means forking a conversation now preserves memory-mode state along with the rest of the conversation, so a forked session doesn't lose that context.

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

### New `docs_unfillable` flag surfaces in `list_types` output

list_types now flags when a Docs-backed artifact type can't be filled in the current session

**What**

The artifact `list_types` action's output now includes an optional `docs_unfillable` field. It gets set when one of the listed types is backed by Docs but cannot be filled in the current session, and when that happens, the type listing now also appends a fixed explanatory message to its summary.

**Why**

This gives a clearer signal when a Docs-backed artifact type is present but unusable in the current session, building on `list_types` already having been made to degrade gracefully (returning an empty list with an unavailable flag) instead of throwing when the type catalog itself was off.

- Area: Artifacts
- Names: `docs_unfillable`
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Spinner tip publication now held until the current turn finishes

The rotating spinner tip no longer changes mid-turn, only after the current turn ends

**What**

The small tip shown next to the loading spinner used to be able to change while Claude was still working on a turn. Now, if a turn is in progress, a new tip is held back and only shown once that turn finishes.

**Why**

This keeps the tip text from changing distractingly while you're waiting for a response.

- Area: UI
- Tier: You'll notice
- Useful: 1/5
- Signal: 0/5

## Bug Fixes

### AskUserQuestion permission fallback message now distinguishes 'server not requested' in headless mode

The AskUserQuestion tool's error message now distinguishes when a server permission check simply wasn't requested

**What**

When the `AskUserQuestion` tool can't show its usual permission prompt because it's running in a headless, asynchronous context, the denial message it returns now has two forms: one specific message for when the server side of the permission check was never requested, and the previous, more general fallback message for other cases.

**Why**

This gives clearer, more accurate feedback about why a question couldn't be asked when Claude Code is running unattended, instead of always showing the same generic explanation.

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

### Disabled-but-listed tools now get a clearer error message

The error for a missing tool now says clearly whether it's switched off or its source was removed

**What**

When a tool that's part of the current conversation isn't actually available to use, the error message now distinguishes two different cases: the tool being switched off in the current session, versus the tool's source (such as a connected server) having been removed or disconnected. Each case now gets its own distinct message.

**Why**

This makes it clearer why a tool isn't working, so a user or model can tell whether to just turn it back on or whether it needs to be reconnected entirely.

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

### FileHistory backup-copy fallback now uses atomic staged write with integrity check and retry

File-history backup copying now writes atomically with an integrity check and retries on failure

**What**

When Claude Code's file-history feature can't create a backup of a session's files by hard-linking (a fast way to duplicate a file without copying its data) and falls back to copying instead, it now writes to a temporary file first, checks that the copied file's size matches the original, and only then renames it into place. If the rename fails, it retries for about 1.5 seconds before giving up, logging a specific message if it's ultimately refused.

**Why**

This avoids leaving corrupted or incomplete backup files in place if a copy is interrupted or a rename briefly fails, which matters since file history is what lets changes to files be tracked and reviewed.

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

### Chrome/browser tool: batch URL checks now pre-screen for unvettable/denied domains across the whole batch

Batched browser URL checks now screen every URL in the batch, not just the first, before allowing the call

**What**

For `browser_batch` tool calls, which bundle multiple browser actions into one call, Claude Code now checks every URL in the batch up front rather than just the primary one. If any URL in the batch is a non-web or unparseable address (like a browser-internal page), the whole call is denied with a message telling the user to navigate to a web page first. If any URL matches a denied-domain rule, the call is denied and the specific offending URL is named.

**Why**

This closes a gap where a batched call could slip past domain restrictions or hit an internal browser page as long as only a secondary URL in the batch was the problem, instead of the first one being checked.

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

### Tool result / binary content / hook output persistence now falls back to an in-transcript truncation preview when disk save is unavailable

Large tool outputs that can't be saved to disk now show a truncated preview instead of being silently cut or dropped

**What**

Large tool results, hook outputs (output from custom scripts that run at certain points), and binary content are normally saved to disk when they're too big to keep in the conversation directly. When disk storage isn't available to save them, Claude Code now builds a truncated preview shown inline in the conversation, marked with an explicit `<truncated-output>` label and a message explaining that the output was too large, couldn't be saved, and only the first part is shown.

**Why**

This makes it clear when output has been cut short because it couldn't be saved, rather than leaving the loss silent or unexplained.

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

### Batch upload rate-limit backoff message

Batch artifact uploads now pause with a retry message instead of failing when rate-limited mid-batch

**What**

If the asset store starts rate-limiting an artifact partway through a `file_paths` batch upload, the remaining files in that batch are no longer sent and failed outright. Instead, Claude Code returns a message saying the store is rate limiting this artifact and to wait a minute before sending the rest.

**Why**

This lets a batch upload recover gracefully from a temporary rate limit instead of losing the remaining files, by telling the model to pause and retry rather than treating the whole batch as a failure.

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

### Artifact read permission checks hardened against a check-time race, and support multi-file save messaging

Artifact file reads now detect a permission check that changed mid-flight, and report multi-file saves

**What**

When Claude Code checks permission for reading a file from an artifact (via `read_file`/`read_asset`), it now detects if a file-edit safety check or an "ask" permission rule for one of the destination files changed while the permission check was in progress. If that happens, the read is denied with a message explaining that nothing was read and to retry, rather than proceeding based on stale information.

- The permission-request wording also now distinguishes saving multiple files at once ("save N files ... to ...") from the existing single-file wording.

**Why**

This closes a race condition where a permission decision could be based on outdated information about a file's safety status, and makes the messaging clearer when several files are being saved from an artifact in one request.

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

### New artifact-egress network error message names the port and requirement

Artifact network errors now explain that outbound HTTPS on port 443 is required

**What**

When fetching an Artifact's content fails due to a plain network error, Claude Code now shows a specific message explaining that the machine running Claude Code needs outbound HTTPS access on port 443 for the Artifact tool to work, instead of a generic "network error" message. Some of these failures are also now marked with a new `transient` flag.

**Why**

This gives a clearer, more actionable explanation when an Artifact fetch fails because of a network or firewall restriction, instead of a vague error.

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

### Marketplace add gets a stricter no-replace safeguard for URL sources

Adding a plugin marketplace from a URL now guards more strictly against overwriting an existing one

**What**

When adding a plugin marketplace from a `url` source, Claude Code now hardlinks the downloaded catalog into its cache instead of always renaming it. If finalizing the cache fails, it now throws a much more explicit error explaining that adding a marketplace never silently replaces an existing one of the same name, and how to recover from the failure.

**Why**

This protects existing cached marketplaces from being unintentionally overwritten and gives a clearer error message with recovery steps if the add can't complete safely.

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

### New artifact watch error: 'watch target changed' when action/url no longer matches the approved watch

New error tells the user to retry when an artifact watch's action or URL no longer matches

**What**

The artifact watch tool (which monitors an artifact for changes) now returns a distinct error, `watch_target_changed`, when the `action` or `url` involved no longer matches the specific watch that was previously approved. The message tells the caller that nothing was carried out and to retry so the watch is checked again.

**Why**

This prevents Claude Code from silently acting on a stale or mismatched watch approval, instead surfacing a clear signal that the request needs to be re-checked before proceeding.

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

### Marketplace add now refuses to overwrite an existing marketplace registered from a different source

Adding a plugin marketplace now fails if the name is already registered from a different source

**What**

Adding a plugin marketplace (a catalog of installable [plugins](/docs/en/plugins)) now fails with an error if a marketplace with the same name is already registered but points to a different source. The error tells you to remove the existing marketplace first with `/plugin marketplace remove`.

**Why**

This prevents silently overwriting or conflicting with an existing marketplace registration that points somewhere else, making it explicit that you need to remove the old one before adding a same-named marketplace from a new source.

- Area: Plugins
- Names: `/plugin marketplace remove`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### New retry path: drop message-threads header on unrecognised HTTP 400

Claude Code now retries a thread-continuation request without its message-threads header after an unrecognized HTTP 400

**What**

When a request that carries the "message-threads" header (used for thread continuation, or "tether") gets back an HTTP 400 error that isn't one of the already-known thread-related error codes, Claude Code now automatically resends that turn without the header, treating it as a stateless request. For the rest of that session, the thread type is then marked as dropped.

**Why**

This lets a conversation keep going instead of failing outright when an unexpected server error is tied to thread continuation, at the cost of falling back to a simpler, stateless request mode for the remainder of the session.

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

### AskUserQuestion / permission requests can be unwound mid-flight during shutdown

Pending questions and permission prompts are now forcibly rejected when a session shuts down mid-flight

**What**

When a Claude Code session is being torn down while it's still waiting on something from the user, such as an `AskUserQuestion` prompt or a tool permission request, those pending requests could previously hang or be silently dropped. A new mechanism now lets the session forcibly reject them instead, with a clear error: "the session is being torn down." This is checked both during normal handling of a permission request and when an error is already being handled.

**Why**

This prevents a session shutdown from leaving a question or permission prompt stuck waiting indefinitely, giving it a clean, explicit failure instead.

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

### Permission dialog answered away from the session is now rejected as a denial

Answering a permission prompt from outside the session now counts as a denial

**What**

When a tool permission decision is set to "ask" and the check finds that it was `localDisplayOnly` — meaning the permission card was answered somewhere other than the active session — the tool call is now denied outright, with the message "a permission card answered away from the session," instead of continuing through the normal ask-or-hook approval flow.

**Why**

This closes a gap where a permission prompt answered in the wrong place could otherwise be treated as a valid approval, ensuring such cases are safely rejected.

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

### Transcript loading now recovers from malformed content blocks and unreadable rows instead of failing

Loading a transcript now repairs malformed or unreadable rows instead of failing outright

**What

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

### Remote session no longer wipes all streaming tool-use indicators on any message

Remote sessions no longer clear all in-progress tool indicators when any message arrives

**What**

In a remote session, Claude Code shows a small indicator while a tool call is still running. Previously, receiving any new message from the assistant would clear every one of these in-progress indicators, even for tools that were still running. Now, only the indicators for tool calls that actually finished (matching the completed tool-use blocks in that message) are cleared; indicators for tools still in flight are left alone.

**Why**

This fixes a case where a remote session's UI could show a tool as no longer running even though it was still executing, because an unrelated message happened to arrive and wiped its indicator.

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

### New dedicated errors for oversized/failed ripgrep output collection

Grep searches now report distinct errors when ripgrep output is too large or fails to collect

**What**

When Claude Code's grep tool runs a search internally using ripgrep, collecting the output can now fail in two clearly distinct ways:

- a general `RipgrepOutputError`, which includes a suggestion to narrow the search

- a `RipgrepOutputTooLargeError`, which fires when the search output exceeds a size cap before even a single complete line was produced, with separate messages depending on whether it was standard output or error output that overflowed

**Why**

This gives clearer, more specific error messages when a search produces too much output, and points toward the fix (narrowing the search) instead of a generic failure.

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

### Headless cloud client permission/dialog forwarding bug fix

Fixed a bug where headless cloud sessions forwarded the wrong argument for permission and dialog requests

**What**

In the headless cloud client, two functions that forward permission requests and user dialog requests (`passPermissionRequest` and `passUserDialogRequest`) were mistakenly passing the same argument twice instead of forwarding the actual request object along with its second argument. This has been fixed so both arguments are now passed correctly and distinctly.

**Why**

This fixes a bug that likely caused permission and dialog requests in headless cloud sessions to be handled with incorrect or missing data, since the real request object wasn't being forwarded properly.

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

### Design system publish can now bypass file-permission checks for font files

Publishing the design system now lets font files through even if permission rules would otherwise block them

**What**

When Claude Code saves 'the design system' to disk, it now checks whether a file is a font file. If it is, the file is allowed to be written even when the usual permission-rule filtering would otherwise have blocked it, and the write is tagged internally with the reason 'font file'.

**Why**

Font files are needed for a design system to render correctly, so blocking them on permission grounds could leave the design system broken. This exception avoids that failure mode for fonts specifically.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### MCP binary content that can't be saved to disk now falls back to an inline size summary in some mode

MCP binary results that fail to save to disk now show a friendlier message instead of a raw disk error

**Unclear.** What the new condition checks and when it is set isn't stated, so it's unclear which failures get the friendlier message versus the raw error.

**What**

When Claude Code tries to save binary or blob content returned by an MCP tool (an external tool connected via the Model Context Protocol) to disk and that save fails, it now checks a new condition. If that condition is set, the result shown is a plain message saying the content was not kept because it could not be saved, instead of the raw disk-error text. This applies across tool results, resources, and images.

**Why**

This replaces a technical, possibly confusing disk-error message with something a user can actually understand when MCP binary content can't be persisted.

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

### queued_notification control messages now require a remote transport

Queued-notification messages are now dropped unless the session is running over a remote connection

**What**

In the message-handling loop used by Claude Code's print mode and SDK, an inbound `queued_notification` control message is now rejected (and not acknowledged) if the session isn't using a remote transport (the connection type used for remote-controlled or cloud sessions). A warning is logged and a telemetry event is recorded when this happens.

**Why**

Queued notifications are meant for remote/bridged sessions; discarding them on other transports avoids processing a message type that doesn't apply there and helps catch cases where one arrives unexpectedly.

- Area: Remote Control
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### poll_event now validates the `kind` format, not just reserved names

MCP poll_event now rejects malformed kind values, not just reserved names

**What**

The MCP (Model Context Protocol, the standard Claude Code uses to talk to external tools) `poll_event` control request now validates the format of the `kind` value it's given before checking whether that name is reserved. A valid `kind` must start with a lowercase letter and contain only lowercase letters, digits, and hyphens after that, up to 64 characters. The wording used when a `kind` is rejected as reserved has also changed.

**Why**

This catches malformed event kinds earlier and more clearly, rather than only rejecting names that happen to collide with reserved ones.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact stale-guard reads now retry once on transient failure

Artifact stale-guard reads now retry once automatically after a transient failure

**What**

The "stale guard" read that checks whether a hand-off artifact is out of date now recognizes transient, retryable failures, distinct from permanent errors, "gone" errors, other-organization errors, or never-published/public-unasked cases, based on either a retryable HTTP status or a transient-failure flag. When such a failure occurs, the read is now retried once after a fixed delay, and the retry is recorded in its telemetry.

**Why**

This makes the stale-guard check for hand-off artifacts more reliable by recovering automatically from temporary failures instead of giving up immediately.

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

### Artifact copy_from not_found error drops the 'another organization' case

Artifact copy_from error message no longer mentions 'another organization' as a possible cause

**What**

When copying content between Artifacts with `copy_from` fails because the source can't be found or opened, the error message shown no longer lists "is in another organization" as one of the indistinguishable possible reasons.

**Why**

The error is now slightly less specific about why a copy might fail, though the underlying permission checks for `copy_from` still apply.

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

### Policy-limits cache write now refuses to stamp when the existing stamp can't be read

Policy-limits cache no longer overwrites its stamp when the existing one can't be read

**What**

When Claude Code saves updated policy-limits data to its local cache, it now first checks whether it could actually read the existing on-disk "stamp" (a marker used to track the cache state). If that read failed, the save is aborted entirely for that cycle and nothing is written, with a log noting the cache stamp could not be read. Previously it would proceed to overwrite regardless.

A companion testing-only method, `_settleCyclesForTesting`, was also added to let tests wait for all in-progress fetch cycles to finish.

**Why**

This avoids silently clobbering the policy-limits cache when its current state can't be verified, reducing the chance of corrupting or losing track of cached policy data.

- Area: Policy Limits
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Git fetch debug-trace no longer inherits the parent environment

Git fetch debug tracing now runs with only GIT_TRACE_PACKET set, not the full environment

**What**

When Claude Code retries a `git fetch` with packet-level tracing turned on (a debug mode that logs the raw network exchange for troubleshooting), the process it spawns for that retry used to inherit the full parent environment plus the `GIT_TRACE_PACKET` variable. It now runs with only `GIT_TRACE_PACKET: "1"` set, and nothing else from the surrounding environment.

**Why**

This narrows what the traced git process has access to during the retry, which mainly affects debugging output rather than normal git operation.

- Area: Git
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### WaitForMcpServers falls back to failed servers when nothing is pending or cached

WaitForMcpServers now also waits on servers that already failed to connect, not just pending ones

**What

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Idempotent retry with id-reuse added to artifact comment-reply posting

Artifact comment replies now retry once on server errors and detect their own duplicate posts

**What**

Posting a reply to a comment on an artifact now handles temporary server failures more gracefully. If the server returns a 5xx error or a 499 (request cancelled), Claude Code waits a random 800-1500 milliseconds and retries once, reusing the same client-generated ID for the retried request. If that retry then gets back a 409 "id_in_use" conflict, meaning the original request had actually already succeeded, it's now treated as a successful replay rather than as an error.

A new telemetry reason called `id_in_use` records this case, and Claude receives an explicit "outcome unknown" message telling it to re-read the comments before retrying, rather than assuming a reply needs to be reposted.

**Why**

Without this, a temporary server hiccup could either cause a genuinely failed reply to be silently dropped, or cause Claude to blindly repost a reply that had actually gone through, resulting in duplicate comments. This makes retries safer and reduces both duplicate and lost replies.

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

### Large tool-result files: fallback savedHint when the save itself failed

Tool results now get a clear hint when saving oversized output to a temp file itself fails

**What**

When a large tool result (from an MCP task, a way of running external tools) is too big and Claude Code tries to save the overflow to a temporary file, that save can itself fail. Previously, if this happened, the truncated text was returned with no explanation. Now, when the save fails, a fixed message is attached explaining that the full output could not be saved.

**Why**

This stops the model from silently receiving cut-off tool output with no indication that something went wrong, making it clearer that the missing portion isn't just intentionally omitted but genuinely lost.

- Area: Tool Results
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Git-tracked-status check now accounts for a worktree override

Git tracked/untracked file checks now account for an active worktree override

**What**

When Claude Code checks whether a file is tracked or untracked by git, it now first checks for a worktree path override before falling back to the normal check based on the current working directory. It checks both the override path and the equivalent path relative to the parent repository.

**Why**

This makes git status checks behave correctly when Claude Code is operating against a worktree (an alternate checkout of a git repository) rather than the main working directory, so tracked/untracked status is reported accurately in that case.

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

### Timed-out parked permissions now always retire

A parked permission request that times out now always ends the interrupted turn

**Unclear.** The finding doesn't say what happened for timeouts outside that condition before this change, only that it was inconsistent.

**What**

When Claude Code is waiting on a permission decision (approving or denying a tool call) that gets parked and then times out, the interrupted turn is now always retired as unanswered.

**Why**

Previously this only happened under a specific internal condition, so a timed-out permission request could behave inconsistently depending on which part of the code path handled it. Now the behavior is consistent: a timeout always ends the turn rather than leaving it in an unclear state.

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

### AWS credential pair sandboxing dedupe fix

Fixed a bug in sandbox handling of AWS credential pairs that compared the wrong entries

**What**

The logic that handles AWS access-key and secret-key pairs inside the sandbox (an isolated environment Claude Code can run commands in) was reworked. The sorting and deduplication of credential pairs, and the way conflicting slots get suffixed, were restructured, fixing a bug where the wrong loop variable was being compared when deciding which AWS credential pairs were functional versus not.

**Why**

The previous bug could cause the sandbox to mismatch or misrank AWS credential pairs, potentially treating a working pair as broken or vice versa. The fix makes that comparison correct.

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

### Deep-link handler content no longer trimmed

Deep-link file content is no longer path-formatted or trimmed before display

**What**

When Claude Code's deep-link handler displays a file's contents as "Contents of {path}:" followed by the file text, it now uses the raw path directly instead of passing it through a formatting function, and it no longer trims whitespace from the content before showing it.

**Why**

This means the displayed path and file content now appear exactly as stored, without the previous formatting or trimming applied.

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

### Path-normalizing helpers no longer require a leading slash

Two path-normalizing helpers now accept relative paths, not just absolute ones

**Unclear.** The finding does not say which callers rely on these helpers or what effect processing relative paths has downstream.

**What**

Two internal path-handling helper functions previously rejected any input that didn't start with a leading slash (`/`), returning null for relative paths. That restriction has been removed, so both functions now also process relative paths.

**Why**

This broadens where these helpers can be used, since they no longer fail outright on relative paths.

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

### Forked (inline) subagents no longer inherit their parent's tool-call replay log

Forked inline subagents now start with an empty tool-call replay log instead of inheriting the parent's

**What**

When launching a forked (inline) subagent, Claude Code previously built its tool-call replay log either by reusing an existing one from tool state or reconstructing it from resume messages. It now always starts the forked subagent with an empty log.

**Why**

This means a forked subagent no longer carries over its parent's history of prior tool calls into its own replay log, giving it a clean slate rather than inherited context from the parent session.

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

### Reply-to-comment tool call is now idempotent via a client id, and reports replayed sends

Replying to an Artifact comment is now safe to resend, and reports when a resend was detected

**What**

The Artifact tool's 'reply' comment action now generates a unique client id for each reply request and sends it along with the reply. If the same request is sent again (for example after a network hiccup), the server can recognize it as a repeat rather than posting a duplicate reply, and the result now includes `replayed: true` when that happens.

**Why**

This prevents the same comment reply from being posted twice if a request has to be retried, and lets the caller know when that protection kicked in.

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

### Artifact comment reply gains retry-on-transient-failure path

Artifact comment replies can now retry instead of failing immediately on a transient error

**What**

When replying to a comment on an artifact fails, Claude Code now checks whether the failure looks like a temporary relay problem versus a generic network error. If the caller has asked for retry behavior, a transient failure now returns a result telling it how long to wait and that it should retry, rather than failing outright.

**Why**

This means a temporary hiccup in sending a comment reply no longer has to be treated as a permanent failure, reducing spurious errors from brief network or relay issues.

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

### npm marketplace/plugin source schema gains registry URL validation and richer docs

npm-based plugin marketplaces now validate registry URLs and support scoped allow/block policies

**What**

When installing a plugin or defining an npm-based marketplace source, the `registry` field is now checked to make sure it's a valid http or https URL, and Claude Code now rejects it otherwise with the message "Registry must be an http(s) URL".

The npm marketplace source definition also gains new `version` and `registry` fields, and the documentation now explains that policies like `strictKnownMarketplaces` and `blockedMarketplaces` can control npm-based marketplace plugins by:

- an exact package name

- a scope wildcard, such as `@acme/*`

- the `registry` value, which acts as an allowed prefix for the plugin's download URL

**Why**

This lets administrators lock down which npm-based plugin marketplaces are allowed, by name, by organization scope, or by trusted registry, and stops obviously malformed registry URLs from being accepted.

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

### Marketplace clone-target self-check now bidirectional

Marketplace directory collision check now runs in both directions

**What**

When fetching a plugin marketplace, Claude Code already checked whether the target directory was already registered as a different marketplace. It now also runs the reverse check, to see if the new marketplace's directory collides with an existing one the other way around.

**Why**

This closes a gap where a directory-name collision could previously be caught in one direction but not the other, giving a more reliable "cannot fetch this marketplace" error when clone directories conflict.

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

### New unhandled-response fallback for saved-output hint

Saving MCP task output now returns a saved-output hint even when the save itself fails

**Unclear.** What the savedHint value actually conveys to the user is not stated.

**What**

When Claude Code tries to save the result of an MCP task to a file and that save fails, it now checks an additional condition and, when it applies, still includes a `savedHint` field alongside the truncated text in the response, instead of returning only the truncated text as before.

**Why**

This gives a hint about the saved output even in a failure case that previously returned nothing extra, though the finding doesn't specify what that hint tells the user.

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

### Sandbox proxy trap now preserves the shell's exit code

Sandbox proxy script now preserves the shell's real exit code instead of masking it on exit

**What**

The launcher for the socat-based sandbox proxy has a shutdown trap that runs when the process exits. Previously it just killed background processes and exited plainly; now it first captures the actual exit code (`$?`), kills the background processes, and then re-exits with that captured code.

**Why**

This means a sandboxed shell's real exit status is now correctly reported when it finishes, instead of being overwritten by the cleanup logic, so scripts or tools checking the exit code get an accurate result.

- Area: Sandbox
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Loading-verb wordlist gets American-spelling cleanup and duplicate removal

Claude Code's loading-status word list gets American spellings and a duplicate removed

**What**

The list of randomly-chosen status words shown while Claude Code is working (like "Perambulating" or "Percolating") had two entries changed to American spelling: "Philosophising" became "Philosophizing" and "Unravelling" became "Unraveling". A duplicate "Channelling" entry was also removed, since "Channeling" was already in the list.

**Why**

This is a small cosmetic cleanup of the status-word list with no functional effect.

- Area: UI
- Tier: You'll notice
- Useful: 1/5
- Signal: 0/5

## In Development

### New "queued_notifications" capability advertised to session context under a remote/live gate

poll_event now rejects malformed kind values with a stricter format check before checking if they're reserved

**What**

The `poll_event` control request (used by MCP, the Model Context Protocol that connects Claude Code to external tools) now checks that the `kind` value it's given has a valid format before checking whether it's a reserved name. A valid `kind` must start with a lowercase letter, followed only by lowercase letters, digits, or hyphens, and be at most 64 characters long. Malformed values are now rejected with a message describing this format. The wording used when a kind is reserved has also changed.

**Why**

This catches badly formed `kind` values earlier and gives a clearer error explaining the expected format, rather than only checking against a list of reserved names.

- Area: MCP
- Names: `queued_notifications`
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### REPL bindings retained across compaction, currently dark

Compaction can now note that REPL variable state was preserved, though this is not yet active

**Unclear.** The finding describes this as currently dark; whether or how it is enabled for any accounts is not stated.

**What**

When Claude Code compacts a conversation (summarizing it to save space), the summary can now include a note that your REPL or notebook variable bindings were kept across the compaction. This replaces the older signal that indicated REPL state had been cleared, with a new `replBindingsKept` field populated from tool state.

**Why**

If active, this would reassure you that variables defined during a REPL or notebook session survive a compaction rather than being lost, but the finding indicates this capability is currently dark, meaning not yet switched on.

- Area: REPL
- Names: `replBindingsKept`
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### Async subagent stall watchdog can now "park" instead of aborting

Background subagents that stall can now be 'parked' with a synthesized result instead of always erroring out

**What**

When a background (async) subagent's stall watchdog detects it has stopped making progress, Claude Code can now handle it two ways:

- As before, hard-abort the run with a "stall watchdog fired" error

- Or, newly, synthesize a completion from whatever transcript exists so far, inject a message, and mark the run as "parked" with a summary and usage information instead of an outright failure

**Why**

This means a stalled background subagent can now produce a usable partial result instead of always just failing, though this behavior sits behind settings (`tengu_zinc_harbor` and `tengu_async_agent_stall_timeout`) that haven't been confirmed active for this release.

- Flag `tengu_zinc_harbor`: Off in both readings (read for one account on one subscription tier against v2.1.275; 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: Subagents
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### Startup promo / limit-wall promo feature

New startup promo system tracks how often it's shown and adds a 'claim credit' option at usage limits

**Unclear.** What the promo or credit actually is, and who is eligible, isn't specified in the evidence.

**What**

Claude Code now tracks a startup promotional message internally: how many times it's been shown (capped at 3 shows) and whether the user is eligible or has already claimed it. When a usage limit is hit, the list of options shown (upgrade, extra usage, cancel, auto-resume, and others) now includes a new `limit-wall-promo` choice, and a new CLI action called `claim-credit` has been added.

- A new notice can also appear in the app's general notice area, shown at medium priority when a usage-reset or limit condition is met.

**Why**

This adds a way for Claude Code to promote and let users claim some kind of credit or offer, surfaced both at startup and when a usage limit is reached.

- Area: Promotions
- Names: `limit-wall-promo`, `claim-credit`
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### Async-agent 'park' fallback behind tengu_zinc_harbor

Stalled background subagents can now be 'parked' with a partial result instead of aborted, behind an off flag

**What**

When a background subagent's tool loop stalls but it has already produced at least one message, Claude Code can now, instead of aborting the subagent outright, synthesize a completion from what it produced so far, mark the subagent as "parked," and clear any tool calls still in flight. This is recorded with a new telemetry event called `subagent_park`.

This behavior is controlled by the `tengu_zinc_harbor` setting.

**Why**

Parking preserves partial work from a stalled subagent rather than discarding it. As of this release the setting behind it has tested off for this site's account and for the anonymous baseline, and has not yet been read under this release, so it is not yet active in practice.

- Flag `tengu_zinc_harbor`: Off in both readings (read for one account on one subscription tier against v2.1.275; 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: Subagents
- Names: `subagent_park`
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### Background-agent "park on Escape" path gated behind tengu_zinc_harbor, off by default

Escape can now 'park' running background agents instead of just ignoring them, gated behind tengu_zinc_harbor

**What**

A new function interrupts and 'parks' running background agents or tasks when you press Escape mid-turn. It posts a transcript notice saying background agents were interrupted by the user and parked, along with a status-bar hint telling you to send a message to resume them. Without this new behavior, the old fallback (which does nothing) still runs.

**Why**

This gives a clearer signal when Escape interrupts background work, showing what happened to those agents and how to pick them back up, instead of leaving their state unclear.

- Flag `tengu_zinc_harbor`: Off in both readings (read for one account on one subscription tier against v2.1.275; 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: Background Tasks
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### Hidden 'claim-credit' local tool tied to a startup promo

A hidden new tool lets Claude open the page for a startup promotional offer

**Unclear.** Nothing has been read about the `tengu_swift_lynx` gate, so it's unclear whether or how this promo is currently shown to any accounts.

**What**

Claude Code now has a hidden internal tool called `claim-credit` that opens the page for whatever promotional offer was shown at startup. It only becomes available when a startup promo configuration is present, which is controlled by a setting called `tengu_swift_lynx`.

**Why**

This lets Claude act on a startup promotion (for example claiming an offer) shown to the user, rather than the user having to navigate to it manually.

- Flag `tengu_swift_lynx`: Not enough to say (read for one account on one subscription tier against v2.1.275; 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: Promotions
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 3/5
- Present in the build but not switched on

### Promotional-offer / credit-claim flow added, gated by org policy

A new promotional-offer and credit-claim flow was added, controlled by an org policy setting

**What**

Claude Code now has an internal system for showing promotional offers and letting users claim credit. It tracks how many times a startup promo has been seen, caches eligibility and claim status, sends related telemetry, and adds a `claim-credit` CLI action and an interactive `limit-wall-promo` prompt case.

Whether this is shown is controlled by an organization compliance policy called `allow_promo_offers`, which is allowed by default and denied only when the organization is in HIPAA mode.

**Why**

This lets Claude Code surface credit or promo offers to eligible users, while organizations under stricter compliance requirements like HIPAA mode never see them.

- Area: Promotions
- Names: `claim-credit`
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 3/5
- Present in the build but not switched on

### New "limit wall" promo option added to the rate-limit options menu

Rate-limit menu gains a new promotional "limit wall" option pointing to a claim page

**What**

The options menu that appears when a user hits usage limits now has a new selectable entry, `limit-wall-promo`. Its label and text come from a remote-configured object with a notice line, label, body text, and a claim-page line. Selecting it shows "Opening the claim page…" and records a `tengu_rate_limit_options_menu_select_limit_wall_promo` telemetry event; a matching notice is also wired into the general notice system.

**Why**

This adds a way for Claude Code to point rate-limited users toward a promotional claim page directly from the limits menu, controlled by remote configuration rather than being hardcoded.

- Flag `tengu_swift_lynx`: Not enough to say (read for one account on one subscription tier against v2.1.275; 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.
- Flag `tengu_smooth_forest`: Not enough to say (read for one account on one subscription tier against v2.1.275; 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: Promotions
- Names: `limit-wall-promo`
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 3/5
- Present in the build but not switched on

### New 'memory-mode' session log entry type has no writer call site

New 'memory-mode' session log entries are fully plumbed through loading and merging, but nothing yet writes them

**Unclear.** What triggers a memory-mode stamp once the writer is called, and what the feature is for, is not stated.

**What**

Claude Code's session-transcript system now recognizes a `memory-mode` entry type, merged using an "accumulate" policy alongside existing types like `mode` and `permission-mode`. Reading, writing, and merging support for these entries (via `memoryModeStamps`) has been added throughout every place sessions get loaded: resuming without a file, reloading a full log, building log lists, and replaying JSONL logs. A writer function exists that records mode, timestamp, and optional reason/account fields and appends them as `memory-mode` entries to the session file, draining a queue of pending stamps whenever unwritten ones exist, but nothing in this build currently calls that writer.

**Why**

This groundwork has no current effect on sessions, since no code path yet triggers the writer, but it lays the plumbing for a future feature that stamps sessions with memory-mode changes.

- Area: Sessions
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 3/5
- Present in the build but not switched on

### Coordinator read-only Bash restriction is fully built but hard-disabled

A read-only restriction on the coordinator's own Bash commands is fully built but currently disabled

**What**

New code would restrict the commands that Claude Code's coordinator session (the top-level session that delegates work to worker subagents) can run directly in Bash. If enabled, the coordinator could only run commands verified to be read-only, could not change directories (blocking `cd`, `pushd`, `popd`, `chdir`), and could not pass anything beyond a command, description, and timeout — anything else would have to be delegated to a worker.

However, the function that would turn this restriction on is hardcoded to always return false, so none of it currently takes effect.

**Why**

This is inactive groundwork for tighter separation between the coordinator and its workers. Nothing changes for current users until this is enabled.

- Area: Bash Tool
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 3/5
- Present in the build but not switched on

### Retrieved-memory citations can now be tagged inline with <cc-memory>

Memory citations can now be tagged inline with markup

**Unclear.** This is controlled by the tengu_salt_marsh gate; no reading of this release's default has been taken yet, and the earlier reading (off for this site's account and for the anonymous baseline) predates this release.

**What**

When enabled, memory retrieval (pulling relevant saved memories into a conversation) now instructs the model to wrap any sentence that cites a retrieved memory in `...` tags. New parsing logic detects and truncates these tagged sentences, recognizing several tag spellings (`cc-memory`, `cc_memory`, `ccmemory`) regardless of case.

**Why**

Tagging which sentences cite a memory makes it possible to surface memory citations distinctly in the interface, for example showing which files a claim was drawn from.

Gate state note

- Flag `tengu_salt_marsh`: Off in both readings (read for one account on one subscription tier against v2.1.275; 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: Memory
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 2/5
- Present in the build but not switched on

### Orphaned backgrounded tasks get auto-aborted and quietly parked

Background tasks left running after their owning agent disappears are now automatically stopped

**What**

When a task running in the background loses its owning agent (the agent that started it no longer exists), Claude Code now detects this and automatically stops it, rather than letting it keep running indefinitely. This only happens for tasks that are actually running in the background, have a way to be cancelled, and have already produced at least one successful (non-error) response. Once stopped this way, the task is marked as notified and "quietly parked."

A related change also adjusts how the app decides whether a completed background task still needs to stay alive, based on whether it's backgrounded and not already in another state.

**Why**

This prevents orphaned background tasks from consuming resources or running forever after the thing that started them is gone, while still preserving whatever useful output they had already produced.

- Flag `tengu_zinc_harbor`: Off in both readings (read for one account on one subscription tier against v2.1.275; 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: Background Tasks
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 2/5
- Present in the build but not switched on

### Artifact publish can now copy files across organizations (server-gated)

Publishing an artifact can now copy files across organizations, when the server supports it

**What**

When publishing an artifact involves copying files from another artifact, Claude Code can now pass a `cross_org_ok` flag to the upload service to allow that copy to cross organization boundaries. A new telemetry reason, `copy_predates_cross_org`, distinguishes servers that don't yet support cross-organization copying from other kinds of copy failures, and there's a dedicated refusal message shown when a server doesn't support it.

**Why**

This is a server-gated capability, so whether it actually works depends on the server the artifact is published to; the distinct error reason helps tell an unsupported server apart from a genuine copy failure.

- Area: Artifacts
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 2/5
- Present in the build but not switched on

### Memory extraction gains an optional 'laptop extract runner' hook

Memory extraction can now run an optional extra 'laptop extract runner' hook at the end of each turn

**Unclear.** What the 'laptop extract runner' does and when it is available is not stated.

**What**

The memory-extraction process that runs at the end of a turn now also instantiates and runs an optional "laptop extract runner" component, if one is available, alongside its existing extraction logic.

**Why**

The finding doesn't say what this runner does, so its practical effect on memory extraction isn't clear.

- Area: Memory
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 2/5
- Present in the build but not switched on

### Plugin source loading gains a `preview` option

Plugin source loading gains a preview option, off by default

**Unclear.** What the `preview` option actually changes about plugin installation is not stated.

**What**

The internal function used by marketplace and plugin add flows to install plugins from a source now accepts a `preview` option, which defaults to off.

**Why**

This is a groundwork change enabling some kind of preview behavior when installing plugins, though the finding doesn't describe what that preview does.

- Area: Plugins
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 2/5
- Present in the build but not switched on

### New internal event kind repl_mcp_needs_auth added to synthetic-message/state maps

New internal event type repl_mcp_needs_auth added for tracking MCP authentication needs

**Unclear.** placeholder

**What

- Area: MCP
- Names: `repl_mcp_needs_auth`
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 2/5
- Present in the build but not switched on

### Deep-link plugin install commands can be turned off by a new gate, `tengu_amber_tollgate`

A new gate can block plugin install links, requiring `/plugin install` to be typed manually instead

**What**

Claude Code supports installing plugins (bundles of extra commands and tools) via deep links, special links that trigger an install when clicked. A new control, the `tengu_amber_tollgate` gate, can now block these deep-link installs entirely. When blocked, instead of running or asking for confirmation, Claude Code shows: "Plugin install links are turned off. To install, type `/plugin install` yourself."

**Why**

This gives a way to disable one-click plugin installation from links, requiring users to explicitly run `/plugin install` themselves instead.

- Flag `tengu_amber_tollgate`: Off in both readings (read for one account on one subscription tier against v2.1.275; 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: Plugins
- Names: `tengu_amber_tollgate`, `/plugin install`
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 2/5
- Present in the build but not switched on

### HIPAA/ZDR policy gains two new gated capabilities

HIPAA/ZDR policy now also governs saving large tool results and promotional offers

**What**

The policy table that controls what's blocked under HIPAA and zero data retention (ZDR) modes gained two new entries: whether large tool results can be saved in the tool container, and whether promotional offers can be shown.

**Why**

This extends HIPAA/ZDR compliance controls to cover two behaviors that weren't previously governed by that policy, keeping tool-result storage and promotional messaging consistent with an account's compliance requirements.

- Area: Compliance
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 2/5
- Present in the build but not switched on

### Plugin hook modules loading gains a 'built-ins only' mode

Plugin hook loading gains a 'built-ins only' mode that can skip loading installed plugins' hooks

**Unclear.** The `tengu_plugin_hooks_modules` gate controls this, but nothing has been read about it, so it's unclear how widely or when built-ins-only mode actually applies.

**What**

When Claude Code loads plugin hooks (scripts that run at certain points in a session), it now computes a `builtinsOnly` flag before registering them. When this flag is on, installed (non-built-in) plugins' hook modules are not loaded, while built-in plugins' hooks still load normally, and a log message notes this.

**Why**

This gives Claude Code a way to restrict hook loading to only its built-in plugins, which could be useful for isolating behavior or troubleshooting.

- Flag `tengu_plugin_hooks_modules`: Not enough to say (read for one account on one subscription tier against v2.1.275; 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

### Permission-mode-at-request preserved for tool_use replies in 'arbiter' mode

A new internal helper preserves the permission mode a tool request was made under when replying to it in 'arbiter' mode

**Unclear.** The gate `tengu_radiant_teapot` controlling this has no recorded reading, so whether it is active for any account is unknown.

**What**

When Claude Code is running in an 'arbiter' permission mode (a mode governing whether tool calls need approval), a new internal helper now restores the exact permission mode that was in effect when a given tool_use request was originally made, and applies it when replying to that request. This only kicks in when the effective mode resolves to 'arbiter' and an internal gate check passes.

**Why**

This keeps replies to in-flight tool calls consistent with the permission rules that were active when the call was issued, rather than picking up whatever mode happens to be current when the reply is processed.

- Flag `tengu_radiant_teapot`: Not enough to say (read for one account on one subscription tier against v2.1.275; 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
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 2/5
- Present in the build but not switched on

### SDK-host (bridge) lane can now apply a model or effort pick sourced from claude_code_args

SDK-host sessions can now have their model or effort level set from claude_code_args in auto mode

**What**

When Claude Code runs as an SDK-embedded host (the "bridge" lane used when Claude Code is driven through the SDK rather than directly), new server-config functions read a `claude_code_args` value from auto-mode facts. If it specifies a model or an effort level that differs from what's already applied, Claude Code now applies that pick to the session, logging either "sdk-host lane model pick applied" or "sdk-host lane effort seeded." If the host refuses to apply it, a warning is logged instead.

**Why**

This lets settings passed in via `claude_code_args` actually take effect on SDK-hosted sessions, and gives visibility (through the logged messages) into whether the change succeeded or was refused.

- Area: SDK
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 2/5
- Present in the build but not switched on

### New 'promo-startup' announcement slot added to the status/announcement rotation

A new 'promo-startup' announcement can now appear in Claude Code's status/announcement rotation

**What**

A new promotional announcement slot, `promo-startup`, has been added to the rotation of announcements Claude Code can show. It comes with its own impression cap, a campaign priority, and a set of conditions that must all be true for it to actually be shown, including checks for whether the release slot applies, whether the account is held out of the promo, and whether it has been suppressed.

**Why**

This lets Claude Code surface a new promotional message to eligible users without affecting other existing announcements, since it's gated independently.

- Area: Promotions
- Names: `promo-startup`
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 2/5
- Present in the build but not switched on

### Alternate background-agent-stop path behind tengu_zinc_harbor flag

A new alternate way to stop background agents on cancel exists behind an unreleased flag

**What**

When you cancel (Ctrl-C) while background tasks are running, Claude Code can now take one of two paths to stop those background agents, depending on a feature flag called `tengu_zinc_harbor`.

**Why**

This is internal groundwork for changing how background agents get stopped on cancel; it isn't yet active for general users.

- Flag `tengu_zinc_harbor`: Off in both readings (read for one account on one subscription tier against v2.1.275; 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: Background Tasks
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 2/5
- Present in the build but not switched on

### Auto-naming for unnamed background subagents behind tengu_zinc_harbor

Unnamed background subagents can now get an automatic display name

**What**

When you launch a subagent (a helper agent Claude Code spawns to work on a task) to run in the background without giving it an explicit name, Claude Code can now generate and assign a display name for it automatically, instead of leaving it unnamed. Subagent types that are purely observers, such as Explore or Plan, are skipped.

**Why**

Automatic names make it easier to tell background subagents apart when several are running at once.

- Flag `tengu_zinc_harbor`: Off in both readings (read for one account on one subscription tier against v2.1.275; 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: Subagents
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 2/5
- Present in the build but not switched on

### New plugin-install-link confirmation dialog, gated by an untested flag defaulting off

A new confirmation dialog for plugin-install links is built but currently keeps those links blocked

**What**

Claude Code has new code for a confirmation dialog that appears when a plugin install command arrives from a deep link (a clickable link that opens Claude Code and pre-fills a command). The dialog shows "Run this command?" and "This command came from a link:", and waits for the user to press y or n before running it.

Whether this dialog can ever appear depends on a remote setting called `tengu_amber_tollgate`. As shipped, that setting defaults to off, which means the underlying flag `installLinkOff` ends up true and plugin-install links are blocked outright rather than reaching the new confirmation prompt.

**Why**

Until `tengu_amber_tollgate` is turned on for an account, this change has no visible effect: plugin-install links stay blocked as before, just through a different code path.

- Flag `tengu_amber_tollgate`: Off in both readings (read for one account on one subscription tier against v2.1.275; 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: Plugins
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 2/5
- Present in the build but not switched on

### New hidden startup-promo command gated behind remote flag tengu_swift_lynx

A hidden command to reopen a startup promo's offer page appears, gated behind tengu_swift_lynx

**Unclear.** Nothing has been read about the tengu_swift_lynx gate, so whether or how it is switched on for any account is unknown.

**What**

New internal state fields (`promoStartupConfig`, `promoStartupConfigParse`, `promoStartupLoginsSeen`, `promoStartupLoginEnded`) back a hidden local command that opens the page for whatever offer was shown at startup. It only activates when a remote configuration value tied to the `tengu_swift_lynx` gate is set to something other than null.

**Why**

This is infrastructure for a startup promotional message with a way to revisit its offer page, but it stays inactive unless the remote configuration turns it on.

- Flag `tengu_swift_lynx`: Not enough to say (read for one account on one subscription tier against v2.1.275; 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: Promotions
- Names: `tengu_swift_lynx`
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 2/5
- Present in the build but not switched on

### Session-teardown 'leave questions standing' path has no caller

New leaveQuestionsStanding path rejects pending permission questions with a teardown message but nothing calls it yet

**Unclear.** No caller of `leaveQuestionsStanding()` itself was found, so it's unclear whether this path is yet triggered in practice.

**What**

A new internal method, `leaveQuestionsStanding()`, marks a session's permission controller as torn down and immediately rejects every pending human-facing permission or question request with the message "the session is being torn down", instead of letting them hang. A related `questionsFrozen()` and `questionsLeftStanding()` check is now consulted in many places across the SDK's control-request handling, including waits for `canUseTool`, `control_request` handling, and the `AskUserQuestion` tool's parking logic, all of which now short-circuit with the same teardown message rather than waiting indefinitely.

**Why**

This should prevent pending permission or question prompts from hanging forever when a session is torn down mid-flight, giving callers a clear rejection instead. This extends earlier work restructuring how permission checks like `canUseTool` are handled across session boundaries.

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

### New gate for surfacing tools disabled by remote config as "available if turned on"

New gates let Claude Code report tools that exist but are switched off as "available if turned on"

**What**

When Claude Code can't find a requested tool, it now has a new check for whether the tool actually exists but is currently disabled by remote configuration. If a gate called `tengu_gleaming_cupcake` is on and the session isn't running under HIPAA restrictions, such disabled tools are counted separately in the tool-resolution results. A second, separate gate called `tengu_joyful_anchor` supplies an allow-list of tool names used for a related decision elsewhere.

**Why**

This is groundwork for telling a user or model that a missing tool isn't unavailable outright, but rather switched off and could be turned on, rather than treating it as simply nonexistent.

- Flag `tengu_gleaming_cupcake`: Not enough to say (read for one account on one subscription tier against v2.1.275; 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_joyful_anchor`: Not enough to say (read for one account on one subscription tier against v2.1.275; 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: Tools
- Tier: Nothing to try yet
- Useful: 1/5
- Signal: 2/5
- Present in the build but not switched on

### Worktree copy now tries an atomic rename before falling back to exclusive create, behind a gate

Worktree file copying can now try a fast atomic rename before falling back to the old method, behind a gate

**What**

When Claude Code copies files for a git worktree, it now has a new path that stages the copy and then attempts an atomic rename directly onto the destination (with a retry for a Windows-specific file-exists error). Only if that rename fails does it fall back to the previous method of exclusively creating the destination file. This new rename-first behavior is controlled by a gate called `tengu_squishy_spring`.

**Why**

An atomic rename is typically faster and safer than the older copy method, so when enabled this should make worktree setup quicker without changing the end result.

- Flag `tengu_squishy_spring`: Not enough to say (read for one account on one subscription tier against v2.1.275; 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
- Tier: Nothing to try yet
- Useful: 1/5
- Signal: 2/5
- Present in the build but not switched on

### Async REPL request now hardcoded off

The internal 'async REPL request' check now always returns false

**Unclear.** It's unclear what user-facing feature relied on the async REPL request check, so the practical effect of disabling it is not known.

**What**

An internal function that used to compute whether an "async REPL request" (a background code-execution request) should happen now always returns `false`, regardless of the tool-permission mode passed into it.

**Why**

This effectively turns off whatever behavior depended on this check, though the finding does not say what that behavior was.

- Area: REPL
- Tier: Nothing to try yet
- Useful: 1/5
- Signal: 2/5
- Present in the build but not switched on

### Artifact creation reply can now tag URLs as agent-scoped, gated by a statsig flag

Artifact creation replies can now mark a URL as agent-scoped, controlled by a gated flag

**Unclear.** What agent-scoped actually changes about the URL or its access is not stated, and the gate `tengu_cobalt_plinth_medlar` is unread.

**What**

When Claude Code creates a new Artifact (a saved piece of generated content like a document or app), the message reporting success can now include `"agent_scoped"` when formatting the artifact's URL, depending on a check that is currently gated.

**Why**

This lays groundwork for treating some artifact URLs as scoped to the agent that created them, rather than general-purpose links, though the gate controlling it has not been read for this account.

- Flag `tengu_cobalt_plinth_medlar`: Not enough to say (read for one account on one subscription tier against v2.1.275; 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
- Tier: Nothing to try yet
- Useful: 1/5
- Signal: 2/5
- Present in the build but not switched on

### In-process teammate polling gets an idle timeout, behind tengu_zinc_harbor

In-process teammate polling can time out after a period of inactivity, gated off for now

**What**

The loop that polls an in-process teammate (a subagent running in the same process) for updates can now give up and report an `idle_timeout` result if nothing happens for a set number of milliseconds, in two places within that polling logic. This behavior is controlled by a setting called `tengu_zinc_harbor`.

**Why**

This would let Claude Code stop waiting on a teammate that has gone silent instead of polling indefinitely, but the setting controlling it is currently off for this site's account and for the general population, so it is not active yet.

- Flag `tengu_zinc_harbor`: Off in both readings (read for one account on one subscription tier against v2.1.275; 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: Elsewhere
- Tier: Nothing to try yet
- Useful: 1/5
- Signal: 2/5
- Present in the build but not switched on

### New codenamed gates amber_astrolabe, bison_cairn, larch_cistern

New internal flags added, including bashActFirstEnabled and three codename gates amber_astrolabe, bison_cairn, larch_cistern

**What**

Claude Code adds several new internal flags:

- `bashActFirstEnabled`, controlled by the experiment `tengu_gorse_plover` (or the `CLAUDE_CODE_GORSE_PLOVER` environment variable)

- three codename-style flags, `amber_astrolabe`, `bison_cairn`, and `larch_cistern`, each backed by its own experiment and a matching `CLAUDE_CODE_*` environment variable override

Several places in the code that used to read the `bison_cairn`, `larch_cistern`, and `amber_astrolabe` flags directly were rewritten to instead read fields off local event objects, such as `pollEmptyDispatch` and `ideSelection`.

**Why**

These are internal flags for gradually rolling out unreleased behavior, so nothing changes for most users yet. The shift away from reading the flags directly at some call sites suggests those particular checks are being replaced by more targeted logic.

- Flag `tengu_gorse_plover`: Off in both readings (read for one account on one subscription tier against v2.1.275; 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: Gates
- Tier: Nothing to try yet
- Useful: 1/5
- Signal: 2/5
- Present in the build but not switched on

### federationIdentity field declared and reset, but never populated anywhere in this bundle slice

A new federationIdentity field was added to identity tracking but nothing in this build sets it

**What**

Two internal classes that track identity information (alongside existing fields like `precedenceSource`, `authType`, and `accountInfo`) gained a new `federationIdentity` field, which starts and resets to an unfilled state. Nothing else in this build's code actually populates it with real data.

**Why**

This looks like groundwork for a future identity-federation feature; it has no visible effect yet since nothing in this release fills the field in.

- Area: Auth
- Names: `federationIdentity`
- Tier: Nothing to try yet
- Useful: 1/5
- Signal: 2/5
- Present in the build but not switched on

### New tengu gates: tengu_typed_koala, tengu_zinc_harbor, tengu_tranquil_crescent

Claude Code adds three new internal feature gates: typed_koala, zinc_harbor, tranquil_crescent

**Unclear.** The specific capabilities gated by `tengu_zinc_harbor` and `tengu_tranquil_crescent` are not named in the evidence, and no reading of any of the three gates has been taken under this release yet.

**What**

Three new internal feature gates were added:

- `tengu_typed_koala` gates a helper that checks whether a value isn't `'empty_store'`

- `tengu_zinc_harbor` gates an unnamed capability

- `tengu_tranquil_crescent` gates another unnamed capability

**Why**

These are internal rollout controls; the finding does not say what user-facing behavior any of them enables.

- Flag `tengu_typed_koala`: On for this account, and not off by default (read for one account on one subscription tier against v2.1.275; 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.
- Flag `tengu_zinc_harbor`: Off in both readings (read for one account on one subscription tier against v2.1.275; 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.
- Flag `tengu_tranquil_crescent`: Off in both readings (read for one account on one subscription tier against v2.1.275; 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: Gates
- Tier: Nothing to try yet
- Useful: 1/5
- Signal: 2/5
- Present in the build but not switched on

### Coordinator Bash safety restriction exists but is compiled off

A safety check that would block risky Bash calls from a coordinator agent exists in the code but is turned off

**What**

Claude Code now contains logic that would refuse a `Bash` tool call made by a 'coordinator' (an agent run without a `remoteCall`/`agentId`, meaning it isn't a spawned sub-agent) if the command isn't verifiably read-only and doesn't stay within the working directory. A refused call would throw the error 'coordinator Bash call refused at call time'. However, the function that turns this check on is hardcoded to always return false, so the restriction does not currently take effect.

**Why**

This appears to be groundwork for a future safety restriction that limits what commands a coordinator agent can run via `Bash`. Since the enabling switch is off, nothing changes for users yet, but the mechanism is now present in the codebase.

- Area: Bash Tool
- Tier: Nothing to try yet
- Useful: 1/5
- Signal: 2/5
- Present in the build but not switched on

### Tool filtering gains a coordinator/worker restriction check, currently hardcoded off

A new coordinator/worker tool-restriction check exists in the code but is currently disabled

**Unclear.** The finding does not say what the coordinator/worker restriction is meant to do once enabled.

**What**

The logic that decides which tools are available now includes an additional check related to a coordinator/worker restriction, but the gate function controlling it always returns false, so this new filtering has no effect in this build.

**Why**

Since the check is hardcoded off, nothing changes for users right now. It appears to be groundwork for a future restriction on tool availability.

- Area: Tools
- Tier: Nothing to try yet
- Useful: 1/5
- Signal: 2/5
- Present in the build but not switched on

### Empty no-op handler registered for a new 'repl_mcp_needs_auth' message kind, with no constructor found anywhere in the bundle

A new internal message type for MCP auth prompts is registered but nothing creates it yet

**Unclear.** The finding does not say what the message kind will eventually be used to display.

**What**

A new internal message subtype called `repl_mcp_needs_auth` was added to Claude Code's list of recognized message kinds, along with a handler that turns such a message into on-screen content. Right now that handler always returns nothing, and no other part of the app actually creates a message of this kind.

**Why**

This is groundwork for a future feature, likely a prompt telling the user an MCP server (a way Claude Code connects to external tools and data) needs authentication. It has no effect on current behavior since nothing triggers it yet.

- Area: REPL
- Names: `repl_mcp_needs_auth`
- Tier: Nothing to try yet
- Useful: 1/5
- Signal: 2/5
- Present in the build but not switched on

### New HIPAA-evidence check gates allow_web_fetch and allow_design_sync policy verdicts

Web fetch and design sync permissions now also depend on a new HIPAA compliance evidence check

**Unclear.** placeholder

**What

- Flag `tengu_tranquil_crescent`: Off in both readings (read for one account on one subscription tier against v2.1.275; 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: Compliance
- Tier: Nothing to try yet
- Useful: 1/5
- Signal: 2/5
- Present in the build but not switched on

### coordinatorReadOnlyBashEnabled cache field declared with no other reference

A new coordinatorReadOnlyBashEnabled cache field was added but nothing yet reads or writes it

**Unclear.** The finding does not say what a read-only bash mode for a coordinator would do, since nothing yet references the field.

**What**

A new field called `coordinatorReadOnlyBashEnabled` was added to the internal cache that stores feature-flag values, sitting alongside similar existing cached flags. Nothing else in the code reads or writes this field yet.

**Why**

This appears to be groundwork for a feature that is not wired up yet, so it has no effect for anyone using Claude Code right now.

- Area: Bash Tool
- Names: `coordinatorReadOnlyBashEnabled`
- Tier: Nothing to try yet
- Useful: 1/5
- Signal: 2/5
- Present in the build but not switched on

### Gate tengu_tranquil_crescent can hard-block allow_web_fetch/allow_design_sync policy checks

A new gate can now force-block web fetch and Design sync policy checks entirely

**Unclear.** The flag server returned this gate off for this site's account and off for the anonymous baseline, and no reading has been taken under this release yet, so it is not known to be active.

**What**

The function that checks the `allow_web_fetch` and `allow_design_sync` organization policies now returns false immediately, before doing any other checks, whenever a new gate (an internal on/off switch) called `tengu_tranquil_crescent` is enabled for the account.

**Why**

When this gate is on, it acts as a hard override that blocks web fetch and Design sync policy checks outright, on top of the existing policy logic. This builds on the earlier change where disabling Design sync already blocked the connection itself, not just the command.

- Flag `tengu_tranquil_crescent`: Off in both readings (read for one account on one subscription tier against v2.1.275; 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: Compliance
- Names: `tengu_tranquil_crescent`
- Tier: Nothing to try yet
- Useful: 1/5
- Signal: 2/5
- Present in the build but not switched on

### Command-queue clear can now optionally preserve certain entries, but the switch is hardcoded off

Command queue clearing gained a way to keep certain entries, but it's not turned on anywhere yet

**What**

When the queue of pending commands is cleared (for example, on a cancel), the underlying function now supports a `keep` option that would let commands matching a certain check survive the clear instead of being wiped. However, this option is not currently used anywhere, so the wipe still clears everything as before.

**Why**

This is groundwork for a future change; it doesn't currently change what you see when you cancel and your queue is cleared.

- Area: Message Queue
- Tier: Nothing to try yet
- Useful: 1/5
- Signal: 1/5
- Present in the build but not switched on

## Internal Changes

### Launch-time project root override (So()) threads through many subsystems

A new host-level project root override now controls settings, skills, MCP servers and LSP working directories

**What**

A new launch-time option lets the application hosting Claude Code (not the end user directly) override which directory is treated as the "project" or working directory. When set, this override takes priority over the current working directory for:

- resolving `.claude/` project settings

- substituting `CLAUDE_SKILL_DIR` and `CLAUDE_PROJECT_DIR` in skills and slash-commands

- the `CLAUDE_PROJECT_DIR` environment variable passed to MCP (Model Context Protocol) servers started over stdio

- the working directory used to start those MCP servers

- the working directory passed to LSP (Language Server Protocol) processes

When this override is active, Claude Code also skips scanning the filesystem for skill directories dynamically.

**Why**

This lets a host application run Claude Code from a different folder (for example a worktree copy) while still treating a separate folder as the "real" project root for settings, skills, and connected tools.

- Area: Project Config
- Tier: Under the hood
- Useful: 3/5
- Signal: 3/5

### New internal remedy metadata attached to tool results (SDKToolResultRemedy)

Tool results can now carry a structured 'remedy' code describing how to fix the underlying problem

**What**

Tool results (the output returned after Claude Code runs a tool) can now include a new internal `remedy` field. Instead of a host having to parse an error message to figure out what went wrong, the result can carry a structured code such as `mcp_needs_auth`, `mcp_disabled`, `mcp_required_missing`, `auth_expired`, `auth_overridden`, `auth_missing_scope`, `design_needs_authorization`, `sandbox_violation`, `outside_reads_blocked`, `memory_paused`, `feature_disabled`, `policy_denied`, `spawn_arg_limit`, or `staged_for_review`.

**Why**

This gives tools built on Claude Code (an MCP server, for example - a way of connecting external tools and data to Claude) a reliable way to tell what kind of fix is needed, rather than relying on guessing from freeform text.

- Area: Tool Results
- Tier: Under the hood
- Useful: 3/5
- Signal: 3/5

### Policy manifest gains session.root, prompt.read, ui.panes surface entries

Plugin API policy list adds session.root, prompt.read, and ui.panes as permitted actions

**What**

The internal manifest of known/permitted actions that plugins can request through Claude Code's API grew three new entries: `session.root`, `prompt.read`, and `ui.panes`. These join existing entries like `session.cwd`, `flag.value`, and the `ui.blit` family.

**Why**

This expands what plugins are allowed to access or do through the API, likely enabling plugin features that need the session's root directory, read access to prompts, or control over UI panes.

- Area: Plugin API
- Names: `session.root`, `prompt.read`, `ui.panes`
- Tier: Under the hood
- Useful: 2/5
- Signal: 3/5

### Artifact file-tracking gains content-hash 'pins' across publish/read/list

Artifact file changes are now tracked with content hashes across publish, read, and list operations

**What**

Claude Code now keeps a record, per file path, of a content hash (SHA-256) and version for files involved in artifacts, tagged with where that record came from: publishing (files written, removed, or copied), listing files, or reading files. This information is stored in a new `pathPins` map that is carried through when restoring a conversation and in the app's general state.

**Why**

This gives Claude Code a way to know exactly which version of a file it last saw or wrote, which helps avoid acting on stale or already-changed file content within an artifact.

- Area: Artifacts
- Tier: Under the hood
- Useful: 3/5
- Signal: 2/5

### New local image store for stored image content

A new local image store was added for saving stored image content to disk

**Unclear.** The finding does not say which features use this store or when images are written to it.

**What**

Claude Code has a new image-storage subsystem with functions to find the image store's directory, list the ids of stored images, and atomically write base64-encoded image content to disk, detecting the correct file extension from the image data itself. It logs a message when an image is stored successfully, or a warning if the image store is unavailable.

**Why**

This provides infrastructure for saving image content locally, which other features (such as poll events carrying media) can build on.

- Area: Images
- Tier: Under the hood
- Useful: 3/5
- Signal: 2/5

### Atomic file writes support a 'beforePublish' refusal hook

Atomic file writes can now be aborted mid-write by a new beforePublish check that throws PublishRefusedError

**What**

The internal helper Claude Code uses to write files and other artifacts safely (writing to a temporary location and then swapping it in, so a crash never leaves a half-written file) now supports a `beforePublish` check that runs just before the write completes. If that check returns false, the write is aborted, a new `PublishRefusedError` is thrown, and nothing is published, including cleaning up any empty placeholder file that may have been created along the way.

**Why**

This gives internal callers a way to cancel a write at the last moment based on some condition, without risking a partially-written or stray file being left behind.

- Area: File Writes
- Tier: Under the hood
- Useful: 3/5
- Signal: 2/5

### New 'profile' and 'federation' credential scope kinds

Credential scoping adds two new kinds, 'profile' and 'federation', alongside token and api_key

**What**

The logic that matches credential scopes, derives cache keys, and names cache files on disk now supports two new scope kinds, `profile` (`profileScope`) and `federation` (`federationScope`), in addition to the existing `token` and `api_key` kinds. Each new kind gets its own on-disk cache filename prefix and its own auth-description text.

**Why**

This extends Claude Code's credential system to recognize and cache credentials scoped by profile or by federation, in addition to the token and API-key scoping it already supported.

- Area: Auth
- Tier: Under the hood
- Useful: 3/5
- Signal: 2/5

### Structured 'remedy' schema added to tool_result_meta, already stamped by several real code paths

Tool results can now carry a structured 'remedy' field describing exactly what fix would resolve a failure

**What**

Claude Code added a new structured field called `remedy` that can be attached to a tool result's metadata. It captures a specific, known reason a tool call needs attention and, implicitly, what would fix it: cases like `mcp_needs_auth`, `mcp_disabled`, `auth_expired`, `sandbox_violation`, `outside_reads_blocked`, `memory_paused`, `feature_disabled`, `policy_denied`, and several others.

Several real code paths already set this field based on structured state from whatever produced the failure, rather than by scanning the result's text for keywords.

**Why**

Because the reason is now a defined category instead of free text, tools built on top of Claude Code can offer the right fix (like "reconnect this MCP server" or "request the missing permission") reliably, instead of guessing from error messages.

- Area: Tool Results
- Names: `remedy`
- Tier: Under the hood
- Useful: 3/5
- Signal: 2/5

### Plugin identifiers can now reference npm-scoped packages

Plugin identifiers can now reference npm-scoped package names like @scope/name

**What**

Plugin identifier parsing and validation now accept npm-style scoped package names in the form `@scope/name`. A plugin ID written as `@scope/name@npm` is parsed as the plugin name `@scope/name` with marketplace `npm`. A new validator checks that the identifier matches either the scoped or plain-name pattern and rejects identifiers containing `..` or `//`.

**Why**

This is what allows plugins published as scoped npm packages to be referenced by ID elsewhere in Claude Code, such as in the new npm-based marketplace and install-plugin deep links.

- Area: Plugins
- Names: `@scope/name@npm`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Skill/command/agent trust checks now consider multiple project config roots

Trust checks for skills, commands, and agents now look across multiple project config roots, not just one

**What**

When Claude Code decides whether to trust custom commands, agents, and skills defined in `.claude/commands`, `.claude/agents`, and `.claude/skills`, it previously checked a single hardcoded directory. That logic now iterates over a list of locations that includes the working directory and, if configured, a separate project-config-root path.

**Why**

Projects that keep their `.claude` configuration in a separate root from the working directory get correct trust checks instead of being evaluated against only the working directory.

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

### Multi-root scratchpad/base-directory resolution

Artifact base-path resolution can now match against multiple repository roots, not just one

**What**

The logic that redirects artifact base paths (used for scratchpad files) and the headless setup summary previously worked against a single current-working-directory or scratchpad path. Both now accept a list of additional repository roots and check redirected paths against any of them.

**Why**

This lets artifact and scratchpad path handling work correctly in setups spanning multiple repository roots rather than assuming just one.

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

### Policy-limits fetch telemetry gains auth-denial and injected-token-recovery fields

Policy-limits telemetry now records server auth denials and injected-token recovery outcomes

**What**

When Claude Code fetches an account's policy limits, it now performs an upfront check of the managed-configuration policy gate, and its telemetry and credential-state tracking gain new fields covering server-side authentication denials and the outcome of attempts to recover using an injected token.

**Why**

This gives more visibility into why a policy-limits fetch might fail due to authentication, and how token recovery attempts resolve, which helps diagnose account and credential issues.

- Area: Policy Limits
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New 'cloud_session_default' telemetry path and 'violin_wood_gate' flag for --remote session creation

Cloud/remote session creation now tracks whether the session type was defaulted, with a new telemetry event

**Unclear.** what the violin_wood_gate flag itself controls is not stated

**What**

Creating a remote or cloud session now records a boolean `defaulted` flag on its telemetry events, and fires a distinct `cloud_session_default` event when session creation is cancelled, fails, or succeeds. A separate telemetry flag called `violin_wood_gate` is now also reported alongside the existing model-gate hint event. Note that `--remote` is a deprecated alias for `--cloud`, including when reconnecting to an existing session.

**Why**

This lets Claude Code distinguish cases where a cloud session was created by explicit user choice versus by default, which helps understand how the `--cloud`/`--remote` flag is actually being used.

- Area: Sessions
- Names: `--remote`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Team-memory multistore sync gains a new basis-materialization step and richer telemetry

Team-memory multi-store sync gains a new materialization step and more detailed sync telemetry

**What**

The routine that syncs team memory across multiple stores now runs an additional step after it materializes the manifest (the record of what should be synced), when a certain internal setting is on. The telemetry event that summarizes each sync also gains three new fields: `off_retries`, `off_store_count`, and `off_pull_failure`, describing stores whose baseline data couldn't be used.

**Why**

This gives more visibility into cases where a memory store's underlying data is unusable, and adds a step to handle rebuilding a usable basis for that store, which should make multi-store team-memory syncing more resilient to inconsistent stores.

- Flag `tengu_typed_koala`: On for this account, and not off by default (read for one account on one subscription tier against v2.1.275; 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: Team Memory
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New 'memory-mode' session-history event type; removed 'marble-origami' commit tracking

Session history internally switches from 'marble-origami' commit tracking to a new 'memory-mode' event type

**Unclear.** What the 'memory-mode' event actually controls or reflects for the user is not stated.

**What**

Internally, Claude Code's session-history processing has replaced its previous commit-tracking event handling (referred to internally as 'marble-origami', which tracked commits, snapshots, and resets) with a new event type called `memory-mode`. This new event records whether a mode was turned on or off, along with a timestamp and, optionally, a reason such as `paused`, `session_shape`, or `server_off`.

**Why**

This is an internal bookkeeping change to how session history is recorded. It's not clear from this change alone what user-facing behavior, if any, depends on it.

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

### Tool results can now carry a 'remedy'

Tool results can now carry an internal 'remedy' value passed through to the assistant-visible message

**Unclear.** What a 'remedy' represents or when it is populated is not stated.

**What**

When Claude Code builds the message showing a tool's result, it can now carry an additional value called a `remedy`, which is threaded through into the resulting `toolResultRemedy` field.

**Why**

The finding doesn't say what a remedy is used for or when it's set, so it's unclear what this changes in practice for someone using Claude Code.

- Area: Tool Results
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New `defaultedToCloud` field threaded through session startup config

Session startup config gains a new defaultedToCloud field

**Unclear.** The finding does not say what consumes `defaultedToCloud` or how it changes session behavior.

**What**

The options object built during CLI startup, which already includes fields like `serveOnly` and `remoteControl`, now also carries a `defaultedToCloud` field. It's passed through to the interactive-session setup function.

**Why**

This tracks, as part of session setup, whether the session defaulted to running in the cloud, though the finding doesn't say how this field is used further.

- Area: Cloud Sessions
- Names: `defaultedToCloud`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Multi-store-sync writes gain a 'publish fence' that can drop writes and now return an explicit publish outcome

Storage sync writes gain a 'publish fence' that can drop a write and now report whether it published

**What**

When Claude Code syncs data across multiple storage backends, the write function now checks an optional `publishFence` on the backend, both before starting and again right before the final write. If the fence's file no longer exists, or its `mayPublish()` check returns false, the write is dropped and the old content is re-fetched instead of being overwritten.

The function also now returns an explicit `"published"` or `"dropped"` result instead of returning nothing.

**Why**

This prevents a storage sync write from overwriting data when another process has moved on or the write is no longer valid, and lets callers tell whether their write actually took effect.

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

### Remote control requests now carry attestation data

Remote control tool/permission requests now carry attestation data

**Unclear.** What attestation mechanism produces these values or how they are validated is not stated in the finding.

**What**

When a remote session forwards a tool or permission request to a callback (the code that decides how to handle it), it now also includes `attestationStatus` and `attestationRaw` fields alongside the existing timing information.

**Why**

This gives remote-control handlers more information to verify the authenticity of an incoming request before acting on it.

- Area: Remote Control
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Startup now tracks whether the session defaulted to cloud

Startup now records whether a session defaulted to running in the cloud

**Unclear.** What determines the default or what consumes this field downstream is not stated.

**What**

The options Claude Code builds when starting an interactive session now include a `defaultedToCloud` field, passed through alongside existing startup options like `disableSlashCommands`.

**Why**

This lets the rest of session setup know when a session ended up running in the cloud by default rather than by explicit choice.

- Area: Cloud Sessions
- Names: `defaultedToCloud`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### npm-marketplace plugin lane flag added to install/publish context

Plugin install/publish now handles npm-based marketplace plugins via a dedicated resolution path

**What**

When installing or publishing a plugin whose id matches an npm-marketplace naming pattern, Claude Code now marks the operation with an `isNpmMarketplaceLane` flag and resolves its version through npm resolution, rather than through the normal git/archive-based resolution used for other plugins.

**Why**

This lets Claude Code properly support plugins distributed via npm marketplaces, using version resolution appropriate to npm packages instead of the git-based flow.

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

### SDK model switching gains hook-gated flow with gateway/plan-mode side effects

SDK-driven model switches now go through hook approval and can affect auto/plan permission modes

**What**

When the SDK (the programmatic interface used to drive Claude Code) triggers a model switch, the handler for it now validates the target model, can short-circuit early via a bridge-print check, and routes the change through a hook-approval step, unless the session has no hooks pending, before applying it. Hooks are user-configured scripts that can approve, block, or modify actions. After the switch, the handler adjusts tool-permission context for sessions in 'auto' or 'plan' permission mode: it can deny the switch (recorded as `auto_gate_denied`) or update plan-mode context as appropriate.

**Why**

This means a model switch requested via the SDK can now be intercepted by hooks and can be denied or adjusted based on the session's current permission mode, rather than always applying immediately.

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

### Command list gained a plugin-facing filter hook

Command list gained an internal hook for plugins to filter which commands appear

**Unclear.** The finding shows the filtering machinery added but not which plugin-facing feature or command actually uses it.

**What**

The internal registry that manages Claude Code's list of commands gained a `filterCommands` option and a helper function, `applyCommandFilter`, that filters the command list against a given predicate (a test function).

**Why**

This appears to add infrastructure for plugins to filter which commands show up in the command list, though the finding doesn't show it wired to a specific plugin-facing feature yet.

- Area: Slash Commands
- Names: `filterCommands`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Auth-liveness check gains explicit injected-token recovery states

Login-credential health checks now recognize two ways an injected token can recover after failing

**What**

When Claude Code gets a 401 (an authentication failure) response and checks whether the login credential behind it is still working, it now looks at a new signal called `injectedTokenRecovery`, used specifically for credentials that were injected rather than logged in normally. This signal can be:

- `none`, meaning the credential is treated as dead (no longer usable)

- `sdk_host_refresh`, meaning the credential is still treated as live

- `runner_rotation`, meaning the credential is still treated as live

**Why**

Previously a 401 may have simply meant a credential was assumed dead. This change lets Claude Code recognize cases where an injected token can recover on its own, avoiding unnecessary treatment of a still-usable credential as broken.

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

### Policy-limits (org policy cache) gains HIPAA-evidence and WIF-principal robustness tracking

Org policy cache tracks more detail about HIPAA evidence and login credentials

**What**

Claude Code's internal cache of organization policy and rate-limit information was reworked with several additions:

- A new `diskConfirmedAtMs` timestamp, separate from the existing `diskRefusedAtMs`, marking when policy data was confirmed from disk

- Two new fields, `hipaa_seen_incomplete` and `hipaa_ruled_out`, tracking evidence about whether an organization is under HIPAA compliance rules

- New tracking of how a session's credentials were established, including `principalFromOAuthBearer` and a relocated `wifSourceLocation`

- A consolidated `policyGateSnapshot()` and `managedConfigPolicyGateFields()` that bring together fields like `policy_ineligible_reason`, `policy_cache_age_ms`, `policy_would_fail_closed`, and `policy_credential_state`, which were previously computed separately

These feed into the existing `tengu_policy_limits_cache_state_at_first_prompt` telemetry event.

**Why**

This gives Claude Code's internal systems a more complete and consistent picture of an account's policy state, including HIPAA-relevant evidence and how credentials were obtained, which supports more reliable enforcement of organization policies and rate limits.

- Area: Policy Limits
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Sandbox-aware write-permission check via CLAUDE_CODE_SANDBOXED

Write-permission checks now branch based on whether Claude Code is running sandboxed

**What**

Claude Code now uses a different check to decide whether a file can be written to depending on whether the `CLAUDE_CODE_SANDBOXED` environment variable is set. Inside a sandbox, one internal check is used; outside of it, a different one applies. A related addition drains any pending write queues before this decision is finalized.

**Why**

This lets Claude Code apply the correct write-permission logic depending on whether it's running inside a sandbox (a restricted environment that limits what a process can access), rather than using one check for both situations.

- Area: Sandbox
- Names: `CLAUDE_CODE_SANDBOXED`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Remote worker attestation policy plumbed into remote-io transport

Remote/hosted-worker sessions now track an attestation policy and can report an 'unattested request' outcome

**What**

The transport used for remote or hosted-worker sessions now tracks a `workerAttestationPolicy`, set through a new `setWorkerAttestationPolicySink` callback. If this policy sink reports a fault, a corresponding fault path is triggered. A new `unattested_request` outcome was also added alongside existing outcomes like `unknown_call` and `duplicate_call` for tool-call and queue results.

**Why**

This lets Claude Code detect and report when a remote worker's requests aren't properly attested (verified as coming from a trusted source), giving more precise diagnostics for that class of problem in remote or hosted sessions.

- Area: Remote Control
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Permission-mode 'auto' resolves to a concrete mode at request time

'Auto' permission mode now resolves to a concrete mode when a tool request is made

**What**

When Claude Code's permission mode is set to `auto`, a new `permissionModeAtRequest` field now resolves it to a concrete mode at the moment a tool use is requested: `default`, `acceptEdits`, `dontAsk`, or `bubble`. The `plan` and `bypassPermissions` modes both resolve to `default` for this purpose. This replaces an earlier, simpler mode field.

**Why**

This makes permission checks more precise when the mode is set to automatically adapt, since the actual permission behavior applied to a tool call is now pinned down explicitly rather than left ambiguous.

- Area: Permissions
- Names: `permissionModeAtRequest`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Plugin-originated slash actions now include prompt.fill and prompt.suggest, not just command.run

Plugin-triggered slash actions now also cover prompt.fill and prompt.suggest, not just command.run

**What**

The function that stamps default plugin origin information onto actions triggered by slash commands used to only handle `command.run` actions. It now also covers `prompt.fill` (which defaults to `mode: 'replace'`) and `prompt.suggest`, both of which now get a default plugin `origin` stamped on them as well.

**Why**

This extends plugin-origin tracking to more kinds of actions a [plugin](/docs/en/plugins) can trigger from a slash command, not just running a command, so those actions are correctly attributed to the plugin that triggered them.

- Area: Plugins
- Names: `prompt.fill`, `prompt.suggest`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New git/session repo-identity tracking state added to session lifecycle

Sessions now track much more detail about the git repo they launched in

**Unclear.** What user-facing behavior this new tracking state enables is not stated in the finding.

**What**

The internal object that tracks a session's git status has grown a large set of new fields recording repository identity at launch time, including pendingCommits, sessionRepoRoot, sessionCanonicalRoot, launchGitDir, launchCommonDir, launchModuleDirs, launchInodeIdentity, launchPinHandles, launchHeldDirs, vouchedRepos, launchStateTaken, launchRepoRoot, nonGitLaunch, commitGateLatched, launchHookRepo, pendingVouches, attachedDirs, and registration.

**Why**

The finding doesn't say what feature consumes these fields, but tracking this much detail about the launch-time repo location suggests Claude Code is building toward more careful checks around which git repository a session belongs to.

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

### System-prompt tool_removal blocks added alongside tool_addition

System prompt can now list tools that were removed, not just added

**What**

The internal function that builds the system prompt's tool-context section can now describe tool removals as well as additions. It emits `tool_removal` entries (referencing the tool by name) ahead of any `tool_addition` entries, and callers now pass a list of removed tools alongside the list of added ones.

**Why**

This lets Claude's system prompt explicitly note when a tool has been taken away during a session, not just when one is added, which should help Claude stay accurate about which tools are currently available.

- Area: System Prompt
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New OAuth-scope tracking for 'projects' and captured revocation endpoint/email

Claude Code now tracks OAuth scopes for 'projects' and stores a revocation endpoint and email from login

**What**

Claude Code's OAuth client setup (the part that manages login and permissions with your identity provider) now tracks a `PROJECTS_SCOPES_REGISTERED` flag, alongside the existing `PLUGINS_SCOPE_REGISTERED` flag, to record whether the 'projects' scope has been requested. Token storage also now saves a `revocationEndpoint` and an `email` address whenever the identity provider returns them.

**Why**

This lets Claude Code keep track of a new permission scope for projects and hold onto extra account details returned during login, which can support account identification and cleanly revoking access later.

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

### New wake-event 'media' field for hook/queue delivery

Wake events delivered via hooks or queues can now carry an attached 'media' array of images and documents

**What**

Wake events (events delivered to hooks or queues) can now include a `media` field: an array of images and documents attached to those events, listed one-to-one with the events they belong to. This field is only included in the event schema and telemetry when at least one of the events actually has media attached.

**Why**

This lets wake-event consumers, such as hooks, receive images or documents that were part of the triggering events, rather than losing that attached media.

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

### System-prompt "folded attachment" shape now tracked for cache-break diagnosis

Cache-break diagnostics now track the system prompt's folded attachment shape too

**What**

Claude Code already tracks the shape of messages sent to the model to help diagnose when the prompt cache breaks (a cache break means the model has to reprocess parts of the prompt it would otherwise reuse, which costs time and money). A new function now also computes a fingerprint of the system prompt's "folded attachment" spans, recording the type, length, and hash of each part. When a cache break happens, a diff of this shape (parts added, removed, reordered, or changed, plus length differences) is now included in the `tengu_prompt_cache_break` telemetry event.

**Why**

This gives Claude Code more detailed internal diagnostics for figuring out what specifically changed in the system prompt when a cache break occurs, building on the message-shape tracking already used for the same purpose.

- Area: Elsewhere
- Names: `tengu_prompt_cache_break`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New Image component/source validation added (PNG or raw RGBA)

New validation added for rendering images from PNG or raw RGBA data

**Unclear.** The finding does not say where or how the Image component is actually used or displayed to users.

**What**

A new validation module checks image data before it can be rendered as an `Image` component. It supports two source formats: a base64-encoded PNG, or raw RGBA pixel data (`rgba`) with a given `width` and `height`. The validator checks the base64 encoding is correctly padded, verifies the PNG signature and header where applicable, confirms the RGBA byte count matches width × height × 4, and checks that the overall shape (`source`, `columns`, `rows`, `alt`) is correct, producing specific error messages for each kind of problem.

**Why**

This lays groundwork for displaying images in Claude Code's interface, with validation that catches malformed image data early and reports specifically what's wrong with it.

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

### Plugin update flow gains a dedicated npm marketplace lane with integrity checks

Updating npm-installed plugins now goes through a dedicated npm marketplace path with integrity checks

**What**

When Claude Code updates a plugin that was installed from an npm marketplace, it now uses a dedicated code path built for that source. The update resolves the latest npm version, re-caches the package, and records `npmVersionSpec`, `npmResolved`, `npmIntegrity`, and `npmRegistry` on the plugin's install record. The underlying caching step now also accepts a scratch directory, a flag marking the npm marketplace lane, and an expected integrity value for these npm-sourced packages, and plugin loading reads back the recorded npm integrity value.

**Why**

This makes plugin updates from npm marketplaces more reliable by verifying package integrity and tracking exactly which npm version and registry a plugin came from, rather than treating npm-sourced plugins the same as other install sources.

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

### Session view gains disableQuery and filterCommands wiring

Session view internals gain new disableQuery and filterCommands wiring

**Unclear.** What disableQuery and filterCommands actually do or enable for a user isn't stated in the evidence.

**What**

The main session component now accepts two new inputs, `disableQuery` and `filterCommands`, and passes them through to the underlying session engine and command-registry service. `disableQuery` is also passed further down into the turn-controller setup.

**Why**

This is internal plumbing that threads new controls through the session machinery; the finding doesn't specify what user-facing behavior it enables.

- Area: Elsewhere
- Names: `disableQuery`, `filterCommands`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Hook execution now tracks a per-call 'reading budget' and records timing for hooks that never call next()

Hook execution now tracks a reading budget and logs timing when a hook never calls next()

**Unclear.** What the 'reading budget' controls or limits is not stated in the finding.

**What**

Hooks (custom scripts that can run at points in Claude Code's workflow) are invoked with a new `budget` accessor available to their execution context, both in normal runs and in `.catch` error handlers. Separately, Claude Code now detects when a hook produced no downstream calls at all (and wasn't an error handler or a 'hop' handler) and records timing information for that case.

**Why**

This is internal bookkeeping that gives Claude Code more visibility into hook behavior, particularly hooks that run but never pass control onward, without changing what a hook author needs to do.

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

### Remote-io session-channel frame verdicts refactored from booleans to a three-way outcome, with an added attestation-policy judging step

Remote session-channel frame checks move from pass/fail to a three-way verdict, adding an attestation-policy check

**What**

The function that decides whether to drop an unverified frame (a unit of data) on a remote session channel was renamed and now returns one of three outcomes—`passed`, `dropped`, or a new `refusal_rebuilt` (for a case involving stripping forwarded plugins and admitting a refusal)—instead of a simple true/false. A new companion step, `judgeInboundFrame`, classifies incoming frames against a worker attestation policy (a set of rules for verifying the origin of a frame) and runs as part of the frame-processing loop.

**Why**

The finer-grained outcome and the new attestation-policy check give Claude Code more precise handling of suspect frames on a remote session channel than a plain accept-or-reject decision.

- Area: Remote Control
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Batch asset upload result schema added for artifacts

A new batch upload format lets multiple artifact files be uploaded and reported on at once

**What**

Claude Code adds a new `asset_uploads` result format that covers uploading several files together, alongside the existing single-file `asset_upload` format. Each file in the batch is reported individually as one of:

- uploaded, with its id, url, size, content type, and sha256 checksum

- failed, with a reason and message

- not attempted, with a reason and message, and sometimes a `may_be_stored` flag

**Why**

This lets a multi-file upload report per-file success and failure instead of treating the whole batch as one outcome.

- Area: Artifacts
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Turn/command preview component reworked to support multiple processed commands per turn

The internal component that previews turns/commands was reworked to show multiple processed commands per turn

**Unclear.** The finding doesn't say what user-visible difference this produces, only that the internal rendering logic now supports multiple commands per turn.

**What**

The internal component responsible for rendering a checkpoint or turn preview now works with a full `turn` object and can list all of a turn's processed commands, rather than only ever matching a single command out of a flat list of messages. Related spacing logic between preview rows was also adjusted.

**Why**

This is an internal rendering change; it doesn't introduce a new command or setting, but it lays the groundwork for turn previews to correctly display cases where a single turn produced more than one processed command.

- Area: UI
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Plugin-recommendation confirmation dialog generalized into a reusable component

The plugin-recommendation confirmation dialog was rebuilt as a reusable shared component

**What**

The confirmation dialog that used to be specific to plugin recommendations was rewritten to use a new shared component that takes generic `title`, `intro`, `question`, `options`, and `unansweredResponse` inputs, plus an optional `extraIdentityRow` slot for extra identity information.

**Why**

This is an internal restructuring that makes it easier to reuse the same confirmation-dialog layout for other prompts (such as the new marketplace-add confirmation), rather than a change to what the plugin-recommendation dialog itself shows.

- Area: UI
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### context_claude_md_load pipeline restructured around instructionFiles caching

Loading CLAUDE.md project context now reuses cached text when instruction files haven't changed

**What**

The internal process that loads project context (including `CLAUDE.md` instructions) was restructured to compute the list of instruction files through a callback and compare it against the previous version. When the instruction files are unchanged, Claude Code now reuses the previously loaded `claudeMd` text instead of recomputing it from scratch.

**Why**

This avoids redundant work when nothing about a project's instruction files has changed, making context assembly more efficient without changing what ends up being sent to the model.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Artifact publish/boot errors now carry richer diagnostic context

Artifact publish/boot failures now report richer diagnostic details and a 'transient' flag

**What**

When an artifact fails to boot or publish, the diagnostic information sent now includes the original request, the HTTP status code, and context flags about whether the request involved live syncing, an agent peer, or a relay-only connection. Certain error results can now also carry a new `transient` flag.

**Why**

This gives more detail about why an artifact failed to boot or publish, which should make it easier to tell apart a temporary (transient) failure from a persistent one.

- Area: Artifacts
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Server error classification: new OAuth/credential denial reason codes

Server auth errors are now classified into specific denial reasons like token_revoked or org_access_revoked

**What**

A new classifier reads a server error message and sorts it into one of several specific reasons: `org_access_revoked`, `workspace_revoked`, `token_revoked`, `token_expired`, `token_invalid`, `application_deactivated`, `credential_invalid`, or `other`. This populates a new `serverAuthDenial` telemetry field whenever a server authentication or permission error occurs without an explicit error code already attached.

**Why**

This gives more specific information about why a server rejected a request for authentication or permission reasons, instead of lumping all such failures together.

- Area: Auth
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Session-fork sanitization clears bridge and artifact-monitor state

Forking or resuming a session now clears bridge and artifact-monitor state

**What**

When session state is carried forward into a fork or resume, a new helper now strips it of certain state so it doesn't leak into the new session. It clears artifactCommentMonitor and artifactAutoReactLedger unconditionally, along with a full set of bridge-related fields: bridgeSessionId, bridgeLastSeq, bridgeDialogKinds, bridgeSessionGroupingId, bridgeNoHistoryBackfill, bridgeOwnerAccountUuid, and bridgeOwnerOrganizationUuid. It can also optionally strip worktreeSession and relocatedCwd.

**Why**

This prevents a forked or resumed session from inheriting artifact-monitoring or bridge-connection identifiers that belonged to the original session, avoiding cross-session state confusion.

- Area: Sessions
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Cache-read telemetry gains cache-TTL and timing context fields

Cache-read telemetry now logs cache TTL and message-timing details

**What**

The diagnostic event that logs cache-read token counts now also records `is1hCacheTTL` (whether the 1-hour cache time-to-live applies), `lastAssistantMsgOver5minAgo`, `lastAssistantMsgOver1hAgo`, and `querySource`, in addition to the existing baseline and token count fields.

**Why**

This gives more context for diagnosing prompt-cache behavior, such as whether a cache miss happened because too much time passed since the last assistant message.

- Area: Telemetry
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Java trust-store type is now configurable, not hardcoded PKCS12

Java trust-store type is now a configurable setting instead of always being assumed PKCS12

**What**

Sandboxed Java processes route through a proxy using settings injected via `JAVA_TOOL_OPTIONS`. Previously this always assumed the trust store (where Java keeps trusted certificates) was in PKCS12 format. Now, building this configuration requires both `javaTrustStorePath` and a new `javaTrustStoreType` setting, so the format no longer needs to be PKCS12.

**Why**

This lets Java processes running in the sandbox use trust stores in formats other than PKCS12, so the proxy routing works correctly regardless of which trust-store format is actually in use.

- Area: Sandbox
- Names: `javaTrustStoreType`
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Deferred-loading behaviour for MCP tools tightened

Tools from MCP servers are now deferred from loading by default, with one new exception condition

**Unclear.** The new condition that skips deferral (`Xzt()`) isn't identified, so it's unclear what circumstance it represents.

**What**

Tools that come from MCP servers (Model Context Protocol, a way to connect external tools to Claude Code) are now deferred (not loaded immediately) unconditionally, whereas before this was gated behind a feature check. The only exception is when a new internal condition is true, in which case deferral is skipped entirely.

**Why**

This tightens when MCP tools get loaded up front, likely to reduce unnecessary upfront loading, though the specific new exception condition isn't named in a way that says what it represents.

- Area: MCP
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Image treated as a new block-level content type

Image added as a new block-rendered content type alongside Markdown, Client, and Raster

**Unclear.** What user-visible feature this enables isn't stated in the finding.

**What**

Wherever Claude Code enumerates content types that render as blocks (rendering-mode maps, valid-type checks, and the desktop capability list), "Image" was added as a new entry alongside the existing Markdown, Client, and Raster types.

**Why**

This suggests images can now be handled as a distinct block-level content type in rendering, though the finding doesn't specify what new capability this enables for users.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### 'Context collapse' session state replaced by 'memory mode stamps'

Session "context collapse" tracking is replaced by a new "memory mode stamps" array

**Unclear.** The finding does not explain what "context collapse" or "memory mode" represent functionally, or why the change was made.

**What**

The fields `contextCollapseCommits` and `contextCollapseSnapshot`, previously used across transcript loading, session restore, and log merging, have been removed entirely. In their place, a new `memoryModeStamps` array is threaded through the same code paths: it's loaded, filtered by session, restored into `currentSessionMemoryModeStamps`, and persisted along with a "written" flag.

**Why**

This replaces the earlier context-collapse tracking mechanism with a differently structured record of memory-mode state, affecting how session history is loaded, resumed, and merged.

- Area: Session State
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### New REPL poll-event idle delivery guard class

Claude Code now detects and recovers queued REPL events that a turn failed to deliver

**What**

Claude Code now tracks whether queued interactive-session (REPL) events were actually delivered during the turn that was supposed to handle them. If a turn finishes without delivering those queued events, an error is logged internally and an empty placeholder prompt command is re-queued so the events get flushed on the next turn instead of being silently dropped.

**Why**

This prevents queued input from getting stuck and never reaching a turn, ensuring it's eventually processed on a following prompt.

- Area: REPL
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### New structured deny-reason classification for tool/session failures

Tool and session failures now get structured reason codes instead of plain error messages

**What**

Claude Code now sorts internal failures into structured categories instead of just producing a generic message. This affects several kinds of failures:

- transcript-related failures, e.g. `classifier_transcript_too_long`

- permission denials, e.g. `outside_reads_blocked` (with the blocked path and whether it's managed)

- session limits, e.g. `memory_paused`

- connection and authentication failures, e.g. `sandbox_violation`, `mcp_disabled`, `mcp_needs_auth`, and `auth_expired` (distinguishing the `claude_design` and `claude_ai` providers)

**Why**

Giving each failure a specific, structured kind rather than a loose message makes it possible to handle and display different failure situations more precisely, such as showing a clearer explanation when a read is blocked or when an MCP (external tool) connection needs authentication.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Memory sync adds an 'off' backoff-with-jitter retry state

Memory sync adds a backoff-with-jitter retry mode for when memory storage is unusable

**What**

The background process that keeps memory in sync now detects when a memory store's underlying basis is unusable. When that happens, it increments a retry counter and computes a randomized backoff delay (jitter), and pushes the sync with the reason `off_retry` instead of the usual `periodic` reason. The interval between resyncs is now computed by a dedicated helper.

**Why**

This prevents the memory sync process from retrying too aggressively or too predictably when its storage basis isn't usable, spacing out retries instead of hammering it on a fixed schedule.

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

### Deep-link prompt prefill now tracks whether the user actually submitted it unedited

Claude Code now tracks whether a prompt opened via deep link was submitted unedited

**What**

When a prompt arrives through a deep link (a URL that opens Claude Code with prefilled text), the app now records that text in a new field, `linkSuppliedTexts`, and adds a `submittedLinkPrefill` flag that is set when the user submits that exact text without changing it.

**Why**

This lets Claude Code (and whoever analyzes this data) distinguish deep-link prompts that were sent as-is from ones the user edited before submitting, which is useful for understanding how deep-linked prompts actually get used.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Query-string redaction helper for logged URLs

URLs shown in logs now have most query-string values redacted

**What**

A new helper redacts the query string of any URL before it's logged or displayed: it keeps the path, but replaces the value of each query parameter with `***`, unless the parameter's name is on an allowed list (`ref`, `branch`, `tag`, `path`, `file`, `file_path`, `version`, `format`) and its value looks like a safe, path-like string.

**Why**

This reduces the chance that sensitive data passed in a URL's query string (like tokens or identifiers) ends up exposed in logs, while still keeping harmless, useful values like a git ref or file path visible for debugging.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Agent-proxy tool trust: reuse the system JDK truststore when it already trusts the proxy CA

Agent-proxy tool reuses the system Java truststore when it already trusts the proxy's certificate

**What**

Claude Code's agent-proxy tool intercepts network traffic using its own certificate authority (CA), a trusted signer that lets it inspect encrypted connections. For Java-based tools, it needs that CA listed in a Java truststore (a file of trusted certificates). Previously it always built a new merged truststore for this. Now it first checks whether the machine's own Java installation already trusts the proxy's CA, and if so, uses that truststore directly instead of building a new one. It only falls back to building or seeding a new truststore when the system one doesn't already trust the CA.

**Why**

This avoids unnecessary work and file churn when the system Java installation is already set up to trust Claude Code's proxy.

- Area: Sandbox
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Poll event 'kind' now format-validated and per-kind size-capped, wording of reserved-kind error changed

Poll events now validate their 'kind' field format, cap size per kind, and can carry media

**What**

Internal poll events (used for delivering updates) now have stricter validation on their `kind` field:

- `kind` must match a pattern of a lowercase letter followed by lowercase letters, digits, or hyphens, up to 64 characters, and events that don't match are rejected with a new error message

- the maximum envelope size is now looked up per `kind` instead of using one fixed limit for all events

- the error message shown when a reserved kind is used has changed wording, now referring to a "trusted in-process producer" instead of a "server-authored producer"

- poll events can now optionally carry a `media` field

**Why**

The stricter format check and per-kind size limits make poll event handling more precise and harder to misuse, and the new `media` field lays groundwork for events to carry attachments.

- Area: Poll Events
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Subprocess auth/telemetry helpers now run from the project config directory when one is set

Auth and telemetry helper commands now run from the project config directory when one is configured

**Unclear.** placeholder

**What

- Area: Project Config
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New telemetry when auto-mode's decision matches the mode already requested

New telemetry logs when auto-mode's permission decision matches what was already requested

**What

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Effort-level helper reworked to pull model from a new source function

Internal helper for attaching effort_level to telemetry now pulls the model from a different internal source

**Unclear.** the finding is a low-level rename of an internal helper's data source with no stated effect on behavior; unclear what this changes for a reader beyond that the internal wiring differs

**What

- Area: Models
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Rate-limit options dialog rewritten from React-compiler memoized form to a plain component

Rate-limit options dialog's code was rewritten from compiler-generated memoization to plain hooks

**What**

The component behind the rate-limit options dialog was rewritten from an auto-generated, memoization-heavy form (produced by a React compiler) into ordinary hooks-based code. This accompanies the new limit-wall-promo option added to the same dialog.

**Why**

This is an internal code change with no described effect on behavior; it doesn't change what the dialog looks like or does.

- Area: UI
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Plugin loading splits out npm-sourced plugins from marketplace catalog flow

Plugins installed from npm are now resolved through a separate code path from marketplace plugins

**What**

When Claude Code figures out which plugins are enabled, plugins whose source is the special "npm" pseudo-marketplace are no longer processed through the normal marketplace-catalog lookup. Instead they are resolved through a dedicated path built specifically for npm-sourced plugins.

**Why**

This separates the handling of plugins installed via npm from plugins installed via a marketplace catalog, which should make npm-based plugin installs more reliable since they no longer have to go through machinery meant for marketplace catalogs.

- Area: Plugins
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Stream-json input class's internal limit constant raised 50 → 512

A limit used in stream-json/headless input handling was raised from 50 to 512

**Unclear.** What exactly this constant limits (e.g. queue size, buffered messages, line count) is not established by the evidence.

**What**

An internal constant used somewhere in the handling of stream-json input (used in headless, non-interactive modes) was raised from 50 to 512, a tenfold increase.

**Why**

The finding does not say what this limit governs, so it isn't possible to say concretely what changes for users, but a limit raised by 10x suggests headless stream-json input can now handle substantially more of whatever this constant was capping.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Fallback model config now seeded to remote sessions

Fallback model setting is now passed to remote sessions when running under CLAUDE_CODE_REMOTE

**What**

When Claude Code is running under the `CLAUDE_CODE_REMOTE` environment variable, the resolved fallback-model setting (the backup model used when the primary model is unavailable) is now passed into the remote-control path as well.

**Why**

This keeps a remotely-run session's fallback model configuration in sync with the rest of its setup, rather than leaving it unset in that path.

- Area: Sessions
- Names: `CLAUDE_CODE_REMOTE`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Tool pool cache now also keys on WaitForMcpServers declaration and a REPL primitive grant

Internal tool-pool cache now also depends on WaitForMcpServers usage and a REPL primitive grant

**What**

Claude Code's internal cache of which tools are available (the "tool pool") now also takes into account two more factors when deciding whether to reuse a cached result: whether the host has declared it uses the `WaitForMcpServers` tool, and a "REPL primitive grant" derived from the main agent. Previously the cache only tracked the set of tools and allowed subagent types.

**Why**

This is an internal correctness fix: without tracking these inputs, the tool pool could theoretically serve a stale cached result when either of these factors changed. It shouldn't be noticeable to users beyond more accurate tool availability.

- Area: Tools
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New byte cap on Image elements in agent UI trees

Agent UI trees now reject Image elements once their combined source size exceeds a byte cap

**What**

The internal validator that checks the structure of agent-generated UI component trees (covering elements like Box, Client, and Markdown) now also adds up the byte size of any `Image` element's source data across the tree, and rejects the tree if that total exceeds a threshold.

**Why**

This prevents a UI tree from embedding excessively large image data, which could otherwise bloat or break rendering.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### CLI startup: conditional auto-launch of a background helper

Claude Code startup can now auto-launch a background helper process under certain conditions

**Unclear.** The finding does not say what the launched background helper (`lp()`) actually does.

**What**

On startup, if the session wasn't opened via a deep link, no MDM (mobile device management) policy-helper configuration is present, and the `worktree` flag wasn't used, Claude Code now fires off a call to launch a background helper process, catching and ignoring any failure.

**Why**

This adds an automatic background process launch during ordinary startup in the conditions described, though the finding doesn't specify what the helper does.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Query run loop gains a disableQuery short-circuit

The main query loop can now skip running a turn entirely via a new disableQuery check

**Unclear.** The finding does not say what sets `disableQuery` or why a turn would need to be skipped.

**What**

The core function that runs each turn of a query now checks a `disableQuery` flag right after session-start hooks run. If it's set, and either a new turn is starting or input is queued, the function returns early and skips running the turn.

**Why**

This adds a way to short-circuit a turn before it runs, though the finding doesn't say what sets `disableQuery` or under what circumstances a turn would be skipped this way.

- Area: Elsewhere
- Names: `disableQuery`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Attachment builder drops a tool-availability gate around pending MCP names

Pending MCP server names are now always included when building tool-availability updates

**Unclear.** The finding does not say what visible difference this makes to the tools Claude sees during a session.

**What**

The code that builds the list of tool changes sent to Claude (the "deferred tools delta") used to only include the names of pending MCP clients (external tool servers still connecting) when a certain tool-availability check was false. That check has been removed, so pending MCP client names are now always included. A related `keepMcp` flag used when stripping tools is also now hard-coded to `true`.

**Why**

This means information about MCP servers that are still connecting is passed through more consistently, though the finding doesn't specify the downstream effect of always including it.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Pasted/attached image dimension lookup now defers to an async image store when available

Pasted image size lookup can now go through an async image store, gated by a flag

**Unclear.** The `tengu_pasted_image_resize_attempt` gate is unread, so it's unclear whether this path is active.

**What**

When Claude Code processes pasted or attached images while building a request, it now checks whether an image store is available and, if so, computes image dimensions in a batch through that store asynchronously instead of the previous method. This path also emits an `input_image_block` telemetry event counting how many images were successfully stored versus not.

**Why**

This is a groundwork change for handling image dimensions more efficiently when pasting or attaching images, though whether it is active depends on a gate that has not been read for this account.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Team memory bulk inflate telemetry now scoped to non-account memory

Team memory bulk-inflate telemetry now only fires for non-account memory, plus a new bail-out

**Unclear.** The `tengu_memory_bulk_inflate` gate is unread, so nothing can be said about whether it is active.

**What**

The team-memory bulk-inflate process (which loads memory data in bulk) now exits early when `rejoinWalkUntrusted` is set and its basis data is unusable. Its failure and incomplete-run telemetry event, `team_memory_multistore_bulk_inflate`, now only fires when the memory scope is not `account`.

**Why**

This narrows telemetry to the cases it's meant to cover and avoids continuing a bulk-inflate operation on data that can't be trusted.

- Flag `tengu_memory_bulk_inflate`: Not enough to say (read for one account on one subscription tier against v2.1.275; 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: Team Memory
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New in-process terminal UI test harness for plugin Clients

New internal test harness simulates a terminal UI for testing plugin Client components

**What**

A new test-support module adds a mountable, scriptable terminal UI harness that can simulate key presses, pointer actions, posting messages, advancing a virtual clock, and unmounting, so plugin "Client" components can be tested without a real terminal.

**Why**

This is a developer-facing testing tool that makes it possible to write automated tests for plugin UI behavior, which should help catch plugin interface bugs before release.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New session-state flag tracks restored memory pause

Session state now tracks a restored memory pause flag in resume telemetry

**What**

Session state now includes a `restoredMemoryPause` field, with matching getter and setter methods, alongside the existing `memoryToggledOff` field. This new field is now included in the telemetry sent when a session is restored or resumed.

**Why**

This lets Claude Code track and report whether a memory pause was carried over when a session is restored, giving more visibility into memory state across session resumes.

- Area: Memory
- Names: `restoredMemoryPause`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Served model catalog gains an always-false early bail-out

A new internal check can now skip fetching the served model catalog entirely

**Unclear.** What `Ug()` actually checks, and thus when the served model catalog fetch is skipped, is not known from the evidence.

**What**

The internal logic that fetches the catalog of models served to the account added a second condition, `Ug()`, that can cause the fetch to be skipped entirely, in addition to the existing check for whether the current context is "primary".

**Why**

The finding doesn't say what `Ug()` checks or when it returns true, so it's unclear what effect this has for a reader in practice.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Turn-end event now carries a `force` flag

The turn_end lifecycle event now carries a force flag

**Unclear.** What the `force` flag causes listeners of `turn_end` to do differently is not stated in the finding.

**What**

The internal `turn_end` event, which fires when a conversational turn finishes, now includes a `force: true` flag when it's emitted, where previously it was sent with no extra options.

**Why**

The finding doesn't say what consuming this flag changes, so its practical effect isn't clear from the evidence.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New telemetry event for dropped thinking blocks

New telemetry event tengu_thinking_drop logs when thinking blocks get stripped from a request

**What**

Claude Code now sends a telemetry event called `tengu_thinking_drop` whenever "thinking" blocks (the model's intermediate reasoning content) are removed from a request before it's sent, for example when there's a mismatch between the prefix of prior turns and the model currently bound to the session. The event records how many blocks and turns were affected, why they were dropped, which message positions were involved, and details of the client-side change that triggered the request.

**Why**

This gives visibility into a case where reasoning content silently gets stripped out, which should help diagnose situations where thinking output unexpectedly disappears from a conversation.

- Area: Telemetry
- Names: `tengu_thinking_drop`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New SessionState fields: repl poll delivery, project config root

Session state gains new internal fields for REPL poll delivery tracking and a project config root

**Unclear.** What 'repl poll delivery' and 'project config root' are used for is not stated.

**What**

Claude Code's per-session state now tracks two new pieces of internal data: a flag called "repl poll delivery requested" that can only be set to true, and a getter/setter pair for a "project config root" value.

**Why**

The finding doesn't say what these fields are used for, so their practical effect isn't clear from this change alone.

- Area: Session State
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Forked sessions now carry memory-mode stamps

Forking a conversation now carries over 'memory mode stamps' into the new session

**Unclear.** What 'memory mode stamps' represent and why carrying them into a fork matters is not stated.

**What**

When you fork a conversation into a new session, Claude Code now also copies over its "memory mode stamps" into the forked session's metadata, in addition to the existing latch state it already carried over.

**Why**

The finding doesn't explain what memory mode stamps represent, so it's unclear what carrying them over changes for the user beyond keeping forked sessions more consistent with their source.

- Area: Sessions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### claude-test explorer subagent now explicitly disallowed from a browser-allow MCP tool

The built-in claude-test plugin's explorer subagent is now explicitly blocked from a browser-allow MCP tool

**What**

The `explorer` subagent bundled with the built-in `claude-test` plugin now explicitly lists `mcp__plugin_claude-test_browser__claude_test_allow` as a disallowed tool, on top of its existing restriction to only Read, Grep, and Glob. Separately, the plugin's `author` subagent now has an explicit `name: author` field in its definition.

**Why**

This closes off a specific browser-permission tool from the explorer subagent, keeping it restricted to read-only inspection tools as intended.

- Area: Plugins
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Tool-result UI registry refactored to lazily load MCP tool display code

Tool-result display code for MCP tools now loads lazily instead of being bundled upfront

**What**

The internal machinery that renders tool results in the terminal UI (deciding how each tool's output looks, and whether it's been truncated) has been restructured. Several tool-specific display modules for MCP (Model Context Protocol, the standard Claude Code uses to talk to external tool servers) tools were consolidated into a single module that's only loaded when actually needed, rather than always being loaded up front. Built-in tools now more consistently specify whether their results can be truncated.

**Why**

This is an internal cleanup that should make startup lighter by avoiding loading display code for tools that aren't in use, without changing what users see when tool results are rendered.

- Area: UI
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Stream-event upload buffer gains a 'parked rows' path tied to a served_policy hold rule

The terminal display now pauses rendering new frames when output is backed up

**What**

Claude Code's terminal interface (built on a renderer called Ink) now checks how much output is still queued to be written to the terminal. If that backlog is too large, it holds off scheduling the next frame update and retries after a short delay, rather than always updating on a fixed timer regardless of whether the terminal has caught up.

**Why**

This prevents the display from getting further and further behind when the terminal can't keep up with output, keeping the interface more responsive instead of piling up unrendered frames.

- Area: Terminal Rendering
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Skills 'run' library gained a new allow-tool script

The bundled browser-automation skill added a new internal script file for allowing tools

**Unclear.** The finding shows only that the file was added, not what logic it contains or how it changes the skill's behavior.

**What**

The built-in "run" skill, which handles browser automation, added a new file called `allow-tool.mjs` to its internal library folder, alongside the existing files that handle configuration, discovery, guarding, hosts, and tools.

**Why**

This is an internal addition to how the skill manages which tools are allowed to run; the finding doesn't specify what behavior it changes for users.

- Area: Skills
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact asset upload retries are now flagged as `resent`

Retried artifact file uploads are now explicitly marked as resent in the results

**What**

When Claude Code retries uploading a file (an asset) attached to an artifact, both the success and error outcomes of that retry now carry a `resent` marker. This marker is also recorded consistently in the background usage tracking (telemetry) even when the upload fails early.

**Why**

This makes it possible to tell, from the result of an upload, whether it happened on a first try or a retry, which helps in diagnosing upload issues and understanding retry behavior.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Poll tool events can now carry structured child tags, not just text content

Internal poll events can now include structured tagged sub-elements instead of only plain text

**What

- Area: Poll Events
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New holdsEvalSettles() stub added to drain/session-loop class

Internal session-loop class gets a new always-false placeholder check plus a simplified wait condition

**Unclear.** The finding does not say what holdsEvalSettles() is meant to represent or when it might return true.

**What**

A new internal method called `holdsEvalSettles()` was added to the class that manages the drain/session loop, but it currently always returns false. At the same time, the loop's condition for whether to keep waiting was rewritten, combining several separately-named true/false flags into one inline check.

**Why**

This is internal bookkeeping in Claude Code's session-management code with no described effect on behavior yet; the new method appears to be a placeholder for something not yet wired up.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Telemetry gains desktopAppVersion field

Telemetry requests now include a desktopAppVersion field when running in the desktop app

**What**

The shared metadata that Claude Code attaches to its background usage tracking (telemetry) requests now includes a `desktopAppVersion` field, alongside the existing `agentSdkVersion` field. It's only included when it has a value.

**Why**

This lets Claude Code's telemetry distinguish which version of the desktop app a request came from, which is useful for diagnosing issues that are specific to a particular desktop app release.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Env-var snapshot tracker gains explicit snapshotSettled state

Sandbox environment-variable snapshot tracking now separates 'settled' from 'available'

**Unclear.** The finding does not say what practical behavior depends on distinguishing these two states.

**What**

The internal component that tracks whether a snapshot of a sandbox or session's environment variables is ready now keeps track of two separate states: `snapshotSettled`, which becomes true once the snapshot process has finished running, and `snapshotAvailable`, which is a separate existing state. Resetting the tracker now clears both.

**Why**

This distinguishes "the snapshot process has finished" from "the snapshot succeeded and is usable," which is internal plumbing that helps Claude Code reason more precisely about the state of environment-variable snapshots.

- Area: Sandbox
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New telemetry event tengu_tether_unrecognised_400

Claude Code added a new telemetry event, tengu_tether_unrecognised_400, for the thread-continuation system

**What**

A new telemetry event name, `tengu_tether_unrecognised_400`, has been added to the list of recognized events, alongside the existing `tengu_tether_decision`, `tengu_tether_live_outcome` and `tengu_tether_echo_audit` events. These all relate to "tether," the internal planner that decides whether to continue an existing conversation thread rather than start a new one.

**Why**

This lets Claude Code record and analyze a specific new situation involving an unrecognized HTTP 400 error response during thread continuation, which was not previously captured as its own telemetry event.

- Area: Telemetry
- Names: `tengu_tether_unrecognised_400`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Auto-mode classifier telemetry now records root tool surface

Auto-mode decision logging now records which tools were available at the root level

**What**

When Claude Code runs in auto mode (making tool-permission decisions on its own without asking), the internal record it keeps of each decision now also includes the root tool surface: which tools were available at the top level when the decision was made. This applies both to direct tool calls and to cases where a sub-agent hands work back to the main session. The underlying functions that build these decisions were changed to explicitly pass this information through, rather than relying only on the existing permission context.

**Why**

This is a telemetry change: it gives Claude Code's internal logs more context about the conditions under which an auto-mode decision was made, which can help with diagnosing or reviewing how those decisions are reached.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Team-memory multistore-conflict telemetry no longer fires for account-scope stores

Team-memory conflict warnings no longer fire for account-scoped memory stores

**What**

Claude Code's team-memory feature logs a `team_memory_multistore_conflict` event when it detects certain conflicts, such as a manifest changing mid-pull, a manifest appearing foreign at write time, an unlisted non-empty directory, or a foreign partition directory. These checks now skip firing when the memory store in question is scoped to the account rather than to a team.

**Why**

This avoids raising multistore-conflict warnings for memory stores that are personal to an account, where that kind of conflict isn't meaningful, reserving the warning for cases where it actually indicates a problem.

- Area: Team Memory
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Model catalog telemetry gains an auth_kind field distinguishing how the session is authenticated

Model catalog telemetry now records how the session authenticated, as one of ten categories

**What**

Telemetry events related to the model catalog (such as `model_catalog_published`) now include a new `auth_kind` field describing how the current session is authenticated. It reports one of: `third_party`, `host_token`, `claudeai_login`, `auth_token_env`, `api_key_env`, `api_key_login`, `api_key_helper`, `profile_user_oauth`, `profile_federation`, or `none`.

**Why**

This gives Claude Code's internal telemetry a clearer picture of which authentication method was in use when the model catalog was published or accessed, which supports diagnosing catalog-access issues that vary by authentication method.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### HIPAA-relevant evidence tracking added to session state

Session state now tracks HIPAA-related evidence, distinguishing IO failures from unusable content

**What**

Claude Code's session state now tracks three new fields related to HIPAA compliance evidence: `hipaa_seen`, `hipaa_seen_incomplete`, and `hipaa_ruled_out`. These are populated from a "stamp" object and merged into the stored evidence for a session. The tracking distinguishes between cases where evidence is unusable because of an IO failure (errors like EMFILE, ENFILE, EAGAIN, EBUSY, or EINTR, marked "unusable, cause io") versus cases where it's unusable because of its content.

**Why**

This gives Claude Code a more precise record of whether it has found, is missing, or has ruled out evidence relevant to HIPAA compliance for a session, and separates technical read failures from genuinely inconclusive content, which affects how that evidence should be interpreted.

- Area: Compliance
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Session resume gains a disableQuery flag that skips auto-resuming orphaned agents and stale-resume prompts

A new disableQuery flag can skip auto-resuming orphaned agents and stale-resume prompts

**What**

Claude Code's session resume logic now checks a `disableQuery` setting before two things: automatically resuming orphaned agents or workflows, and prompting the user about resuming a stale session. When `disableQuery` is set, both of these are skipped.

**Why**

This gives Claude Code a way to suppress automatic resume behavior and stale-resume prompts entirely, for situations where that automatic handling isn't wanted.

- Area: Sessions
- Names: `disableQuery`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Terminal renderer tracks stale inline images separately

Terminal display now marks inline images as stale after a screen reset so they redraw properly

**What**

The part of Claude Code that draws to the terminal now sets an `imagesStale` flag whenever the screen is reset, such as toggling the alternate screen buffer, a forced full redraw, or a focus reset.

**Why**

Terminal screen resets can otherwise leave inline images (pictures shown directly in the terminal) looking stale or broken, since the terminal repaints text but not necessarily the image data. Tracking staleness separately means Claude Code can now redraw those images properly after such a reset.

- Area: Terminal Rendering
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New promo/startup-announcement state tracking tied to login count

New state tracks login counts to control when a startup promotional announcement ends

**Unclear.** What the promotional announcement is about, and the exact login threshold, aren't given in the evidence.

**What**

Claude Code now tracks additional state around a startup promotional announcement: its configuration, how many logins have occurred while it's been shown, whether it's ended for the user, and whether its display slot has been released.

**Why**

This lets Claude Code stop showing a startup promotional announcement once the user has logged in a certain number of times, rather than showing it indefinitely.

- Area: Promotions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Tool-result denial now can carry a remedy alongside non_execution_kind

Denied tool calls can now include a suggested remedy in transcript summaries

**Unclear.** The finding does not say what a remedy value looks like or where it is shown to the user.

**What**

When a tool call is denied or blocked, the transcript summarizer can now include a `remedy` field alongside the existing reason code, sourced from a new `toolResultRemedy` value on the message. This appears when such a value is present.

**Why**

This gives more detail about denied tool calls in transcripts, potentially surfacing a suggested fix or next step rather than just the fact that something was blocked.

- Area: Tool Results
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Memory/precompact payload gains a laptopMemoryDroppedCount

Pre-compaction memory feedback now also reports a laptopMemoryDroppedCount

**What**

The feedback data sent before a conversation is compacted (compaction shortens a long conversation to keep it within context limits) now includes a `laptopMemoryDroppedCount` value, in addition to the existing `thirdPartyDroppedCount`. This is reported when the payload is too large or otherwise trimmed.

**Why**

This lets the system track how much memory content specifically from the "laptop" context gets dropped during compaction, separate from third-party content.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Cowork memory context distinguishes a "laptop" leg

Cowork memory context now tags content built for a "laptop" leg

**Unclear.** The finding does not explain what a "leg" represents or how the `shown` set is used downstream.

**What**

When the cowork memory context (content attached to give Claude background memory) is built specifically for a "laptop" context, it is now tagged with a `leg: "laptop"` field, and the resulting content is added to a `shown` tracking set in that case.

**Why**

This lets the system distinguish memory content that came from a laptop context from other sources, likely for tracking what has already been shown or included.

- Area: Memory
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Autonomous-operation system guidance now also triggered by a new condition function

Autonomous-operation guidance now checked with a second condition that takes message state as input

**Unclear.** The finding does not say what the new condition function actually evaluates or when it newly triggers versus the old one.

**What**

The system message that tells Claude "You are operating autonomously. The user is not watching in real time... asking will block the work" is now shown when either of two conditions is true. The second condition now receives the message/state argument, whereas before it was checked with no arguments at all.

**Why**

By giving the second check access to the current state, the decision of whether to show this autonomous-operation guidance can now depend on details of the ongoing session rather than being a fixed, context-free check.

- Flag `tengu_amber_sextant`: On for this account, and not off by default (read for one account on one subscription tier against v2.1.275; 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: System Prompt
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New closed-set `decision_reason_code` field on permission decisions

New decision_reason_code field distinguishes specific reasons behind a permission decision

**What**

Permission decision data now includes a new `decision_reason_code` field with a fixed set of possible values, in addition to the existing `decision_reason_type`. The new codes include:

- `outside_reads_blocked` — the `permissions.blockReadsOutsideWorkingDirectories` setting refused a file read outside the working directories

- `memory_paused` — triggered by `/pause-memory`

- `classifier_transcript_too_long` — the auto-mode classifier's transcript exceeded the context window

**Why**

This gives more specific, machine-readable reasons for why a particular permission decision was made, useful for understanding why an action was blocked in a given session.

- Area: Permissions
- Names: `decision_reason_code`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Priority queue insertion can now jump to the front of the queue

Command admission queue can now place a command at the front instead of the back

**Unclear.** The finding does not say which commands or situations actually use the new `ahead` option.

**What**

The internal function that admits a command into the processing queue gained a new `ahead` option. When set, the command is placed at the front of the queue instead of being added to the back as before.

**Why**

This allows certain commands to jump ahead of others already waiting, rather than always being processed in strict arrival order.

- Area: Message Queue
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Standing 'leftStanding' process handling in control-response routing

Control-response routing now tracks replies left for processes that are shutting down

**What**

The logic that routes control responses and user-dialog requests gained a "left standing" concept. When a process is marked as left standing, any new user-dialog requests are cancelled immediately instead of being queued. Replies that were left for a process that's shutting down are now counted separately, as `repliesLeftStanding`, distinct from `repliesLeftForNextProcess`.

**Why**

This prevents new dialog requests from being sent to a process that's already shutting down, and separates the bookkeeping for replies stranded by a shutdown from replies meant for the next process, making that distinction traceable.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### HIPAA credential-cache bookkeeping reworked (evidence with confirmed/ruled-out state)

HIPAA credential cache reworked to track confirmed and ruled-out identities separately

**What**

The per-credential HIPAA cache no longer uses a flat list of "seen identities" (hipaaSeenIdentities). It now uses a richer "evidence" structure that separately tracks identities that have been seen versus ones that have been ruled out, an "incomplete" flag, and confirmation/refusal timestamps, with a new `diskConfirmedAtMs` alongside the existing `diskRefusedAtMs`.

**Why**

This more detailed bookkeeping lets Claude Code distinguish between an identity that's confirmed, one that's ruled out, and one that's still unresolved, rather than treating all past sightings the same way.

- Area: Compliance
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New worker attestation telemetry events (ccr_worker_*)

New telemetry events track worker attestation in the CCR relay pipeline

**Unclear.** What CCR stands for and what user-facing feature this pipeline supports is not stated in the finding.

**What**

Four new telemetry event names have been added covering the CCR worker attestation pipeline: attestation policy receipt, control-request attestation, event attestation, and stray-event attestation.

**Why**

These events give visibility into the attestation (identity verification) steps a relay worker goes through, which should help diagnose issues in that pipeline.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Advisor tool availability check refactored to a shared helper

The check for whether the experimental advisor tool is available was refactored into a shared helper function

**Unclear.** It's unclear whether the `tengu_sage_compass2` gate plays any role in this check, since no reading of it has been taken.

**What**

The internal function that decides whether the (experimental) advisor tool is available now delegates to a shared helper instead of inlining its checks directly. This includes the existing `CLAUDE_CODE_DISABLE_ADVISOR_TOOL` environment variable, which disables the [advisor tool](/docs/en/advisor): setting it to `1` turns off the `/advisor` command, ignores any configured `advisorModel`, and makes the `--advisor` flag accepted but inert.

**Why**

This is an internal code cleanup consolidating how advisor-tool availability is determined; it doesn't change the advisor tool's existing behavior.

- Flag `tengu_sage_compass2`: Not enough to say (read for one account on one subscription tier against v2.1.275; 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: Advisor
- Names: `CLAUDE_CODE_DISABLE_ADVISOR_TOOL`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New warning when a transcript drain is still running at shutdown

Claude Code now warns if saving the session transcript is still running when the process shuts down

**What**

A new helper logs a warning if the process is finishing up but the promise responsible for draining (writing out) the session transcript hasn't finished within a timeout. The warning explicitly notes that the result is returned without waiting for the drain to complete.

**Why**

This surfaces a case where the transcript might not be fully saved before the process exits, making it easier to notice and diagnose incomplete transcripts instead of it failing silently.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### REPL-mode entrypoint now classified into terminal/host/evals for telemetry

REPL-mode startup is now classified as terminal, host, or evals for telemetry purposes

**What**

A new function determines whether the current run counts as a 'terminal', 'host', or 'evals' entrypoint for the async REPL (the interactive prompt loop), based on the entrypoint type, whether input is streamed, the `sdkUrl`, and `asyncReplRequested`. This classification feeds a couple of new telemetry emitters.

**Why**

This lets Claude Code distinguish and report which kind of environment is starting an async REPL session, which can help with understanding usage across terminal, host, and evaluation contexts.

- Area: REPL
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Advisor-model API errors get dedicated recognition, including org-entitlement case

Advisor-model API errors are now specifically recognized, including when unavailable for an organization

**What**

New helper functions now recognize specific 400 errors related to the advisor model: messages saying 'the advisor tool is not available', 'cannot be used as an advisor', or a `tools.N.model` validation error. A further check identifies the specific case where the advisor is unavailable for the caller's organization.

**Why**

This lets Claude Code identify and presumably handle or report advisor-related errors more precisely, including distinguishing an organization-level entitlement problem from other advisor errors.

- Area: Advisor
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Kept-reminder/idle probe renamed to threads probe with its own failure counter

The idle/kept-reminder probe is now a 'threads probe' with its own failure counter separate from the existing one

**What**

An internal background probe, previously tied to kept-reminder/idle checks, is now referred to as a threads probe and tracks its own consecutive-failure count via a new `threadsProbeFailures` counter, giving up after 2 failures. This is separate from the existing `clearAtProbeFailures` counter used elsewhere.

**Why**

Separating the failure tracking lets this probe fail and back off independently without affecting the other probe's failure count.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Sandbox status schema bumped to version 3

Sandbox status data format bumped from version 2 to version 3

**Unclear.** What specifically changed in the status payload between version 2 and 3 isn't stated.

**What**

The internal payload describing a sandbox's status (the isolated environment Claude Code can run commands in) now reports `statusVersion: 3` instead of 2.

**Why**

This signals a change in the shape or contents of the sandbox status data; the version bump itself doesn't change visible behavior.

- Area: Sandbox
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New artifact/comment 'outside org' marker on human accounts

Human accounts outside the organization are now marked with an 'outside' flag in serialized account data

**What**

When a human account is flagged internally as being outside the organization, that fact is now included in the serialized account object as `outside: true`. The corresponding data schema gained a matching optional `outside` field alongside the existing `access` field.

**Why**

This lets other parts of the system (such as artifact or comment handling) know when an account belongs to someone outside the org, which was not previously exposed.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Internal tool-use tracking state reworked

Internal per-session tool-tracking state replaced caching fields with tool-lifecycle and nested-agent bookkeeping

**Unclear.** The finding doesn't state what user-facing behavior, if any, this internal rework affects.

**What**

A piece of internal per-session state that used to cache `markdownTokens`, `highlightedCode`, and `structuredDiff` data has been reworked. It now instead tracks `retracted`, `inProgressToolUses`, `evictedToolUses`, and `nestedUuidAliases`.

**Why**

This appears to shift the bookkeeping from rendering-related caches toward tracking the lifecycle of tool calls (in progress, evicted) and aliasing identifiers for nested agents, though the visible effect of this internal change isn't specified.

- Area: Session State
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Workspace ID now captured from account info

Account info parsing now also captures a workspaceId field

**What**

When Claude Code parses account information, it now also extracts a `workspace_id` value into a `workspaceId` field, alongside the existing `organizationUuid` and `workspaceName` fields it already captured.

**Why**

This makes the workspace identifier available internally wherever account info is used, though the finding doesn't say what new feature consumes it yet.

- Area: Auth
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Bash-tool retry helper with exponential backoff added

The Bash tool gained a retry helper that backs off 100ms, 200ms, 400ms, then 800ms on specific errors

**What**

A new internal retry wrapper for the Bash tool retries an operation when it fails with specific error codes, waiting progressively longer between attempts: 100ms, then 200ms, then 400ms, then 800ms. It gives up either when the error isn't on an allowed list of retryable errors or when it runs out of retry attempts.

**Why**

This should make Bash tool operations more resilient to transient, retryable failures instead of failing immediately on the first error.

- Area: Bash Tool
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New credential/auth error reason ip_restricted

Claude Code adds an ip_restricted error reason for credential/auth failures

**What**

Claude Code's mapping from internal error reasons to a public credential-scope error code now includes `ip_restricted`, alongside the existing `not_permitted` and `lane_unavailable` reasons.

**Why**

This lets Claude Code surface a more specific error when a credential is rejected because of an IP restriction, rather than reporting a generic failure.

- Area: Auth
- Names: `ip_restricted`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Auth-kind resolution extended with profile and federation

Auth-kind resolution now treats profile and federation credentials as orgless, and logs auth_kind

**What**

The internal logic that decides which organization-scoping bucket a credential belongs to now treats credentials of kind "profile" and "federation" the same as "token" and "api_key", resolving all of them to "orgless". A new `auth_kind` field is also now recorded in telemetry alongside the existing route and credential fields.

**Why**

This keeps org-scoping consistent for more kinds of credentials, and the added telemetry field gives more visibility into which authentication method was used for a given request.

- Area: Auth
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### unattested_request added to tool-call outcome buckets

Claude Code adds an unattested_request outcome for tracking failed tool calls

**What**

Claude Code tracks the outcome of tool calls (a tool call is when Claude Code invokes one of its tools, like running a command or editing a file) using a set of outcome categories such as `unknown_call`, `no_approval`, `stale`, `queue_full`, `rate_limited`, and `duplicate_call`. A new category, `unattested_request`, has been added to this set.

**Why**

This gives Claude Code a more precise way to record and diagnose a specific kind of failed or rejected tool call, rather than lumping it into an existing catch-all category.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### asset_uploads (plural) added to a permission scope list

A new asset_uploads (plural) permission scope was added alongside the existing asset_upload

**Unclear.** Whether `asset_uploads` replaces, supplements, or differs in meaning from the existing `asset_upload` scope is not shown by the evidence.

**What**

A list of scoped permission actions, which already included things like `db_read`, `db_write`, `asset_upload`, and `asset_list`, gained a new entry `asset_uploads` (plural), distinct from the existing singular `asset_upload`.

**Why**

The finding does not say what distinguishes the new plural scope from the existing singular one in practice.

- Area: Artifacts
- Names: `asset_uploads`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New subscribable signal for host tool-declaration state

Claude Code adds an internal signal tracking whether a connected host has declared its tools

**Unclear.** What functionality depends on this declared/undeclared signal is not shown by the evidence.

**What**

Claude Code now tracks, per connected host, whether that host has 'declared' its tools, using a new reactive flag with helpers to mark a host as declared, mark it as undeclared, and subscribe to changes in that state. This is wired in so that clearing a session marks the host as undeclared again.

**Why**

This is internal plumbing for tracking tool-declaration state per host; the finding does not describe a user-facing effect.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact 'copy' access checks now special-case type-locked artifacts

Copying a type-locked artifact now goes through a dedicated access check instead of the generic one

**Unclear.** The finding doesn't say what the dedicated check does differently from the generic one, or what a type-locked artifact is.

**What**

The function that checks whether a user can access an artifact now takes a `mode` parameter, defaulting to "copy". When that mode is used on an artifact that is locked to a specific type, the check is now routed through a dedicated function instead of the general ownership/read check that other access requests use.

**Why**

This lets copy permission for type-locked artifacts be evaluated with its own dedicated logic, separate from ordinary read access.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Headless/print background-task wind-down tracks an eval-settle hold and exposes ceiling-exceeded state

Headless background-task dispatch now tracks whether it's held for eval-settling and whether the wait ceiling was hit

**What**

In headless (non-interactive, "print") mode, the loop that dispatches background tasks now accepts a `holdsEvalSettles` option; when it returns true, dispatch is held back rather than picking up the next task. A new `bgWaitCeilingExceeded` field also records whether the background-wait time limit, set by `CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS`, was actually reached.

**Why**

This gives the headless dispatch loop a way to pause until pending evaluations have settled, and makes it possible to tell afterward whether a run was cut off by hitting the configured wait ceiling.

- Area: Elsewhere
- Names: `CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### OTEL metrics exporter headers now vary by protocol

OTEL metrics exporter now builds its request headers based on which protocol is in use

**What**

The function that builds headers for the OpenTelemetry (OTEL) metrics exporter now also receives the resolved protocol string as an input, so the headers it produces can vary depending on which protocol is being used to send metrics.

**Why**

This allows the metrics exporter to send protocol-appropriate headers instead of a single fixed set, which matters for anyone configuring OTEL metrics export with different transport protocols.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Handoff payloads gain a memory_context field

Handoff payloads can now include a memory_context field alongside relay_marker

**Unclear.** The finding does not say what `memory_context` contains or how it is used once accepted.

**What**

The function that validates handoff objects (used to pass state between parts of Claude Code) now recognizes a `memory_context` field as a valid top-level field, alongside the existing `relay_marker` field. Both are accepted outside of the main schema-validated fields.

**Why**

This lets handoff payloads carry memory-related context through the same validation path already used for `relay_marker`, without being rejected as unrecognized.

- Area: Elsewhere
- Names: `memory_context`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact comment auto-react/forecast now checks whether the thread is 'headless' in parallel

Artifact comment auto-react and forecast checks now also detect whether the thread is 'headless' in parallel

**Unclear.** The finding does not say what effect knowing the thread is headless has on behavior, only that the check is now performed.

**What**

When Claude Code automatically reacts to an artifact comment or generates a summon forecast, it now runs an extra check alongside the usual permission check. This check looks up the artifact's comment capability and determines whether the thread is 'headless' (running without a visible interface), and it runs at the same time as the permission check rather than after it.

**Why**

Running the two checks in parallel means the headless status is available without adding extra wait time to the auto-react or forecast flow.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Plugin op dispatch (ie) gains a post-processing/scan hook

Plugin operation dispatch now runs every result through a new post-processing/scan step before returning it

**Unclear.** What the new scan/post-processing step actually does to the op result is not stated in the finding.

**What**

The internal dispatcher that routes plugin operations now passes a `scan` argument through, and every operation's result is run through a new post-processing step before it is returned to the caller, instead of being returned as-is.

**Why**

The finding does not say what the post-processing step checks or changes, only that plugin operation results now pass through it before reaching whatever called them.

- Area: Plugin API
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Tool execution can now flag a permission decision as classifier-driven auto-mode

Tool calls now carry a flag noting when permission was auto-approved by the auto-mode classifier

**Unclear.** placeholder

**What

- Area: Permissions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New 'toolResultRemedy' field surfaced on tool-call errors

Failed tool calls now report a 'toolResultRemedy' alongside the existing denial reason

**Unclear.** The finding does not state what a 'remedy' value contains or how it is displayed to the user.

**What**

When a tool call fails and Claude Code builds the resulting error message, it now includes a `toolResultRemedy` field in addition to the existing `toolDenialKind` field. Both come from the same underlying classification of why the tool call was denied.

**Why**

Surfacing a remedy alongside the denial kind suggests the error message can now carry a suggestion for how to address the failure, not just a label for why it happened.

- Area: Tool Results
- Names: `toolResultRemedy`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New content-stream case 'thinking_drop' renders to nothing

New message content type `thinking_drop` renders as nothing in the chat display

**Unclear.** The finding doesn't say what distinguishes a 'dropped' thinking block from a 'stripped' one.

**What**

The part of Claude Code that renders message content added a new content type, `thinking_drop`, which renders to nothing (an empty result), similar to the existing `thinking_stripped` type used when a model's extended thinking (its visible reasoning steps) is removed from the conversation.

**Why**

This gives Claude Code a way to mark thinking content as dropped from the display without showing anything in its place, alongside the existing mechanism for stripped thinking blocks.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New telemetry: laptop_memory_rows_dropped on bug report submission

Bug report telemetry now records how many memory-context rows were dropped before submission

**What**

When a bug report or feedback is submitted, the `tengu_bug_report_submitted` telemetry now includes a `laptop_memory_rows_dropped` field. This counts how many transcript messages were stripped out because they were `cowork_memory_context` attachments tagged with leg `laptop`, before the report was sent.

**Why**

This lets Claude Code track how much memory-context data gets removed from bug reports before submission, which is relevant to diagnosing issues involving the memory feature.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Scheduled task lock acquisition skipped in certain remote/So() sessions

A scheduled-task lock is now skipped entirely in certain remote sessions instead of being acquired

**Unclear.** It is unclear exactly what session/context check this guards against or what practical effect skipping the lock has for the reader.

**What**

The internal function that acquires a lock before running a scheduled task now returns immediately, without ever touching the lock file, when no explicit lock directory is given and the session is running in a certain remote context. In that situation the lock is simply never acquired.

**Why**

Skipping the lock check avoids unnecessary file operations in remote sessions where the lock wasn't being used meaningfully, though it means scheduled-task locking behaves differently there than in a normal local session.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Existing status-banner promo gains an extra suppression condition

An existing status-banner promo now checks an extra condition before it can show

**Unclear.** The exact purpose of the added audience check isn't stated beyond it being another suppression condition.

**What**

An existing promotional banner's visibility check gained an additional condition. It already suppressed the banner based on two checks (one of them since renamed); now it also checks a viewer/campaign-audience condition before deciding whether to show.

**Why**

Adding this check narrows down further who sees the banner, likely to avoid showing it to accounts it isn't meant for.

- Area: Promotions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Permission decision telemetry gains a separate decision_reason_code field

Permission-decision telemetry now records a separate reason code alongside the reason text

**What**

When Claude Code logs telemetry about a tool-permission decision (like whether a tool call was allowed or denied), it now sends both a `decision_reason_code` and a `decision_reason`. Previously only a single combined reason field was sent; now the reason is split into a short code plus the existing descriptive message, and this applies to both the standard permission-decision event and the control-request send path.

**Why**

Splitting the reason into a stable code plus a message makes it easier to analyze and group permission decisions by reason, rather than relying on parsing free-form text.

- Area: Telemetry
- Names: `decision_reason_code`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### prompt.submit context building now goes through async storage-aware helper

Building the context attached to a submitted prompt is now an async, storage-aware step

**Unclear.** The finding does not say what practical difference this makes beyond enabling async/storage-backed resolution of context items.

**What**

When you submit a prompt, Claude Code attaches any context items (like referenced files) to the message. That attachment step now runs through a new async helper that has access to the session's storage layer (`storageV5`), instead of reading the context synchronously.

**Why**

This suggests context items can now be fetched or hydrated from storage before being attached to a prompt, rather than only using whatever was already loaded in memory. For users this should be invisible beyond potentially more complete or up-to-date context being included with a submitted prompt.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Custom system prompt strings can now be split at a boundary marker for caching

Custom system prompts can now be split into multiple cache segments

**What**

When Claude Code builds the system prompt used for analyzing context usage, a custom system prompt string is now passed through a new `splitSystemPromptAtBoundary()` helper instead of being included as one single block.

**Why**

Splitting the prompt at a boundary allows it to be broken into multiple segments for prompt caching (where Anthropic's API can reuse unchanged parts of a prompt across requests instead of reprocessing them), which can make repeated requests with a custom system prompt more efficient.

- Area: System Prompt
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Remote-notification nudge logic gains an early, simplified path

Unread-notification nudges gain a faster, simplified check before the full logic runs

**Unclear.** The gate `tengu_saffron_kite` is mentioned in evidence but nothing has been read about its state, so it's unclear what role it plays here.

**What**

The internal logic that decides whether to re-show the "unread notifications" nudge now runs a quick check first. When that check comes back false, the nudge is pushed directly using a shorter path instead of going through the full set of threshold and suppression rules.

**Why**

This is an internal streamlining of when the unread-notifications nudge gets shown; it does not change what the nudge itself communicates.

- Area: Terminal UI
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### OTel custom header helper now prefetched for HTTP-based exporters

OpenTelemetry custom header helper now prefetches once for HTTP-based exporters

**What

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### REPL progress-message deduplication in the transcript reducer

Claude Code now cleans up stale REPL progress messages instead of letting them pile up in the transcript

**What**

The internal system that tracks and updates progress messages in the conversation transcript now matches progress updates more precisely for REPL (interactive code execution) tool calls, using the specific tool call ID rather than a looser match. It also automatically discards older completed or errored REPL progress entries once more than a small number have built up recently.

**Why**

This keeps the transcript from accumulating stale, no-longer-useful REPL progress records, which should make transcripts cleaner and progress updates more accurate when running interactive code.

- Area: REPL
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Cache-key comparators for tool/hook/skill descriptions gain explicit size measurement

Internal caching for tool/hook/skill descriptions now explicitly measures text size

**Unclear.** The finding does not say what the added size measurement is used for or what behavior it changes.

**What**

Internal comparators that decide when a cache should be invalidated for tool descriptions, hook text, prompt sections, and skill text now also explicitly measure the size of that text, in addition to the equality checks they already did.

**Why**

This is an internal caching refinement with no directly described effect on user-facing behavior.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Terminal renderer gained inline-image retransmission tracking

Terminal display now retransmits inline images that may have gone stale

**What**

The terminal-drawing code now tracks when inline images shown in the terminal might be stale (`imagesStale`), and re-sends them (`retransmitAll`) or flushes queued image content (`drain`) both during normal rendering and when switching in and out of the terminal's alternate screen mode.

**Why**

Terminals can lose or garble inline images when the screen is redrawn or switched, so this keeps images displayed correctly by retransmitting them when needed.

- Area: Terminal Rendering
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### npm-sourced plugins skip the "local plugin can't be updated remotely" check

Plugins installed from npm are now treated like local plugins for update eligibility

**What**

When Claude Code checks whether a plugin can be updated remotely, plugins sourced from the npm marketplace are now special-cased: the check that normally blocks remote updates for local plugins returns immediately (no block) for npm-sourced plugins, and the plugin-info logic treats npm the same way it treats local plugins.

**Why**

This avoids incorrectly treating npm-installed plugins the same as ordinary local plugins for the purposes of the "can't update a local plugin remotely" restriction.

- Area: Plugins
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Attachment downloads now report timing/size telemetry

Attachment downloads now report timing and size telemetry

**What**

When Claude Code downloads file attachments (used when resolving bridge attachments via OAuth), it now tracks the slowest download time and the total number of bytes downloaded in a batch, and reports these numbers in a new telemetry event.

**Why**

This gives visibility into attachment download performance, which can help identify slow or oversized downloads.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Workflow agent() auto-mode classifier call now receives rootToolSurface

Workflow agents running in auto mode now report their root tool surface to the auto-mode classifier

**Unclear.** What effect passing rootToolSurface has on the classifier's decisions is not specified.

**What**

When an agent spawned inside a workflow finishes while running in `auto` permission mode (a mode where tool calls are approved automatically rather than asking the user each time), the internal check that decides how to treat that agent's actions now also receives a `rootToolSurface` value alongside the fields it already sent.

**Why**

This is an internal plumbing change. It gives the auto-mode classifier more information about which tools the agent had access to at the root level, which likely helps it make more accurate decisions, though the finding doesn't specify exactly what changes as a result.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### MCP client connections now record first-party bearer tokens

MCP connections now store first-party bearer tokens separately in memory

**What**

When Claude Code successfully connects to an MCP (Model Context Protocol, a way for Claude to talk to external tools and data sources) server, it now also stores the first-party bearer authentication token for that connection in a new internal lookup table, alongside the existing table of auth providers.

**Why**

This lets Claude Code track and reuse first-party bearer credentials per connection separately from general auth provider state, which is bookkeeping that supports more reliable authenticated MCP connections.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact comments now flag participants outside the organization

Artifact comments now mark which participants are outside your organization

**What**

When Claude Code processes comment threads on an artifact, it now identifies which participants are human, verified, and marked as being outside the organization. Comments from those participants now include an `outside: true` field in their output, and related filtering logic uses this to distinguish outside-org comments.

**Why**

This lets Claude Code and related features tell apart feedback from people inside versus outside your organization when working with shared artifacts.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Prompt-cache break diagnostics now record time-since-last-assistant-message

Prompt-cache diagnostics now record how long it's been since the last assistant message

**What**

When Claude Code diagnoses why a prompt cache (a mechanism that avoids resending unchanged context to the model) was invalidated, it now also records whether more than 5 minutes or more than 1 hour have passed since the last assistant message, plus a `querySource` field, alongside the existing cache-break diagnostic data.

**Why**

This gives more context for understanding why prompt caching broke in a given session, since cache validity is time-sensitive and knowing how long a session sat idle helps explain cache misses.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Directory-sync mid-turn notes gain a structured 'kind' alongside text

Mid-turn directory-sync notices now carry a structured reason code, not just text

**What

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Edit/Write tools now report a syncedSkillNext field

Edit and Write tool results now include a syncedSkillNext field when relevant

**Unclear.** What syncedSkillNext represents or is used for is not stated in the finding.

**What**

The `Edit` and `Write` tools (used to modify and create files) now compute an extra value and, when it's present, include it in their result data under a new field called `syncedSkillNext`.

**Why**

The finding doesn't say what this value represents or how it's used, so its practical effect for someone using Claude Code isn't clear from this change alone.

- Area: Elsewhere
- Names: `syncedSkillNext`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New global suggestions/dialog store for a UI overlay

A new shared store manages suggestion data and dialog state for a UI overlay

**Unclear.** What the suggestions/dialog overlay actually displays or is used for is not stated.

**What**

A new internal store holds two pieces of state, suggestion data and dialog state, along with a context provider and a set of hooks for components to read and write these values.

**Why**

This is internal plumbing for a UI overlay feature. The finding doesn't describe what the suggestions or dialog actually show to the user.

- Area: UI
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Boot artifact-read failures now carry richer transient/telemetry metadata

Failed artifact reads at startup now record more detail about why they failed

**What**

When Claude Code fails to read an artifact during startup, the error it records now includes whether the failure looks temporary, how long the request took in milliseconds, and whether it happened through a relay, in addition to the existing error code.

**Why**

This extra detail makes it easier to diagnose why a startup artifact read failed and whether it was a transient issue, rather than only seeing a bare error code.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Git diff helpers gain worktree/gitDir awareness

Memory sync gains a slower 'off' retry mode with random delay when its data store is unusable

**What**

The background process that keeps memory in sync now checks whether any of its data stores has become unusable. When that happens, it switches into a new 'off' retry state: it counts the number of retries, computes a randomized delay before trying again (to avoid retries all happening at once), and records the reason as `off_retry` instead of the usual `periodic` sync reason. The interval between resync attempts is now computed by a new helper function.

**Why**

This prevents memory sync from hammering a broken data store on a fixed schedule; instead it backs off with increasing, randomized delays until the store becomes usable again.

- Area: Memory Sync
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New consent-slug bucket for outside-org artifacts

Consent tracking for artifacts now separately tracks artifacts from outside your organization

**What**

Claude Code already tracked which artifacts a user had consented to interact with. It now adds a separate tracking bucket, `artifactOutsideOrgConsentSlugs`, specifically for artifacts that originate from outside the user's organization.

**Why**

Splitting this out lets Claude Code treat consent for artifacts from outside your organization differently from artifacts within it, which matters for keeping data boundaries clear between organizations.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Compaction summaries track kept REPL bindings instead of a cleared flag

Git diff-related helpers now respect the correct worktree and git directory

**What**

Two internal git helpers, one that estimates diff size and one that checks for staged deletions, now take the repository root and git directory into account and prepend that information to the underlying `git diff` command, instead of always running plain `git diff` from a fixed root.

**Why**

This makes these git checks work correctly when Claude Code is operating in a git worktree (a secondary working copy of a repository) rather than only in the main repository location.

- Area: Git
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New helper classifies plugin load source for telemetry/errors

A new helper classifies where a plugin was loaded from, for telemetry and error messages

**What**

A new internal function classifies how a plugin was loaded into one of three categories: `marketplace_not_available` (for plugins from reserved registries such as pip, uv, cargo, github, or gh), `builtin`, or `directory_loaded`.

**Why**

This gives Claude Code a consistent way to label a plugin's load source in telemetry and error reporting, which can help diagnose plugin-loading issues.

- Area: Plugins
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact publish tracks 'routine unasked' state on frame URLs

Artifact publishing now tracks a 'routine unasked' state on frame URLs during republishing

**Unclear.** What effect the 'routineUnasked' flag has for the user, beyond being recorded, is not stated.

**What**

When publishing an artifact, Claude Code now checks a new `routineRepublishedPaths` list and a per-path `routineUnasked` flag on the artifact's frame URLs (the addresses used to load the artifact's preview). When this condition applies, it marks the state with `routineUnasked: true` both internally and in the data returned by the publish tool.

**Why**

The finding doesn't say what user-facing behavior this enables, only that publishing now tracks this additional state when republishing an artifact.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New short-lived timestamp-prefixed token validity check

A new internal check rejects timestamp-prefixed tokens older than 10 minutes

**Unclear.** What token or value this expiry check is applied to, and what happens when it is rejected, is not stated.

**What**

Claude Code now has a helper that reads a leading number from the start of a string (assumed to be a unix timestamp in seconds) and only accepts the string as still valid if that timestamp is within 10 minutes of the current time; otherwise it treats the value as expired.

**Why**

The finding doesn't say what kind of string or token this check applies to, so it's not clear what user-facing feature depends on it.

- Area: Auth
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### tool.call hook-event schema gains a `measure` combinator

The tool.call hook event gained a 'measure' step that combines context across related events

**Unclear.** What practical difference the new 'measure' combinator makes to hook authors versus the previous 'carry' function is not stated.

**What**

The internal descriptor for the `tool.call` hook event, used alongside `PreToolUse` (a hook point that runs before a tool call executes and can block it), now includes a `measure` function. This function combines the context of one event with the contexts of a list of related events, replacing what was previously a simpler `carry` function.

**Why**

This is internal plumbing for how hook event context is assembled; the finding doesn't indicate a directly user-visible change.

- Area: Hooks
- Names: `tool.call`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Lazy-loaded 'mcp-display-only' tool UI module

A new 'mcp-display-only' tool UI is now lazy-loaded instead of bundled upfront

**Unclear.** What the 'mcp-display-only' tool kind represents to a user is not stated in the finding.

**What**

Claude Code's tool-UI system now has an entry for an `mcp-display-only` tool kind that only loads its display code when a tool of that type is actually shown, rather than always including it in the initial bundle.

**Why**

Loading this UI only when needed keeps the amount of code loaded upfront smaller, which can help startup performance.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New 'settings_env_default' model-source classification when ANTHROPIC_DEFAULT_MODEL is set via managed settings

Model-source tracking adds a 'settings_env_default' label for ANTHROPIC_DEFAULT_MODEL set via managed settings

**What**

The logic that attributes which source chose the current model now returns `settings_env_default` in a new case: when an organization's model-attribution mode is set to "env" and the active model matches an `ANTHROPIC_DEFAULT_MODEL`-style setting (one of the `ANTHROPIC_DEFAULT_*_MODEL` environment-variable-shaped settings).

**Why**

This lets Claude Code correctly attribute a model choice to a managed-settings-provided `ANTHROPIC_DEFAULT_MODEL` value rather than misclassifying its source, building on the existing precedence where settings-provided defaults are considered ahead of the environment variable at startup.

- Area: Models
- Names: `ANTHROPIC_DEFAULT_MODEL`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Plugin marketplace name resolution short-circuits for names already qualified with the npm marketplace suffix

Plugin marketplace resolution skips names already qualified with the npm marketplace suffix

**What**

When installing a plugin or accepting a marketplace review, Claude Code now checks first whether the plugin's identifier already ends with the `@npm` marketplace suffix. If it does, both flows stop immediately instead of trying to resolve or accept a marketplace entry for it.

**Why**

This avoids redundant or incorrect marketplace lookups for plugin names that are already fully qualified with their npm marketplace suffix.

- Area: Plugins
- Names: `@npm`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New gate tengu_typed_koala, defaults on, gates a string-comparison helper

A new internal check flags any non-empty string value other than 'empty_store'

**Unclear.** No reading of `tengu_typed_koala` has been taken under this release, and the finding does not say what feature this check supports.

**What**

A new internal helper function checks a value and returns true only when that value is a piece of text (a string) and is not the specific placeholder text `empty_store`. This check is controlled by a new gate (an internal on/off switch called a feature flag) named `tengu_typed_koala`.

**Why**

This is an internal plumbing change with no described effect on what you can do in Claude Code; it's used somewhere to distinguish real stored values from an empty placeholder.

- Flag `tengu_typed_koala`: On for this account, and not off by default (read for one account on one subscription tier against v2.1.275; 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: Gates
- Names: `tengu_typed_koala`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New notification/queued-command gate 'tengu_saffron_kite', defaults on

A new gate can now trigger remote-session notifications on its own

**Unclear.** Nothing has been read about `tengu_saffron_kite` for this site's account, so whether it is switched on cannot be said.

**What**

A function that decides whether to send certain notifications used to fire only when a session was running remotely (via `CLAUDE_CODE_REMOTE`) and another condition was met. Now it also fires whenever a new gate (an internal on/off switch) called `tengu_saffron_kite` is enabled, independent of that remote check.

**Why**

This widens the conditions under which these notifications can be sent, but the finding does not say which notifications or what triggers them beyond the gate name.

- Area: Terminal UI
- Names: `tengu_saffron_kite`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### tengu_repl_mcp_error_throw gate appears renamed to tengu_tranquil_fern

The gate behind MCP error-throwing now reads under the name tengu_tranquil_fern instead of tengu_repl_mcp_error_throw

**Unclear.** Nothing has been read about either `tengu_tranquil_fern` or `tengu_repl_mcp_error_throw` under this release, so their current state for this site's account is unknown.

**What**

The internal helper that used to check a gate (an internal on/off switch) named `tengu_repl_mcp_error_throw` now instead checks a gate named `tengu_tranquil_fern`, with the same default of enabled.

**Why**

This looks like a rename rather than a behavior change, continuing this gate's history: it was previously documented as one of a small set of flags whose value gets pinned for the life of a session so a remote configuration change mid-session can't flip it, and was compiled on at that time.

- Flag `tengu_tranquil_fern`: Not enough to say (read for one account on one subscription tier against v2.1.275; 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_repl_mcp_error_throw`: Not enough to say (read for one account on one subscription tier against v2.1.275; 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: Gates
- Names: `tengu_tranquil_fern`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Plugin op host-refusal messages consolidated behind new gate helper

Plugin hook-refusal error messages now come from one shared helper function

**What**

When a plugin operation is refused because no matching hooks module is loaded, or because a loaded hooks module doesn't call that particular hook, both refusal messages now come from a single new shared helper function instead of being handled separately. The code path that runs the operation also now passes along the relevant scan information to the function that picks the runtime handler.

**Why**

This is an internal cleanup that consolidates duplicate refusal logic; it should not change what message you see when a plugin operation is refused, just how that message gets produced internally.

- Area: Plugin API
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Compact/session-clear now resets a 'host declared tools' flag explicitly

Clearing or compacting a session now explicitly resets a per-host 'declared tools' flag

**What**

When a session is cleared or compacted (compaction summarizes and trims history to save space), Claude Code now explicitly resets a piece of state that tracks whether a host has 'declared' its tools, using a new per-host state store. This store can be subscribed to for change notifications, and at least one place in the code uses that subscription to trigger a refresh shortly afterward.

**Why**

This makes sure that after a session is cleared or compacted, Claude Code doesn't hold onto a stale record of which tools a host previously declared, so that state gets recomputed cleanly.

- Area: Sessions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact type descriptions can now resolve from a `type_file` reference

Artifact type descriptions can now be resolved from a separate type_file reference instead of inline content

**What**

A new function handles describing an Artifact's type when that type's data lives in a separate `type_file` reference rather than being written inline. It can show either a placeholder for content that hasn't been read yet, or a preview of the actual content. The calling code also now checks a new `read_of_type_link` flag to decide whether to prefix the type's title before showing its description.

**Why**

This lets Artifact type information be stored in and pulled from a separate file rather than always being embedded directly, with appropriate handling for cases where that file hasn't been read yet.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### UI-message coalescer (`DDn`) rebuilt with injectable run/schedule/warn hooks

The UI message batching function was rebuilt to accept swappable run, schedule, and warn functions

**What**

The internal function that batches and dispatches queued `ui.message` chains was rewritten so its `run`, `schedule`, and `warn` behaviors can be swapped out, instead of being fixed. By default it still uses the same real implementations as before (a function called `yft` for running, a `setTimeout`-based scheduler for scheduling, and the standard warning logger).

**Why**

This is an internal refactor that makes the message-batching logic easier to test or override, without changing its default behavior for everyday use.

- Area: UI
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### SDK bridge onSetModel/model-switch code path: internal renaming only

SDK bridge's model-switching code was re-minified with renamed internals only

**What**

The bridge code handling model switching and related MCP handlers (`onSetModel`, `onSetMaxThinkingTokens`, `onMcp*`) was re-minified with renamed internal variable names, but the logic, telemetry events, and error messages appear unchanged.

**Why**

This is a cosmetic/internal packaging change with no described effect on behavior.

- Area: SDK
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Rewind/fork_conversation remote-request handling: internal renaming only

Internal code cleanup for remote rewind and fork_conversation request handlers, no behavior change

**What**

The internal handlers for several remote-control request types, including `rewind`, `fork_conversation`, `read_file`, `get_workspace_diff`, `get_plan`, `stage_file`, `add_directory`, `file_suggestions`, and `seed_read_state`, were rewritten with renamed internal variables.

**Why**

This is housekeeping in the code that handles remote-control requests. There is no indication that behavior changed, so users should not notice any difference.

- Area: Remote Control
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### New timing constants added near context-source-checkout / OAuth refresh code

New 10-second and 60-second timing constants added near context-source-checkout and OAuth token refresh code

**Unclear.** What these timers actually govern (timeout, retry delay, or refresh schedule) is not established by the evidence.

**What**

A few new numeric timing values, two set to 10,000 milliseconds (10 seconds) and one to 60,000 milliseconds (60 seconds), were added into existing code near the error handling for context-source checkout and the scheduling logic for refreshing OAuth (login) tokens.

**Why**

The finding does not say what these timers control, such as a timeout, a retry delay, or a refresh interval, so it is not possible to say what effect this has for users.

- Area: Auth
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Startup permission/config plumbing reordered around a new call

CLI startup swaps one internal setup call for another just before model-restriction wiring

**Unclear.** What functionality these renamed/replaced calls perform, and whether startup behavior actually changes, is not established by the evidence.

**What**

During CLI startup, a call referred to internally as `Fsr(iKn(O))` was removed and replaced with a new call, `Ekt(cie(C))`, positioned right before the existing code that wires up model restrictions.

**Why**

The finding doesn't specify what these calls actually do, so it isn't possible to say what practical effect this has on startup behavior.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Internal rework of stdin/user-message admission pipeline (no clear behavior change found)

Internal code handling incoming user messages was restructured, with no identified behavior change

**Unclear.** placeholder

**What

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Chat-history virtualization / speaker-label list rendering internally reworked

Internal rework of how chat history renders speaker labels and message rows

**What**

The internal code that computes speaker-label continuation state (whether consecutive messages from the same speaker are grouped together), reply boundaries, and message row rendering in the chat history view was restructured, including a new memoized rendering call. No new user-facing capability was identified.

**Why**

This appears to be an internal refactor of chat history rendering with no described change in what users see or can do.

- Area: Chat UI
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Screen-reader render pipeline internally reworked (helper renames only)

Screen-reader output code was internally rewritten with no behavior change

**What**

The code that produces Claude Code's screen-reader accessibility output was substantially rewritten internally, with functions and local variables renamed. The actual behavior, such as how it detects a paused state, compares against previously shown lines, and delays before pausing, appears unchanged.

**Why**

This is a code-cleanliness change with no expected effect on what screen-reader users see or hear.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### reply-on-resume flow: internal rename only

Reply-on-resume code was internally renamed with no behavior change

**What**

The internal code that handles resuming a prompt and replying after it (covering prefill boundary mismatches, continuing after interrupted output, and clearing context) was heavily renamed internally. The actual behavior appears unchanged.

**Why**

This is an internal cleanup with no expected effect on how resuming or replying to a prompt behaves.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Bridge meta-MCP mount: internal rename only

Internal rename of the dynamic-MCP bridge server code, no behavior change

**What**

The module that manages the "meta-MCP" bridge (the internal server config used to mount dynamically connected MCP servers, a way of plugging in external tool servers) had its internal variables and helper functions renamed throughout, including its permission set/get wrapper, allow/deny rule helpers, and mount connect/detach logic.

**Why**

This is a code-clarity change only; nothing about how the bridge behaves appears to have changed.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Transcript list rendering: memoization slot renumbering only

Transcript list rendering code was internally renumbered, no visible change

**What**

A large block of generated memoization code (used to cache parts of message-list rendering and search-text extraction in the conversation transcript view) was renumbered and reshuffled internally.

**Why**

This appears to be a build/compiler artifact with no visible effect on behavior.

- Area: Chat UI
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Artifact publish deploy-response parsing: internal rename only

Internal rename of artifact publish deploy-response parsing code, no behavior change

**What**

The code that parses the deploy response when publishing an Artifact — including schema validation, staging file uploads, and handling conflicts or errors — had its internal variable names extensively rewritten.

**Why**

This is a code-clarity change only; the underlying logic does not appear to have changed.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Message re-queue after aborted session-start hooks now preserves order via enqueueReportingAdmission

Re-queued messages after an aborted session-start hook now keep their original order

**What**

When session-start hooks abort a batch of queued messages, the non-prompt and "resurrected" messages in that batch are now collected and re-added in reverse order using a new `enqueueReportingAdmission` call with an `{ahead: true}` option, instead of being pushed back one at a time with the plain `enqueue` call used before.

**Why**

This preserves the original ordering of messages that get put back on the queue after a session-start hook aborts, avoiding messages ending up out of sequence.

- Area: Message Queue
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### LSP plugin recommendation dialog refactored onto a shared generic component

LSP plugin install prompt rebuilt on a shared dialog component

**Unclear.** Whether this shared component is used by other plugin-recommendation dialogs is not confirmed, only suggested by the finding.

**What**

The dialog that recommends installing an LSP (language server protocol, used for code intelligence features) plugin has been rewritten to use a shared dialog component instead of its own custom layout, passing in its title, introductory text, plugin name, marketplace name, and options.

**Why**

This is an internal restructuring that likely lets this dialog share behavior and appearance with other plugin-recommendation prompts, without changing what it recommends.

- Area: UI
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### User message rendering tracks an 'awaiting model' state

User messages in the transcript now track an internal 'awaiting model' state

**Unclear.** What awaitingModel actually changes about how a message looks or behaves isn't stated.

**What**

The component that renders a user's message in the transcript now derives an `awaitingModel` value from the message's ID and passes it down into the message body, for both the brief and normal transcript display layouts.

**Why**

The finding doesn't say what visible effect this has, only that the state is now tracked and threaded through rendering.

- Area: Chat UI
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### MCP task-result saving now records cwd used for the auth-helper subprocess

MCP auth-helper subprocess now runs with an explicit working directory when one is set

**What**

When Claude Code saves the results of an MCP (Model Context Protocol, a way of connecting external tools) task, it runs an internal `proxyAuthHelper` subprocess to handle authentication. That subprocess now runs with an explicit working directory (`cwd`) when one is available, instead of always using the default.

**Why**

Setting the working directory explicitly makes the auth-helper subprocess behave consistently regardless of what directory it happens to be launched from, which matters when Claude Code needs it to resolve paths correctly.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Assistant transcript entries now carry request_id and structured error/uuid/timestamp fields directly

Assistant transcript entries now explicitly store a request_id alongside error, uuid, and timestamp

**What**

The internal code that builds each assistant message entry in a conversation transcript was rewritten to explicitly set its fields: `type`, `message`, `uuid`, `timestamp`, `error`, and, when available, `request_id`. Previously this was built by copying the whole input object and only removing one field; now each field is set directly.

**Why**

This makes transcript entries carry a clear, explicit `request_id` when one exists, which is useful for tracing a given assistant message back to the specific request that produced it, rather than relying on whatever happened to be present in the original object.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Trust-workspace default variable renamed in help text template

Help text for --trust-workspace now references a renamed internal default variable

**Unclear.** It is unclear whether the displayed default value or wording actually changed, or only the internal variable name.

**What**

The help text shown for the `--trust-workspace` flag now pulls its default value from a differently-named internal variable than before.

**Why**

The finding does not indicate any visible behavior change, only an internal renaming of the variable that feeds the flag's help text.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Queued-notification drop message reworded to 'no ingress host'

Warning for undeliverable queued notifications now says 'no ingress host' instead of blaming remote mode

**What**

When a queued notification arrives but Claude Code has nowhere to route it, the internal log message describing the situation changed. It previously referred to 'remote mode'; it now says there is no ingress host (the address notifications would be sent to).

**Why**

This is a wording fix to the internal warning log, making the actual cause (a missing routing address) clearer than the old, less accurate description.

- Area: Remote Control
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### apiKeyHelper case removed from dead switch in Op

A dead code path's switch statement dropped an unused apiKeyHelper case

**What**

Inside a function that is already unreachable (guarded by a condition that is always false), the `case "apiKeyHelper"` branch was removed from a switch statement that also handles `"none"`, `"ANTHROPIC_API_KEY"`, and `/login managed key`.

**Why**

Since this code path never runs, this is a cleanup of dead code rather than a behavior change. It does not affect the `apiKeyHelper` setting itself, which is used elsewhere to generate API credentials.

- Area: Auth
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### File-read content tracking gained readNotes

File-read display now carries additional read notes alongside the file's text content

**Unclear.** The finding doesn't say what readNotes contains or how it changes what's shown to the user.

**What**

When Claude Code renders the result of reading a text file, it now passes along an additional `readNotes` value together with the file's raw content, rather than passing just the content string on its own.

**Why**

This allows the file-read display to carry extra contextual notes about the read alongside the content itself, though the finding doesn't specify what those notes contain.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Some abort/tracking object (HN) removed from remote-session hook wiring

An abort-tracking object is no longer created in remote session hook setup

**Unclear.** What the removed object tracked and what effect its removal has isn't stated in the evidence.

**What**

In the code that wires up remote/thin-client sessions, an object that used to be conditionally created (when a certain internal flag was true) is now never instantiated at all, in both of the relevant session-hook code paths.

**Why**

Whatever tracking or abort-handling this object provided is no longer active in these remote session paths; the practical effect for users isn't specified.

- Area: Remote Control
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### New helper checks whether an MCP client already has a registered auth provider

A new internal check tells whether an MCP client already has a registered auth provider

**Unclear.** The finding states this is 'likely' used to skip redundant OAuth steps, but doesn't confirm where or how it's actually used.

**What**

A new helper function checks whether a given MCP (Model Context Protocol) client already has an authentication provider registered, by looking it up in an internal map of client auth providers.

**Why**

This check likely lets Claude Code skip redundant OAuth registration or step-up authentication steps for a client that's already been set up, though the finding doesn't confirm exactly where it's used.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### MCP call/auth error-handling block heavily refactored (no behavior change found)

MCP call and auth error-handling code was rewritten internally with no behavior change found

**What**

The internal code handling MCP (Model Context Protocol, used to connect Claude Code to external tools and data) calls, authentication, clearing auth, and applying flag settings was restructured with new variable names throughout. The error messages it produces and the logic for when they occur appear unchanged.

**Why**

This looks like internal cleanup rather than a change a user would notice.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Input-box React component internals re-memoized (no evident feature change)

Chat input box internals were re-memoized with no visible feature change

**What**

The internal caching logic for the chat input box's React component was regenerated with new internal names and cache slot positions. The visible behavior it supports—history navigation, pasting, opening an external editor, pasting images, and toggling the workflow keyword—looks the same as before.

**Why**

This appears to be internal refactoring rather than a change that affects how typing or pasting in the input box works.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### runner session cleanup: appears to be pure identifier churn, no behavioral diff found

Runner session cleanup code was renamed internally with no behavioral change found

**What**

The block of code that handles cleanup when a session fails to spawn or is released—unmounting, running the post-session hook, flushing debug logs, and removing worktree and session state—is structurally the same as before. The only differences found were internal variable renames from the build process.

**Why**

This appears to be incidental renaming rather than a change to how session cleanup behaves.

- Area: Sessions
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### No-op fallback for non-prompt name labeling

A source-scope labeling helper now returns nothing for anything that isn't a prompt

**Unclear.** The finding does not say which non-prompt item types are affected or what previously happened for them.

**What**

A helper function that labels slash-command-like items by where they come from (project, plugin, org, or claude.ai) now falls through to a function that always returns `undefined` for any item that isn't a prompt type.

**Why**

This means non-prompt items no longer get a source-scope label from this helper, avoiding incorrect labeling for item types the helper wasn't meant to handle.

- Area: Slash Commands
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

## Removed

### Account-scope memory store removed / disabled in this build

Account-level memory storage no longer works in this build and errors instead

**What**

Claude Code supports storing memory (persisted notes/context) at different scopes. The 'account' scope, which would store memory tied to your account rather than a specific project or machine, now always fails: looking up its storage key throws an error, and the function that used to locate the account-scope storage directory now just returns the literal string "escape" instead of doing a real lookup.

**Why**

Anyone relying on account-scoped memory will find it no longer works in this build; attempts to read or write it will fail outright rather than silently doing nothing.

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

### CLAUDE_REPL_VERBOSE env var and its virtual-message filtering removed

The CLAUDE_REPL_VERBOSE environment variable and its message-filtering behavior have been removed

**What**

Claude Code previously supported a `CLAUDE_REPL_VERBOSE` environment variable. When set, it changed how the message-history compaction and resume logic worked: it would skip certain internal (virtual) assistant and user messages that weren't "thinking" messages. In this build, that variable is gone entirely, and the underlying setting it controlled is now hardcoded to off, so the skip behavior no longer happens.

**Why**

If you were relying on `CLAUDE_REPL_VERBOSE` for any workflow, it no longer has any effect, since the code path that read it has been removed.

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

### Context-collapse ('marble-origami') sync channel removed

Old context-collapse sync channel replaced by a new memory-mode channel

**Unclear.** What functional difference the new memory-mode sync entry makes compared to the old context-collapse entries is not stated.

**What**

The 'marble-origami' sync-state entries used for context collapse (commit, snapshot, and reset) have been removed from the session-state broadcast tables and session serialization, along with their contextCollapseCommits and contextCollapseSnapshot fields. A new 'memory-mode' sync entry has replaced them.

**Why**

This retires the old context-collapse syncing mechanism in favor of a new memory-mode mechanism, though the finding doesn't say what behavior changes for users as a result.

- Area: Session State
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### "Context collapse" feature and its telemetry removed

The 'context collapse' feature and its telemetry have been removed

**What**

All `context_collapse_*` telemetry events (`apply`, `ctx_agent_spawn`, `recover_413`, `restore`) were removed from the list of allowed telemetry events, and related fields such as `claimedCollapse` and the `skipCollapseStatus` logic in the memory/context summary builder were stripped out as well.

**Why**

This removes an existing feature, referred to internally as context collapse, along with its tracking, from Claude Code.

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

### CLAUDE_CONTEXT_COLLAPSE_MODEL env var removed entirely

The CLAUDE_CONTEXT_COLLAPSE_MODEL environment variable has been removed

**Unclear.** The finding does not say what CLAUDE_CONTEXT_COLLAPSE_MODEL did or why it was removed.

**What**

The `CLAUDE_CONTEXT_COLLAPSE_MODEL` environment variable, which was previously recognized and passed through by Claude Code in two places, no longer appears anywhere in the codebase.

**Why**

Anyone who set this environment variable should know it no longer has any effect.

- Area: Env Vars
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5
