# Claude Code v2.1.274

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

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

This build carries 28 gated additions that stay out of reach. A pasted-content wrapping tag can mark text as untrusted content, but the killswitch tengu_virtual_pancake defaults off, and a new built-in AGENTS.md plugin that can load AGENTS.md as project instructions alongside or instead of CLAUDE.md is also off by default. A hidden, server-armed fallback lane can now retry refused or failed model turns under different telemetry names, and a gated "start kit" feature (tengu_concurrent_candle, or CLAUDE_CODE_ARTIFACT_START_KIT) can auto-bundle an artifact type, design system, and REPL tool once switched on. Compaction has also gained the ability to carry forward a short summary of key attachments across a compaction boundary, and Projects threads can now label replies as sent directly, relayed, or from the timeline behind a killswitch that defaults off.

Of 231 shipped changes, a new built-in "Claude Test" plugin runs plain-language specs against your local dev server in a real browser and reports pass or fail, and the Plugin SDK adds agent.register and session.refreshAgents calls alongside a new register-agent hook, so plugins can define custom agents at runtime. Org admins can now force their default reasoning-effort level onto all users, and public artifact reads from outside your organization are blocked unless a person approved them. Several new environment variables landed too: CLAUDE_CODE_MCP_STARTUP_WAIT_MS caps how long Claude Code waits for MCP servers to start, CLAUDE_CODE_FOOTER_INDICATOR overrides the status line's footer pill text, and CLAUDE_CODE_HOST_SESSION_ID is now recognized for passthrough. The claude gateway command also shuts down gracefully on SIGTERM/SIGINT instead of exiting abruptly, and the MCP client SDK's compiled fallback runtime flipped from v1 to v2.

Among 42 fixes, stdio MCP servers that exit right after a startup probe times out now get one automatic restart, and worktree cleanup now checks whether the .git file still exists before assuming a worktree is safe to remove. Clicking in the terminal UI no longer registers hits on elements clipped outside their scrollable or hidden container, and plugin config sync no longer drops managed plugin entries when remote policy settings haven't caught up yet. OAuth device-flow login now shows a clear message when sign-in attempts hit "slow_down" rate limiting, and device IDs are now validated against a pattern before being trusted for bridge or session connections. Very long proxied requests can also skip the HTTP client's own timeout when a longer timeout is explicitly requested.

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

### New built-in "Claude Test" plugin for browser-based spec testing

New built-in 'Claude Test' plugin runs plain-language specs against your local dev server in a real browser and reports PASS/FAIL

**Unclear.** Whether the tengu_mellow_hollerith gate is switched on for any account is unread, so nothing can be said about its status.

**What**

Claude Code now ships a bundled plugin called Claude Test, invoked with the `/claude-test` command. It includes:

- skills for running, executing, and drafting test specs (`claude-test`, `claude-test-execute`, `claude-test-draft`)

- agents for exploring, authoring, and running tests (`explorer`, `author`, `runner`)

- a browser automation server (built on Playwright) that drives a real, headless browser

It reads plain-language test specs from a `.claude-test/specs/` folder in your project, runs them against your local development server in an actual browser, and reports a PASS or FAIL for each spec along with a screenshot.

**Why**

This lets you describe how a feature should behave in plain language and have Claude Code verify it in a real browser, rather than writing and maintaining browser test code by hand.

- Area: Testing
- Names: `/claude-test`
- Tier: Use it now
- Useful: 5/5
- Signal: 4/5

### New built-in AGENTS.md plugin (off by default)

A new built-in agents-md plugin can load AGENTS.md as project instructions instead of, or alongside, CLAUDE.md

**Unclear.** Whether this plugin is active for any given account is unknown, since nothing has been read yet about the `tengu_agents_md_mod` gate.

**What**

A new bundled plugin called "agents-md" can load an `AGENTS.md` file as project instructions instead of, or together with, `CLAUDE.md`. This is controlled by a `projectInstructions` user config option with four values:

- `claude` (the default): use `CLAUDE.md` only

- `agents-fallback`: fall back to `AGENTS.md` when there's no `CLAUDE.md`

- `both`: use both files

- `none`: use neither

When a project has an `AGENTS.md` but no `CLAUDE.md` and the setting is left at `claude`, Claude Code shows a one-time toast suggesting the user switch the setting to `agents-fallback` to load it.

**Why**

This gives projects that already use the `AGENTS.md` convention a way to have Claude Code pick it up as project instructions.

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

### New skill-proposal tool surfaces recurring procedures as skill suggestions

New skill-proposal card suggests skills based on procedures that recur in a session

**What**

A new render-only tool can show a review card that proposes up to 3 skills (reusable, packaged sets of instructions) when it notices a multi-step procedure recurring in the current session. Proposals can be brand-new skills or improvements to skills the user already owns. This tool cannot write files itself, cannot update plugin skills or Claude Code's own built-in skills, and any proposed improvement must replace the skill's entire `SKILL.md` file rather than editing part of it.

**Why**

This surfaces an opportunity to turn a repeated manual workflow into a reusable skill, without the tool silently modifying files on its own; the user still reviews and applies the suggestion.

- Area: Skills
- Tier: Nothing to try yet
- Useful: 4/5
- Signal: 4/5

### Pasted-content wrapping tags gated off by default (tengu_virtual_pancake)

Pasted text can be wrapped with an 'untrusted content' marker, but the gate defaults off

**What**

A new helper decides whether text a user pastes into a conversation turn should be wrapped in a tagged block carrying an instruction that the content inside is untrusted pasted text. This helper is already called from several places, including message rendering, paste handling, and prompt construction, but it is controlled by a flag, `tengu_virtual_pancake`, that defaults to off.

**Why**

This groundwork would let Claude Code flag pasted content as untrusted input, which could help models treat it more cautiously, but since the flag defaults off, it has no effect unless enabled.

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

### SendUserFile can now place files in a project's shared Library folder, gated behind bridge child sessions

SendUserFile can now deliver files into a project's shared Library folder for bridge child sessions

**Unclear.** Whether this project-Library delivery path is active for any given account is unknown, since nothing has been read yet about the `tengu_bridge_child_file_upload` gate that controls it.

**What**

The `SendUserFile` tool now runs a `checkPermissions` step before sending a file, in addition to the input validation it already had. It also gains a new destination: a project's shared folder (called the 'project files door'), which shows up in the project's Library. When a file lands there, Claude is told to declare `attached_outputs: [{ kind: 'file', ref: <path> }]` so the file also shows up on the current thread. This new destination is gated behind bridge child sessions by a helper check.

**Why**

This lets Claude place output files somewhere shared across a project instead of only attaching them to a single conversation.

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

### New plugin hook: register agent

Plugins can now register custom agents at runtime through a new hook

**What**

Plugins (add-on packages that extend Claude Code) can now register their own agent definitions while running, using a new function hook called `$.agent.register`. This joins the existing hooks that let plugins register commands and tools. The definition a plugin submits is checked against a schema before being accepted, and Claude Code records whether each registration succeeds or fails.

**Why**

This lets plugin authors ship custom agents that install themselves automatically, instead of requiring users to manually add agent configuration.

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

### Plugin SDK ($.) gains agent.register and session.refreshAgents, plus a system-prompt-delivered flag consumable once

Plugin SDK adds agent.register and session.refreshAgents, plus a one-shot flag for whether the system prompt was delivered

**What**

The plugin system's internal dispatch table adds an `agent.register` action, which validates that a `prompt` is provided and that the description meets length rules, sitting alongside the existing `agent.list` action. The headless session's `$` scripting surface also gains a `refreshAgents()` method next to the existing `refreshCommands()`.

Separately, the turn-runner gains a `takeSystemPromptDelivered` option: a one-shot getter that reads and then clears an internal flag tracking whether the system prompt was delivered.

**Why**

This lets plugins register new agents programmatically and refresh the list of available agents, and lets other code check exactly once whether the system prompt has already been sent for a turn.

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

### Background classifier gains a (currently dark) turn-brief tail-length knob

Background classifier gets a new, currently inactive setting to control how much recent conversation text it quotes

**Unclear.** Whether the tengu_bg_classifier_config or tengu_bg_classify gates are switched on for any account is unread, so nothing can be said about their status.

**What**

Claude Code runs a background classifier behind the scenes to judge the state of a conversation turn. It has gained a new `turnBriefTailChars` setting that would control how many trailing characters of the turn's text get quoted when building a "turn brief" summary, replacing a fixed-length cutoff. When this setting is present, the classifier can also produce this new 'turn brief' output, using a larger token budget than before, and report it through a new `turn_brief` telemetry event alongside the existing background-classification events.

However, the function that would supply this setting is hard-coded to return nothing in this build, so the new behavior cannot actually take effect yet.

**Why**

This lays groundwork for a future feature that summarizes what happened at the end of a turn, but it has no effect on the current release.

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

### New artifact "quickstart start kit" feature, gated by tengu_concurrent_candle / CLAUDE_CODE_ARTIFACT_START_KIT

A new gated 'start kit' feature can auto-bundle an artifact type, design system, and REPL tool

**What

- Flag `tengu_concurrent_candle`: Off in both readings (read for one account on one subscription tier against v2.1.274; 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: Artifacts
- Names: `tengu_concurrent_candle`, `CLAUDE_CODE_ARTIFACT_START_KIT`
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 4/5
- Present in the build but not switched on

### SSE transport can parse a worker attestation policy header, but nothing installs the sink

SSE network transport can parse a worker attestation policy header, but nothing installs it yet

**What**

The SSE (server-sent events, a way of streaming data over HTTP) transport used for network connections gained the ability to hold a "worker attestation policy sink" and, if one is set, to add a `worker_capabilities=attestation-floor/1` marker to its connection URL and parse a new `x-ccr-attestation-policy` response header. That header can specify a mode (`off`, `observe`, or `enforce`) and an acceptance level such as `VERIFIED_BY_GATE`. Nothing in this build actually sets the sink, so none of this runs yet.

**Why**

This is groundwork for a future worker-attestation feature (a way to verify properties of the machine handling a request) that isn't wired up or active in this build.

- Area: Internals
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 4/5
- Present in the build but not switched on

### Silent, server-armed fallback lane for refused/failed model turns

A hidden, server-controlled fallback path can now retry refused model turns under different, less visible telemetry names

**Unclear.** None of the related gates (`tengu_convolute_arcades_retry`, `tengu_convolute_arcades_tools`, `tengu_fallback_sweep_tools`, `tengu_refusal_fallback_triggered`) have been read, so nothing can be said about whether this silent lane is active for any account.

**What**

Claude Code already retries a turn on a fallback model when the main model refuses or fails, logging that under clearly named events. A new 'silent lane' mechanism now sits alongside this. It can be turned on either by a remote configuration key (`convolute_arcades`) or by the server sending a response header `x-cc-tender-quilt: 1`, which the client locks in via a function called `armSilentLaneFromServer`. When this silent lane is active, the same kind of retry is logged under differently, less descriptively named telemetry events (`tengu_convolute_arcades_retry` and `tengu_convolute_arcades_tools`) instead of the normal ones (`tengu_fallback_sweep_tools`, `tengu_refusal_fallback_triggered`), and the source that armed it is recorded as `arm_source`.

**Why**

This adds a server-controlled path for retry behavior that is deliberately harder to distinguish from other traffic in the usual telemetry, though what specifically triggers or benefits from it is not stated.

- Area: Model Fallback
- Names: `convolute_arcades`, `x-cc-tender-quilt`
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 4/5
- Present in the build but not switched on

### New `Markdown` JSX element type added to the terminal UI element SDK

Plugin and skill terminal UIs can now render a Markdown element with optional clickable links

**What**

When plugins or skills build custom terminal user interfaces (screens made of building blocks like `Box`, `Text`, and `Code`), they can now use a new `Markdown` element type. It takes a `text` prop containing markdown, and supports `dimColor` for dimmed text, plus `pressableLinks` and `onLinkPress` for clickable links inside the rendered markdown. The new element is recognized across terminal, desktop, mobile, and VS Code layouts.

Alongside this, the rendering engine got extra safety checks for the new element: it guards against a hook or plugin secretly swapping in much longer text than it originally rendered, and it rejects any prop value that contains a control character (a hidden escape sequence that could make the terminal do something unexpected).

**Why**

This gives plugin and skill authors a straightforward way to show formatted text, including links, inside custom UI panels, without having to hand-roll markdown rendering themselves. The added validation helps stop a compromised or misbehaving plugin from tricking the terminal into rendering something other than what it appears to show.

- Area: Terminal UI SDK
- Names: `Markdown`, `dimColor`, `pressableLinks`, `onLinkPress`
- Tier: Use it now
- Useful: 4/5
- Signal: 3/5

### Org admins can force their default reasoning-effort level onto users

Org admins can now force their default reasoning effort level onto all users

**What**

A new server-side configuration field, `org_model_default.override_user_effort`, lets an organization force its default effort level (`effortLevel`, which sets how much reasoning a model does by default) onto all its users for a given model. When this field is set to true, Claude Code's effort-level resolution uses the organization's `default_effort_level` instead of a user's own saved per-model effort setting.

**Why**

This gives organizations a way to standardize reasoning effort across their users, overriding individual preferences when the admin wants consistent behavior or cost control.

- Area: Model Settings
- Names: `org_model_default.override_user_effort`
- Tier: Use it now
- Useful: 4/5
- Signal: 3/5

### Plugin-provided agent definitions can be registered and forgotten dynamically

Plugins can now register and later unregister their own agent definitions dynamically

**What**

Plugins can now register custom agent definitions (subagents, i.e. specialized helper agents a plugin provides) under a composite key combining the plugin's name and the agent's name. Plugins can also forget these registrations later, which triggers the agent list to refresh automatically.

**Why**

This lets plugins add and remove their own agents dynamically, for example if a plugin is disabled or reloaded, without requiring a restart to update the list of available agents.

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

### Artifact 'watch' tool distinguishes a new 'live' watch mode from 'durable'

Artifact watch tool adds a 'live' watch mode distinct from 'durable' watching

**Unclear.** The finding does not say what distinguishes 'live' watching from 'durable' watching in practice, beyond the unwatch description.

**What**

The Artifact tool's `watch` feature now distinguishes a third mode, 'live', from the existing 'durable' mode. This changes the permission prompts shown when watching starts, and changes what 'unwatch' is described as doing: for live watches, unwatching now says "it stops keeping track of new versions published elsewhere," instead of the durable-mode description about stopping republish notifications and cloud-session comment wakes.

**Why**

This gives the model and the user a clearer, mode-specific explanation of what stopping a watch actually does, rather than one description covering two different behaviors.

- Area: Artifacts
- Names: `live`, `durable`
- Tier: You'll notice
- Useful: 4/5
- Signal: 3/5

### New env var caps/controls MCP connector startup wait

New CLAUDE_CODE_MCP_STARTUP_WAIT_MS env var controls how long Claude Code waits for MCP servers to start

**What**

A new environment variable, `CLAUDE_CODE_MCP_STARTUP_WAIT_MS`, controls how long Claude Code waits for MCP (Model Context Protocol) connector servers to start up. When set, it overrides the normally computed wait time, though it's still capped by an internal maximum. Setting it to a value greater than 0 also switches on waiting for 'deferrable' MCP connections, which otherwise may not be waited for.

**Why**

This gives users a way to tune startup behavior for MCP servers that are slow to connect, instead of being stuck with a fixed built-in timeout.

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

### SDK gains an agent.register call

SDK adds an agent.register call for defining named agents programmatically

**What**

The SDK's agent namespace, alongside its existing `spawn` and `list` methods, now has a `register` method. It takes an object with `name`, `description`, `prompt`, and other fields, validates that the name is only letters, digits, underscores, or hyphens (up to 64 characters), and forwards the call to the underlying `agent.register`.

**Why**

This lets developers using the SDK define and register custom agents (specialized configurations of Claude Code for specific tasks) in code, rather than only through configuration files.

- Area: SDK
- Names: `agent.register`
- Tier: Use it now
- Useful: 5/5
- Signal: 2/5

### Type-locked artifact reads can skip the raw-HTML disk save ("fresh read")

Artifact reads for type-locked artifacts can now return data without first writing it to disk

**What**

When an artifact (a file-like object Claude Code creates and manages, such as a document or piece of generated content) is "type-locked" and you own it but haven't yet saved your own files to it, reading it via `artifact_bash` can now compute a fresh summary directly instead of always writing a raw HTML copy to disk first. This path is controlled by feature flags (`typeCatalogOn`, `typeCreateOn`) and a new environment variable, `CLAUDE_CODE_ARTIFACT_FRESH_READ`.

**Why**

Skipping the unnecessary disk write for a fresh, unmodified artifact should make reads faster and avoid creating file copies that aren't needed yet.

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

### Public, outside-org artifact reads now explicitly gated and denied by default

Reading a public artifact from outside your organization is now blocked unless a person approved it

**Unclear.** Whether this behavior is active for any given account depends on the `tengu_cobalt_plinth_sedge` setting, which no reading has yet confirmed for this release.

**What**

An "artifact" is a file or piece of content Claude Code can read or produce. There is now a specific check for public artifacts that belong to an organization other than yours: reading one is denied by default, with no fetch happening at all, unless a person has explicitly approved reading it. A separate, previously ungated "tokenless" public-read path is also now covered by this same gating.

**Why**

This closes a gap where Claude Code could pull in a public artifact from an outside organization without anyone signing off on it first, reducing the risk of unintentionally reading content that wasn't meant to be accessed in that context.

- Flag `tengu_cobalt_plinth_sedge`: Off by default, switched on for this account (read for one account on one subscription tier against v2.1.274; 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: 3/5
- Signal: 3/5

### CLAUDE_CODE_FOOTER_INDICATOR environment variable can override the footer pill

New CLAUDE_CODE_FOOTER_INDICATOR environment variable overrides the status line's footer pill text

**What**

The small text pill shown in Claude Code's status line footer can now be set directly with a new `CLAUDE_CODE_FOOTER_INDICATOR` environment variable. If it's not set, the footer falls back to the existing behavior of pulling the indicator text from the bootstrap `client_data.footer_indicator` value.

**Why**

This lets you (or whatever environment launches Claude Code) control the footer pill text directly, without depending on the client-supplied bootstrap data.

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

### CSS 'position' (absolute/relative) support added to Ink layout styles

Ink-based layout boxes now support CSS-style position (relative/absolute) with top/left/right/bottom offsets

**What**

The internal layout system that Claude Code uses to draw boxes on screen now accepts a `position` property, set to either `relative` or `absolute`, along with `top`, `left`, `right`, and `bottom` offsets. This was previously rejected as an unsupported style.

**Why**

This is an internal capability used to build the terminal interface. It allows screen elements to be positioned more precisely, which can enable more complex or polished layouts in the tool's output.

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

### Markdown text can now register clickable/pressable links in the TUI

Links inside markdown text in the terminal UI are now clickable, not just buttons

**What**

Markdown text rendered in Claude Code's terminal interface can now contain clickable links. Links using `https`, `http`, or `file` schemes are recognized, and the interface distinguishes a single click from a double-click before triggering the link. This is built on the same `ui.press` event plumbing that previously only worked for `Button` elements, now extended to a `Markdown` element type.

**Why**

This means links written in markdown output (rather than only dedicated buttons) can now be clicked to trigger an action, making links in Claude's terminal responses more interactive.

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

### New built-in plugins 'diff' and 'claude-test' added, plugin loading made lazy/named

Claude Code adds two new built-in plugins, 'diff' and 'claude-test', and loads plugins lazily

**Unclear.** The finding doesn't say what the 'diff' or 'claude-test' plugins actually do, or whether lazy loading changes startup behavior noticeably.

**What**

Claude Code ships two new built-in plugins, called `diff` and `claude-test`, alongside the existing built-in ones (`sec-default`, `agents-md`, `plugin-authoring`, `tips`). A plugin is a bundle of extra capabilities that Claude Code can load into a session. Internally, the way these built-in plugins get loaded also changed: instead of registering each one immediately at startup, they're now registered by name with a loader function that presumably runs only when needed.

**Why**

The new plugins add capabilities to Claude Code out of the box, though the finding doesn't say what `diff` or `claude-test` specifically do. The lazier loading mechanism is an internal change that shouldn't be visible day to day.

- Area: Plugins
- Names: `diff`, `claude-test`
- Tier: Use it now
- Useful: 4/5
- Signal: 2/5

### Artifacts flow now routes documents to a first-party Docs connector when attached

Publishing artifacts now routes documents to a connected Claude Docs connector when one is attached

**What**

When creating an artifact (a generated file or document shown alongside a conversation), Claude Code can now detect whether the host application has attached a first-party connector for reading and writing documents, referred to as Claude Docs. If that connector is present, document creation is routed to it (or to a related skill) instead of creating a regular Artifact. If no such connector is attached, it falls back to the existing quickstart behavior. The connector is only treated as first-party when the host itself asserts this; it is never inferred from a server's own name, description, or instructions.

**Why**

This lets documents be created directly in a proper document connector when one is available, rather than always falling back to a generic artifact.

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

### Model-pinning setup wizard generalized to support both Vertex AI and Bedrock

The onboarding model-pinning wizard now supports Bedrock as well as Vertex AI

**What**

The onboarding screen for "pinning" model versions (locking Claude Code to specific model versions for Sonnet, Opus, Haiku, and Fable, rather than always trying newly released models) was rewritten to work with more than one provider. It now takes a provider object that supplies tier defaults, candidate model lists, a probe check, and error labeling, and two providers are wired in:

- Amazon Bedrock, with automatic AWS profile discovery and region-specific error handling

- Vertex AI, using the same flow as before

The wizard warns that without pinning, Claude Code will try newly-shipped models even if your account or project hasn't enabled them yet, which can cause connection failures until you pin to a model you have access to or enable the new one.

**Why**

Bedrock users get the same guided model-pinning setup that was previously only available for Vertex AI, reducing the chance of unexpected connection failures when a new model ships that their account hasn't enabled.

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

### New bash-first prompt steer variant experiment slot

A new bashFirstSteerVariant experiment slot was added, gated by tengu_cozy_teapot and overridable via CLAUDE_CODE_COZY_TEAPOT

**What**

The per-session experiment-memoization system gained a new field, `bashFirstSteerVariant`, joining existing experiment slots like `preReadLineDropped`, `leanPrompt`, `modelForPrompt`, and `delegationCostsFirst`. It defaults to "strict" and can be controlled by the `tengu_cozy_teapot` gate or overridden with the `CLAUDE_CODE_COZY_TEAPOT` environment variable.

**Why**

This is infrastructure for testing variants of the 'bash-first' steering wording that pushes Claude toward using Bash for edits, allowing the behavior to be adjusted per session without a code change.

Gate state

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

### Agent spawn config now recognizes an 'isolation' key end-to-end

Spawning an agent can now carry an 'isolation' setting through to its configuration

**What**

The list of settings recognized when serializing an agent's spawn configuration (for example, for the SDK) now includes `isolation`, alongside existing settings like `background` and `omitClaudeMd`. Separately, the schema validating spawn options for isolation, observer, and observer message was refactored to use shared helper definitions instead of separate inline ones.

**Why**

This lets an agent's `isolation` setting actually be carried through when its configuration is passed along, rather than being dropped during serialization.

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

### Fleet view background-agent relaunch can now target a specific agent type

Fleet view can now relaunch a background agent as a specific agent type after an update

**What**

The Fleet view (the screen listing background jobs/agents) now accepts a `typedAgent` value, which flows through to the helper that relaunches the Fleet UI after an app update. When relaunching, this is passed via a new `--agent` argument, alongside the existing `cwdFilter` and `dispatchDefaults` (with an inherited default permission mode stripped out).

**Why**

This lets a background agent relaunched after an update keep running as the specific agent type it was dispatched with, rather than losing that setting across the relaunch.

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

### New CLAUDE_CODE_HOST_SESSION_ID passthrough env var

Claude Code now recognizes a CLAUDE_CODE_HOST_SESSION_ID environment variable

**Unclear.** The finding does not say what consumes this value or what behavior depends on it.

**What**

Claude Code now forwards and recognizes a new environment variable, `CLAUDE_CODE_HOST_SESSION_ID`, alongside existing ones like `CLAUDE_CODE_ENTRYPOINT` and `CLAUDE_CODE_IS_COWORK`.

**Why**

This lets the host environment that launches Claude Code pass through an identifier for the session it is running inside, which other internal logic (such as entry-point-specific gating) can rely on.

- Area: Environment Variables
- Names: `CLAUDE_CODE_HOST_SESSION_ID`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### New height-locking layout primitive for terminal UI

New terminal UI component can lock a box's minimum height to prevent output from jumping around, e.g. for parked sessions

**What**

A new layout building block for the terminal interface renders its contents in a box whose minimum height can be locked to the last-measured size. The lock can apply 'always' or only while the content is offscreen, and a `restartKey` can reset the lock. It's used to keep output height stable in cases where content might otherwise jump around, such as parked or background sessions.

**Why**

This prevents the terminal display from visibly resizing or jumping when content changes, particularly for sessions running in the background, making the interface feel steadier.

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

### New pressable 'Markdown' UI component added to render surfaces

A new 'Markdown' component can now be rendered by custom render hooks, with link-press handling required

**What**

Render hooks (custom code that draws parts of the Claude Code interface) can now draw a `Markdown` component, added to the list of allowed components for the default, mobile, and VS Code display surfaces. A `Markdown` component must be given an `onLinkPress` handler (a function that runs when a link inside it is clicked); leaving it out now produces a specific error message. The logic that figures out where dialogs can be positioned on screen also now treats `Markdown` specially, since its rows aren't bounded the way other components' are.

**Why**

This lets custom render hooks display formatted Markdown text directly, with a safeguard to make sure links inside it are actually clickable rather than silently doing nothing.

- Area: Plugin UI SDK
- Names: `onLinkPress`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### Structured startup-refusal reasons for host integrations

New structured reason codes let a host app tell why Claude Code refused to start

**What**

Claude Code can now report a specific, structured reason when it refuses to start, instead of just failing silently or with a generic message. This is meant for a host application (like an IDE extension or desktop wrapper) that embeds Claude Code, so it can react to the specific cause rather than just retrying blindly. New reason values include:

- `worktree_resume_refused` and `worktree_unverified` (problems resuming a git worktree, an isolated working copy of a repo)

- `session_held_by_background` (another process is using the session)

- `bypass_root` (a root-related safety check)

- `shell_tool_missing`, tied to the `CLAUDE_CODE_USE_POWERSHELL_TOOL` setting

- `cli_version_too_old`

- `gateway_signin_required` and `gateway_access_denied`

- `org_pin_api_key_conflict`, `org_verify_failed`, `org_pin_mismatch`

- `managed_settings_invalid` and `remote_settings_required_unavailable`

- `proxy_invalid`

- `temp_dir_unusable` and `cwd_unavailable`

**Why**

Giving each startup failure a distinct machine-readable reason lets host applications show the right message or take the right corrective action automatically, rather than treating every startup refusal the same way.

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

### claude gateway gets graceful shutdown on SIGTERM/SIGINT

claude gateway now shuts down gracefully on SIGTERM/SIGINT instead of exiting abruptly

**What**

The `claude gateway` command now installs signal handlers for SIGTERM and SIGINT (the standard shutdown and interrupt signals). On receiving one, it stops accepting new connections and drains any in-flight requests, waiting up to `CLAUDE_GATEWAY_DRAIN_TIMEOUT_MS` (default 25000ms) plus a 3-second grace buffer before exiting. If a second signal arrives while shutting down, the gateway force-closes and exits immediately.

**Why**

This lets requests already in progress finish cleanly when the gateway is stopped or restarted, instead of being cut off mid-flight, while still allowing an impatient operator to force an immediate exit.

- Area: Gateway
- Names: `CLAUDE_GATEWAY_DRAIN_TIMEOUT_MS`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### MCP HTTP protocol negotiation default flips to enabled via tengu_mcp_protocol_negotiation_http

MCP HTTP servers now default to attempting protocol version auto-negotiation instead of legacy mode

**What**

For MCP (Model Context Protocol) servers connected over HTTP, the connection code now falls back to `{mode: 'auto', probe: ...}` — attempting to negotiate a newer protocol version — unless the `tengu_mcp_protocol_negotiation_http` setting is explicitly turned off. The equivalent settings for the claudeai, stdio, and ccr-proxy transports still default to the older legacy behavior. This release's compiled default for the HTTP setting was flipped from off to on.

**Why**

This moves HTTP-based MCP connections toward attempting the newer protocol handshake by default, while other transport types are unaffected for now and continue to default to the previous legacy connection behavior.

- Flag `tengu_mcp_protocol_negotiation_http`: On for this account, and not off by default (read for one account on one subscription tier against v2.1.274; this account: on, anonymous baseline: on, compiled default: on) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: MCP
- Names: `tengu_mcp_protocol_negotiation_http`
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### MCP SDK generation default flips to v2 via tengu_brindle_causeway

MCP SDK generation gate tengu_brindle_causeway now defaults to on, favoring MCP SDK generation v2 when not set explicitly

**What**

The internal selector that decides which version of the MCP (Model Context Protocol) client SDK to generate now falls back to `v2` when the `tengu_brindle_causeway` setting is at its default, rather than falling back to `v1`. It still uses `v1` if that setting is explicitly turned off. This release's compiled default for the setting was flipped from off to on.

**Why**

For anyone not explicitly setting `MCP_SDK_GENERATION`, this changes which generated SDK version MCP client code is built against by default, once the new default takes effect for an account.

- Flag `tengu_brindle_causeway`: On for this account, and not off by default (read for one account on one subscription tier against v2.1.274; this account: on, anonymous baseline: on, compiled default: on) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: MCP
- Names: `tengu_brindle_causeway`
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### MCP client SDK runtime now defaults to v2, not v1

MCP client runtime's compiled fallback flipped from v1 to v2

**Unclear.** No reading of `tengu_brindle_causeway` has been taken under this release yet, so whether it is switched on for any account in this version isn't known; a prior reading (site account and anonymous baseline) showed it on, but that reading predates this release.

**What**

Claude Code decides which version of its MCP (Model Context Protocol, used to connect external tool servers) client runtime to use, either 'v1' or 'v2', based on the `tengu_brindle_causeway` gate. Previously, that gate's compiled default was false and the code fell back to 'v1' unless the gate resolved true. Now the gate's compiled default is true and the code falls back to 'v2' unless the gate resolves false. The `MCP_SDK_GENERATION` environment variable still overrides the choice either way.

**Why**

This changes which MCP client runtime is used by default when the gate isn't otherwise resolved, shifting the baseline from v1 to v2.

- Flag `tengu_brindle_causeway`: On for this account, and not off by default (read for one account on one subscription tier against v2.1.274; this account: on, anonymous baseline: on, compiled default: on) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: MCP
- Names: `MCP_SDK_GENERATION`
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### tengu_mcp_protocol_negotiation_http fallback flips from legacy to auto-negotiate

MCP servers connected over HTTP now default to trying the newer protocol handshake instead of legacy mode

**What**

When Claude Code connects to an MCP server (an external tool provider) over HTTP, it previously defaulted to using the older, legacy connection handshake unless told otherwise. The fallback default has now flipped: HTTP connections default to automatically probing for the newer MCP protocol-version negotiation instead, unless something explicitly turns that off.

**Why**

This lets HTTP-based MCP connections take advantage of newer protocol capabilities by default rather than always falling back to the older behavior.

- Flag `tengu_mcp_protocol_negotiation_http`: On for this account, and not off by default (read for one account on one subscription tier against v2.1.274; this account: on, anonymous baseline: on, compiled default: on) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: MCP
- Names: `tengu_mcp_protocol_negotiation_http`
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### Artifact create now accepts per-file content type

Artifact file uploads can now specify a content type per file

**What**

When creating or publishing an Artifact or Skill, the `files` list can now specify, for each file, an object with `from` (the source path) and `contentType`, instead of only a plain path string as before.

**Why**

This lets a publish call declare the MIME type of an uploaded file directly, rather than relying entirely on it being inferred, which is useful when the automatic inference from the destination path wouldn't pick the right type.

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

### Enterprise gateway: configurable Postgres connect timeout, retried boot connection, and rate-limit / X-Forwarded-For diagnostics

Enterprise gateway gets a configurable database connect timeout and clearer rate-limit/proxy warnings

**What**

The internal LLM gateway server used in enterprise deployments now supports a `store.connect_timeout_seconds` setting, retries its initial database (Postgres) connection on startup instead of failing outright, and gives a clearer error message naming that setting if the connection still fails.

It also now logs warnings (throttled to once per minute) when:

- Sign-in rate limits are hit (`rate_limits.device_authorization.max`, `rate_limits.device_verify.max`)

- A request arrives with an `X-Forwarded-For` header from a source not listed in `listen.trusted_proxies`

**Why**

These changes make gateway startup more resilient to transient database hiccups and give administrators better diagnostics when authentication limits or proxy configuration issues occur.

- Area: Gateway
- Names: `store.connect_timeout_seconds`
- Tier: Use it now
- Useful: 3/5
- Signal: 1/5

### New connect_timeout_seconds config field for gateway DB pool

Self-hosted gateway's database config adds a connect_timeout_seconds setting

**What**

The configuration schema for the self-hosted gateway's database connection pool gains a new field, `connect_timeout_seconds`. It accepts an integer between 1 and 60, defaulting to 5, and sits alongside the existing `max_connections` setting.

**Why**

This lets operators of a self-hosted gateway tune how long the database pool waits when establishing a connection, instead of relying on a fixed, unconfigurable timeout.

- Area: Gateway
- Names: `connect_timeout_seconds`
- Tier: Use it now
- Useful: 3/5
- Signal: 1/5

### New environment variable CLAUDE_CODE_EMIT_STARTUP_TIMING

A new CLAUDE_CODE_EMIT_STARTUP_TIMING environment variable turns on startup-timing telemetry outside remote sessions

**What**

Startup-timing telemetry, which used to only get collected in remote or CCR mode, now also fires when the new `CLAUDE_CODE_EMIT_STARTUP_TIMING` environment variable is set, even in a regular local session.

**Why**

This lets someone measure Claude Code's startup timing outside of remote sessions, useful for diagnosing slow starts without needing to run remotely.

- Area: Telemetry
- Names: `CLAUDE_CODE_EMIT_STARTUP_TIMING`
- Tier: Use it now
- Useful: 3/5
- Signal: 1/5

### CLAUDE_CODE_FOOTER_INDICATOR env var now overrides settings config directly

CLAUDE_CODE_FOOTER_INDICATOR environment variable now overrides the footer_indicator setting

**What**

The small indicator shown in the status line footer is now controlled first by the `CLAUDE_CODE_FOOTER_INDICATOR` environment variable. If that variable is set, it takes priority; otherwise Claude Code falls back to the `footer_indicator` value in `settings.json` as before.

**Why**

This lets the footer indicator be set per-environment (for example, in a shell profile or CI setup) without editing the settings file.

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

### New OTEL_LOG_MANAGED_SETTINGS telemetry env var

New OTEL_LOG_MANAGED_SETTINGS environment variable added for telemetry configuration

**Unclear.** What effect setting OTEL_LOG_MANAGED_SETTINGS has is not specified beyond it being a recognized telemetry-related variable.

**What**

A new environment variable, `OTEL_LOG_MANAGED_SETTINGS`, has been added to the list of environment variables Claude Code recognizes for OpenTelemetry (OTEL), the system used to export logs and metrics for monitoring.

**Why**

Recognizing this variable name means it can now be used to control whether managed settings are logged as part of telemetry output, though the finding does not specify the exact behavior it triggers.

- Area: Telemetry
- Names: `OTEL_LOG_MANAGED_SETTINGS`
- Tier: Use it now
- Useful: 2/5
- Signal: 1/5

### Startup-failure result payload gated behind CLAUDE_CODE_STARTUP_FAILURE_RESULTS

Startup failures can emit a structured result message when CLAUDE_CODE_STARTUP_FAILURE_RESULTS is set

**What**

When a `stream-json` run fails to start, Claude Code can now emit a `result` message containing `startup_failure_reason` and `result_index`, instead of only writing an error to stderr. This only happens when the `CLAUDE_CODE_STARTUP_FAILURE_RESULTS` environment variable is set and the run uses `--output-format stream-json`.

**Why**

This lets scripts and tools that consume Claude Code's streamed JSON output detect and handle a startup failure as a normal structured message, rather than having to watch stderr separately.

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

### Ultra-review billing confirmation can show a low-credits note

Ultra-review's billing confirmation can now show an added note when your credits are low

**What**

The confirmation prompt shown before running an ultra-review (a deep, cloud-based code review) can now include an extra note about low credits, appended below the standard message stating that the review bills as usage credits. This is controlled by a new `skipLowCreditsNote` option, which can suppress the note when not wanted.

**Why**

This warns you upfront if you're low on credits before committing to a review that consumes them, rather than finding out only after the review runs or fails.

- Area: Elsewhere
- Names: `skipLowCreditsNote`
- Tier: Use it now
- Useful: 2/5
- Signal: 1/5

### Memory-pressure background-shell reaper gets an explanatory user message; feature itself already live

Claude now explains to itself why a background shell was stopped for memory pressure and how to disable it

**What**

By default, on macOS and Linux, Claude Code stops a background shell command that was started in the main session if the operating system signals memory pressure, the session has been idle for 30 minutes, and no turn or subagent is currently running. That behavior already existed; what's new is a message that explains this to the agent when it happens, including how to turn it off by setting `CLAUDE_CODE_DISABLE_BG_SHELL_PRESSURE_REAP`. Windows has no memory-pressure signal, so this has no effect there.

**Why**

Without this explanation, a stopped background command could look like an unexplained failure. Now the agent (and by extension the user) is told directly why it happened and how to disable the behavior if it's unwanted.

- Area: Background Tasks
- Names: `CLAUDE_CODE_DISABLE_BG_SHELL_PRESSURE_REAP`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

## New Features

### New remote control subtype: set_chrome_browser_hints

New remote-control command lets a host set which Chrome device Claude Code's browser tool prefers

**What**

A new remote-control request type, `set_chrome_browser_hints`, lets a connected host or gateway tell the built-in claude-in-chrome MCP server (which lets Claude Code control a Chrome browser) which browser device to prefer on the current machine. The request carries a preferred device ID, a list of locally known device IDs, and the host operating system, and is checked against a schema before being applied. It only takes effect in a remote-hosted session, where it calls `setChromeBrowserHints()` to store the preference for that session only.

**Why**

This helps Claude Code pick the right browser instance when multiple Chrome windows or devices with the extension are connected to the same account, instead of guessing.

- Area: Chrome Control
- Names: `set_chrome_browser_hints`
- Tier: Under the hood
- Useful: 3/5
- Signal: 3/5

### New bridge capability: write files to a remote session channel

Remote worker sessions can now write files back through the bridge, not just read them

**What**

A new function lets a remote 'worker' session write a batch of files (sent as base64-encoded content) back through the API to a bridge/channel endpoint. Previously this bridge could only be used to read files.

**Why**

This lets a remote session push its output files back to the project, rather than only pulling files down, making two-way file exchange possible over the bridge.

- Area: Remote Control
- Tier: Under the hood
- Useful: 3/5
- Signal: 3/5

### New 'x-memory-context-stop' response header controls memory-context shutdown

Server can now tell Claude Code to stop using shared memory context via a new response header

**What**

Claude Code now reads a new `x-memory-context-stop` response header, which can carry the value "org" or "credential". When the server sends this header on certain responses, Claude Code treats it as an instruction to stop using team or shared memory context for the current session, surfaced internally as a `stopped_org` or `stopped_credential` state.

**Why**

This lets the server centrally shut off shared memory context for an organization or a specific credential, for example if access should no longer be granted, without requiring a client update.

- Area: Team Memory
- Names: `x-memory-context-stop`
- Tier: Under the hood
- Useful: 3/5
- Signal: 3/5

### Plugin agents can now load from a hooks-module 'files' map, not just a folder

Plugin agents can now load hooks from a files map, not just a folder

**What**

Plugins that define agents can now supply their hooks module (code that runs around tool or agent actions) in two ways: the existing folder-based layout, or a new files-object keyed by namespace paths. In the new form, each entry is turned into a synthetic `builtin:` file path and parsed individually.

**Why**

This gives plugin authors a second, more flexible way to package hooks without needing a folder structure on disk.

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

## Improvements

### Pasted-content text can be re-tagged with `<pasted_content>` markers before submission

Pasted text in a prompt can now be re-tagged with pasted_content markers before sending

**Unclear.** Nothing has been read about the `tengu_virtual_pancake` gate that controls this, so it's unclear whether or how widely it is enabled.

**What**

Claude Code can now rewrite a prompt before submitting it so that pasted blocks of text (the ones that get substituted in for a placeholder when you paste content) are wrapped in `<pasted_content id="...">` tags. When this happens, the queued message is marked with `pasteTagged: true`.

**Why**

Tagging pasted content this way likely helps distinguish text you pasted from text you typed directly, though the finding doesn't specify what downstream behavior relies on the tag.

- Flag `tengu_virtual_pancake`: Not enough to say (read for one account on one subscription tier against v2.1.274; 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: Paste Handling
- Tier: You'll notice
- Useful: 3/5
- Signal: 3/5

### Team memory multi-store sync: structured basis-load failure reasons and new 'account' scope

Team memory sync adds structured failure reasons for loading its sync baseline, plus a new account-wide memory scope

**Unclear.** Whether the tengu_team_mem_basis_unusable gate is switched on for any account is unread, so nothing can be said about its status.

**What**

Claude Code's team memory feature keeps multiple synced memory stores in agreement using a saved "basis" of prior state. Loading that basis now returns a specific reason when it fails or is unusable, instead of just an empty result: `over_cap`, `absent`, `read_error`, `parse_failed`, `partition_mismatch`, `empty_store`, or `zero_entries`.

Memory sync also gains a new `account` scope, alongside the existing team and user memory mirrors, with its own:

- escape detection and key resolution logic

- handling for a store that returns 404 or fails to list

- settings-path resolution, alongside the existing "user" and default (team) cases

Separately, sync telemetry now distinguishes a push that partially failed because specific files were refused (reason `file_refused`) from a hard failure, account-scope mount directories are created with restrictive file permissions (mode 0700), syncing now skips certain checks and can return early when every store involved is account-scoped, and a `push_tombstones_removed` stat was dropped from the sync summary.

**Why**

The structured failure reasons make it easier to diagnose why a team memory sync basis couldn't be loaded, and the new `account` scope extends memory syncing beyond team and personal mirrors to an account-wide store, with its own safety checks.

- Area: Team Memory
- Tier: Under the hood
- Useful: 3/5
- Signal: 3/5

### Team memory sync: individual files can be "refused" without breaking the whole sync

Team memory sync can now skip an individual refused file without breaking the whole sync, and reports how many files were refused

**Unclear.** Whether the tengu_team_mem_push_delete_deferred or tengu_org_memory_first_write_into_write_home gates are switched on for any account is unread, so nothing can be said about their status.

**What**

When Claude Code pushes team memory files to the server, an individual file can now be "refused" by the server (for reasons in a defined refusal set) without stopping the rest of the sync. A refused file is tracked by its path, content hash, and timestamp, is skipped on retries for a set time window, and the rest of the files continue syncing normally. You're told that the refused file "stays local only, and its changes will be lost when this session's machine is recycled." The final sync result now also reports how many files were refused, as `filesRefused`.

**Why**

This prevents one problematic file from blocking an entire team memory sync, while still making clear which files didn't make it to the server and what happens to them.

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

### Asset reads from artifacts can now hit a public path outside the org

Reading a file from an artifact now supports a public-read path for requesters outside the artifact owner's organization

**What**

When Claude reads an asset (a file) attached to an artifact, it can now go through a distinct 'public read' path used when the requester is outside the artifact owner's organization. The read result carries a new `public_read`/`public` marker, and a dedicated `public_refused` error reason covers the case where a public artifact simply has no matching file for outside readers.

Alongside this, the artifact and frame layer adds a broader `outsideOrg`/`outsideOrgReader`/`publicRead` distinction, with new explanatory text for the case where an artifact is public but belongs to a different organization: it explains the artifact can still be read as data, but the live-subscribe ('watch') feature won't track it. A new error reason also separates 'no file at that path for outside-org readers' from other ordinary 404s.

**Why**

This lets Claude read data from artifacts shared publicly across organizations while being explicit about the limits of that access, particularly that live updates won't be tracked.

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

### Session inbox pointers renotify unfetched bridge attachments when idle

Claude Code can re-notify itself about unread bridge attachments after going idle

**What**

A session's "bridge inbox" — the queue that tracks files or attachments delivered from a connected peer — now re-sends a notification if Claude Code never actually opened (read) a delivered item. This check runs when the session goes idle and rearms, and also from a new callback tied into the run/turn machinery.

When a notification is still unread, the session gets a message telling it to read the item before doing anything else. If it's still unread after that one re-notify, Claude Code gives up and just logs the fact rather than repeating indefinitely.

**Why**

This prevents a delivered file or attachment from being silently dropped if Claude Code missed reading it the first time, while avoiding an infinite notification loop for items that never get read.

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

### WebFetch of artifacts gains a public-read consent path with new gates

WebFetch of artifacts gets a dedicated consent flow for reading artifacts owned by another organization

**What**

The permission check that runs before Claude uses `WebFetch` on an artifact now checks two internal flags, `isFramePublicReadEnabled` and `isFiveClassAsksEnabled`, and adds a new `OUTSIDE_ORG_READ_NOTE` message plus bookkeeping (`notePersonOnlyReadAskPending`) to track pending consent. This changes how Claude Code asks for permission when reading an artifact from someone else's organization, with different wording depending on whether network access is off entirely or the read is specifically flagged as an outside-org read.

**Why**

This gives clearer, more specific prompts when Claude wants to fetch an artifact that belongs to a different organization than the current user's.

- Area: Artifacts
- Tier: Under the hood
- Useful: 2/5
- Signal: 3/5

### Publishing artifacts outside org-consented locations is now explicitly refused

Claude Code now explicitly refuses to publish files or assets to locations an organization hasn't consented to

**What**

When Claude Code tries to write a file or asset to a location outside what an organization has consented to, it now explicitly refuses the action instead of allowing it. The refusal is recorded with a specific reason (`file_outside_org_unasked`, `asset_outside_org_unasked`, or `asset_copy_outside_org_unasked`), and an `artifact_outside_org_consent` telemetry event is emitted.

**Why**

This prevents Claude Code from publishing files or assets outside org-approved locations, closing off a way that output could end up somewhere the organization hasn't agreed to.

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

### Artifact publish flow gets a 'stale version guard' and outside-org publish consent wording

Publishing an artifact now blocks stale versions and gets new consent wording for cross-org publishes

**What**

The logic that decides whether Claude is allowed to publish an artifact now includes a 'stale version guard': it denies the publish (with reason `stale_version_guard` or `stale_version_guard_before_card`) if the current session hasn't recently read or published that artifact. It also adds new consent text for publishing when the artifact belongs to a different organization (`outsideOrg`), and a `readKeepsFlagOffAsk` check that affects whether such a publish can be auto-approved without asking.

**Why**

This prevents Claude from overwriting an artifact with a stale version it hasn't actually seen recently, and makes cross-organization publishing prompts more explicit.

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

### frameTunnel now requires session-jwt auth instead of no auth

Frame tunnel requests now require a session token instead of no authentication at all

**What**

The internal HTTP helper used for 'frame tunnel' requests previously allowed requests to the 'frame' host with no authentication. It now requires a session JWT (a signed session token) instead. Other headers are explicitly stripped from frame tunnel requests, and only the `Authorization` header carrying that session token is reapplied.

**Why**

This closes a gap where frame tunnel requests could go out unauthenticated, requiring a valid session token instead.

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

### Large expansion of typed API error kinds (is_api_error_message schema)

Around 20 new structured API error types were added so tools can react to specific failure causes

**What**

The schema for typed API errors gained roughly 20 new specific error kinds, including:

- `effort_requires_thinking`

- `advisor_incompatible`

- `tool_history_mismatch`

- `autocompact_thrashing`

- `pdf_too_large` and `pdf_password_protected`

- `no_response`

- `tls_untrusted_ca`

- `gateway_content_type`, `gateway_signin_required`, and `gateway_session_expired`

- `provider_credentials`, `api_key_auth_disabled`, `org_disabled_credential`, and `invalid_credential_header`

- `model_requires_usage_credits` and `long_context_credits_required`

- `consent_unanswered`

- `no_allowed_fallback` and `model_substitution_disabled`

- `field_not_granted`

Two new companion fields, `api_error_params` (carrying effort/provider/remedy details) and `api_error_code` (a passthrough of the server's own error code), were also added.

**Why**

This lets Claude Code and anything built on it detect the specific cause of an API failure directly from structured data, instead of having to parse the error message text.

- Area: API Errors
- Tier: Under the hood
- Useful: 3/5
- Signal: 2/5

### Artifact publish flow gained a deceptive/unexaminable content guard

Publishing artifact files now forces a person-only confirmation when a copied file's read permission was judged deceptive or unexaminable

**What**

When Claude Code publishes or copies files as part of an artifact, it now checks the read-permission decision made for each file. If any file was flagged as "deceptive" or "unexaminable", and the request is happening in plan mode, through a served call, or with redirected roots, the confirmation for that publish is forced to require approval from an actual person rather than something a hook or another agent could silently approve on the user's behalf.

**Why**

This closes a gap where a suspicious or unreadable file could be published as part of an artifact without a human actually looking at it, ensuring risky publishes always get a genuine human check.

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

### New guard against permission hooks silently approving foreign-artifact reads

New messaging explains exactly why a foreign-org artifact read was blocked, including when a PermissionRequest hook auto-answered instead of the user

**What**

When Claude Code blocks reading or copying an artifact that belongs to a different organization, it now gives the model one of three specific explanations:

- nobody was asked for permission, so retrying may help

- nobody can be asked in this session, so it shouldn't retry

- a `PermissionRequest` hook (a script that can answer permission prompts automatically) answered on the user's behalf, in which case the model is told that only the user's own approval allows the read, and to tell the user that their hook auto-answered

**Why**

This stops a `PermissionRequest` hook from silently standing in for the user on a sensitive cross-organization read, and makes sure the user finds out when their own automation made that call instead of them.

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

### Local background shell tasks: memory-pressure reap now checks actual host memory scarcity

Background bash tasks are now only killed for memory pressure after checking actual available system memory, with more reasons to skip the reap

**What**

When a memory-pressure event fires, Claude Code used to reap (kill) background bash tasks almost unconditionally, aside from a few checks. Now it first checks actual host memory scarcity by reading `/proc/meminfo` on Linux and WSL, comparing available memory against both a percentage and an absolute gigabyte floor, before killing anything. It also now skips reaping when a turn is currently running, when delegated agents are running, or when the session was recently reaped, and logs the reason a reap was skipped without duplicating the log entry.

**Why**

This prevents background tasks from being killed unnecessarily when memory pressure is reported but the system isn't actually short on memory, and avoids interrupting work that's actively in progress.

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

### Rewind now heals subagents and can self-repair a failed persist

Rewinding a conversation now stops orphaned subagents and can self-repair if saving the rewound state fails

**What**

New rewind machinery persists a rewound conversation's state, and if that save fails, it now walks backward to find the last user or assistant message and retries mirroring it up to 3 times to bring the local and remote state back into sync, or "heal" it. A companion function also walks the list of currently running subagents, whether teammates or in-process tasks, and when a rewind cuts past the point where one of those subagents was spawned, that subagent is now stopped instead of being left running orphaned.

**Why**

This makes rewinding a conversation more reliable: a failed save no longer leaves the conversation state out of sync, and rewinding past where a subagent was started no longer leaves that subagent running unattended.

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

### Artifact watch/subscribe no longer starts a turn on republish — it silently tracks versions and warns on next read

Republishing a watched artifact no longer wakes the session with a new turn; the next read or publish gets a warning to re-fetch and merge instead

**What**

The artifact "watch" feature was reworked. Publishing or watching an artifact no longer says the session will be woken up with a new turn or a notification when someone else republishes it elsewhere. Instead, Claude Code silently keeps track of the artifact's version in the background, and the next time the artifact is read or a publish is attempted, that attempt gets an injected warning telling Claude to re-fetch the artifact and merge its edits before publishing.

**Why**

This changes how watching an artifact behaves: instead of interrupting a session with a live notification, it now waits until the artifact is actually touched again and warns at that point, so edits based on stale versions get caught before being published.

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

### New file-path safety annotations warn about symlinks, hardlinks, and out-of-tree paths

New warnings flag file paths that are symlinks, hardlinks, or outside the session's working directories

**What**

New helper functions inspect a file path and add bracketed warnings when the file is a symbolic link, when the path resolves somewhere else, when the file is hard-linked, meaning edits to it may affect other paths that share the same underlying data, or when the path is outside the session's working directories or in the uploads folder. These appear designed to annotate the inputs or outputs of file tools like Read, Write, and Edit with these warnings.

**Why**

This helps catch cases where a file path isn't what it appears to be, such as a symlink pointing elsewhere or a hardlinked file whose edits ripple to other locations, before a tool acts on it.

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

### Chrome-bridge browser picker gets explicit selection prompts and telemetry

Chrome bridge now always asks which connected browser to use, and logs the choice

**What**

When Claude Code's Chrome bridge (its connection to a browser) needs to take a browser action and it's ambiguous which browser to use, two new prompt-builder functions now instruct the model to always ask the user to pick among every connected browser, plus an option to switch to a different browser, before proceeding. The model does this by calling `select_browser` or `switch_browser` as appropriate. A new `reportBrowserSelected` method also emits a `chrome_bridge_browser_selected` telemetry event recording the outcome, the number of connected browsers, and the number of local browsers.

**Why**

This avoids Claude Code guessing which browser to control when more than one is available, making browser actions more predictable and giving the user explicit control over which browser is used.

- Area: Chrome Control
- Names: `select_browser`, `switch_browser`
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### System-prompt hot-swap now takes effect from the next turn, not at next compaction

Swapping the system prompt mid-session now applies from the next turn instead of waiting for compaction

**What**

When Claude Code's internal system prompt is replaced mid-session, the new prompt text now takes effect starting from the very next turn. Tool definitions already sent to the model in that session stay unchanged. Previously, the new prompt only took effect at the next compaction (the point where conversation history gets condensed), unless a `systemPromptSnapshot` setting was turned off.

**Why**

This makes system-prompt changes apply sooner and more predictably, rather than sitting unused until the next compaction happens to occur.

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

### New memory-store rejection reasons: content_screened and index_too_large

Claude Code now explains two new reasons memory writes can be rejected: content screening and an oversized index file

**What**

When Claude Code tries to save something to its memory store and the server rejects it, two new rejection reasons now come with user-facing explanations:

- `content_screened`: the write failed a safety screening, without specifying which part of the content triggered it

- A size-cap rejection for the memory index file (`MEMORY.md`), which has a much smaller size limit than the cap applied to individual memory files

**Why**

This gives clearer feedback when a memory write fails, so you know whether it was blocked for safety reasons or because the index file grew past its (smaller) limit, rather than seeing an unexplained failure.

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

### MCP inference-token refresh rewritten with jittered backoff, TTL tracking, and proactive refresh-on-401/403

Self-hosted runner's automatic MCP inference-token refresh gets smarter retry timing and can now refresh immediately on a 401/403 error

**What**

The self-hosted runner's mechanism for automatically refreshing its MCP (Model Context Protocol) inference token has been substantially reworked:

- it now tracks how long a token is valid for (a TTL, defaulting to 30 minutes) and refreshes proactively before expiry

- retries after a failed refresh now use exponential backoff with random jitter (increasing delays with some randomness added, to avoid repeated retries all colliding)

- tokens close to expiring get a separate, shorter retry window

- a new classifier distinguishes network/transient errors from more permanent ones, such as a new `RemoteConfigWithoutInferenceAuthError` or a 401/403 response, which are treated as not worth retrying quickly

- a new `onResultApiError` callback lets a 401 or 403 error returned by the model API during a child task's turn trigger an immediate, out-of-band token refresh

**Why**

This makes long-running self-hosted sessions more resilient: tokens are refreshed ahead of expiring rather than only after they fail, retries back off sensibly instead of hammering the server, and an authorization error during a task can trigger an immediate fix instead of waiting for the next scheduled refresh.

- Area: Self-Hosted Runner
- Tier: Under the hood
- Useful: 3/5
- Signal: 2/5

### MCP auth-error classification reworked to add a 403 'step-up' (insufficient scope) case

MCP auth errors now distinguish an expired token from a 403 requiring extra OAuth permission ('step-up')

**What**

When an MCP (Model Context Protocol) tool call fails authentication, Claude Code now classifies the failure more precisely with a new classifier. A 403 error that carries a pending 'step-up scope' (a signal that additional OAuth permission is needed) is now recognized as its own case, `step_up`, requiring re-authentication for extra access. Previously this was lumped together with the generic case of a rejected or expired token (`credential_rejected`).

**Why**

Distinguishing an outright rejected credential from one that just needs a broader permission scope means the right kind of re-authentication can be prompted, instead of treating both as the same failure.

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

### Public artifacts from another org are now hard-blocked

Public artifacts belonging to a different organization are now completely blocked from being read or written

**Unclear.** Whether tengu_cobalt_plinth_sedge governs this specific behavior isn't stated, and no reading of it has been taken under this release.

**What**

Artifacts (shareable pieces of content or apps Claude can create) that are public but belong to a different organization than the current login are now hard-blocked: any attempt to read or write such an artifact is denied outright, with a message explaining that its endpoints and database aren't reachable from the current login and there's nothing to retry.

**Why**

This closes off a path where a session could otherwise interact with a public artifact that belongs to someone else's organization, keeping artifact access scoped to the user's own organization.

- Flag `tengu_cobalt_plinth_sedge`: Off by default, switched on for this account (read for one account on one subscription tier against v2.1.274; 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: 3/5
- Signal: 2/5

### Artifact database read/write approvals now depend on plan mode, served calls, and batch size, not a blanket rule

Approval rules for artifact database reads and writes now depend on plan mode, batch size, and whether the call runs in the background

**What**

Permission checks for the artifact database's `read_db` and `write_db` actions no longer apply a blanket rule requiring human approval. Instead, whether approval is needed is now computed based on several factors:

- whether the call is a served or background call

- whether it's a multi-entry batch operation

- the current permission mode (such as plan mode)

**Why**

This replaces a one-size-fits-all approval requirement with more nuanced rules, so lower-risk database operations (for example, background or batched calls in certain modes) can proceed without requiring a human to approve each one, while other cases still do.

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

### Artifact asset-delete and type-create approvals now vary by plan mode/served-call instead of always requiring a human

Some artifact actions no longer always require a human to approve them

**What**

For several artifact actions (deleting an asset, creating an artifact from a type, and publishing), Claude Code previously always required a human to approve the action before it could run. Now that requirement is computed based on context instead: what plan mode is active, whether the call was already served, and whether the artifact is already owned or consented to.

**Why**

This means some of these actions can now be approved automatically in certain situations, rather than always stopping to ask a person, while still requiring human approval in others depending on context.

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

### Chrome extension multi-browser selection reworked with 'browser hints'

Choosing among multiple connected Chrome extensions is now smarter and groups them by location

**What**

When more than one Chrome browser extension is connected to Claude Code, a new selection process now automatically picks the right one when possible: a previously remembered device, the only extension available, or the single local candidate when hint data confirms it's the only one actively running on this computer. When it can't decide automatically, it now asks the user to choose, presenting the options in two groups: "Browsers on this computer" and "Other connected browsers."

**Why**

This reduces unnecessary prompts when the right browser extension is obvious, and makes the manual choice clearer when it isn't, by separating local browsers from remote ones.

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

### Public artifact page reads now require explicit caller approval

Fetching a public artifact's page from outside your organization now requires explicit caller approval, and is refused by default

**What**

When Claude Code goes to read the HTML page of a public artifact that belongs to an organization other than your own, it now requires an explicit approval check (`admitPublicRead`) before fetching it. By default this check refuses the read. Only calls that pass an approval the user granted are allowed through; anything else fails with a dedicated error instead of silently being fetched.

**Why**

This closes off a path where a public artifact's page could be fetched without the user having actually approved that read, making it clearer when and why an external page is being pulled in.

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

### Worktree state now tracks unverified/uncommitted submodule work

Git worktree cleanup now checks for unverified or uncommitted submodule changes before removing

**What**

Claude Code's git worktree (an isolated working copy of a repository) safety checks now understand submodules (repositories nested inside another repository). A new helper computes each submodule's status, and:

- Worktree removal now refuses to proceed, with an explicit message, if submodule work can't be verified or has changes

- Dirty-state reporting now includes a `submodules_unverified` field

- The background-agent worktree deletion flow threads this submodule status through to the notice shown when a worktree is kept instead of deleted

**Why**

This prevents Claude Code from silently deleting a worktree that has uncommitted or unverifiable work sitting inside a submodule, which previously could have been lost without warning.

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

### Gerrit-aware push tracking in git command detection

Claude Code now recognizes Gerrit pushes separately from GitHub-style pushes

**What**

When Claude Code watches the output of a `git push` command, it can now tell whether the destination is a Gerrit remote (a code-review system some teams use instead of GitHub pull requests) rather than a GitHub-style provider. Gerrit pushes are now routed through a different notification path than the one used for pull-request pushes.

**Why**

Gerrit pushes don't create pull requests the way GitHub does, so treating them the same way would produce misleading or missing notifications. This lets Claude Code give Gerrit users appropriate feedback after a push.

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

### Headless/stream-json errors gain a structured startupFailureReason field

Headless mode's startup-failure errors now include a structured reason code

**What**

When Claude Code fails to start in headless mode (running without an interactive interface, using stream-json output), the error-reporting helper now accepts a `startupFailureReason` and a `resultIndex`, and includes both in the emitted stream-json error object. One concrete reason value is `session_held_by_background`, used when a session is already held by a background process.

**Why**

This gives tools and scripts consuming stream-json output a structured way to detect and handle specific headless startup failures, such as a session being locked by another background process, instead of just seeing a generic error.

- Area: Headless Mode
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### CLI-too-old failure now emits structured JSON in stream-json/SDK mode

Version-mismatch startup failures now return structured JSON for SDK-driven sessions

**What**

When Claude Code's CLI is too old to talk to a newer workspace or server, and it's running with `--output-format stream-json` plus `CLAUDE_CODE_STARTUP_FAILURE_RESULTS` set, the version-mismatch failure is now emitted as a structured JSON result object with `startup_failure_reason: 'cli_version_too_old'`, instead of only printing a human-readable error to the console before exiting.

**Why**

Tools and SDKs that drive Claude Code programmatically can now detect and handle this specific failure reason directly from the output stream, rather than having to parse plain-text error messages.

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

### Startup failures now reported to stdout as an SDK stream-json result message

Startup failures now emit a structured JSON result line for SDK callers

**What**

When Claude Code is run with `--output-format stream-json` and a `--session-id`, certain startup failures — such as an invalid proxy configuration (`proxy_invalid`) or a missing shell tool (`shell_tool_missing`) — now produce a structured JSON result line on stdout, in addition to the existing stderr text.

**Why**

This gives programmatic and SDK callers a reliable, structured way to detect and handle specific startup failures, rather than having to parse stderr text.

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

### Policy-helper (managed settings) refresh now tracks failure identity and announces tier changes

Claude Code now tracks the specific failure reason when its managed-settings helper repeatedly fails, and announces tier changes when that reason changes

**What**

Claude Code can be configured through a remote "policy helper" that fetches managed settings from an organization. When that helper keeps failing and Claude Code falls back to static default settings, it now remembers the specific failure code from last time. If the new failure differs from the last one seen, it records the change and announces a tier change.

Internally, the tracking state for this process also now keeps a record of which settings entry was selected and what the last failure was, and both are reset when settings are applied or the process is retired.

**Why**

This gives clearer diagnostics for why managed settings were or weren't applied, and ensures a change in failure type is properly surfaced rather than silently repeated.

- Area: Managed Settings
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Agent proxy can install its CA into the system trust store 'directly' via a new anchor/layout path, not just via a refresh helper

Claude Code's local proxy can now install its security certificate into the system trust store directly, not just via a refresh helper

**What**

Claude Code runs a local agent proxy that needs its certificate authority (CA) trusted by the system so it can inspect secure connections. Installing that certificate into the system trust store now tries a new 'direct' method first, writing the certificate to an anchor location, before falling back to the previous approach of refreshing it through a helper command. Diagnostic telemetry now records which method succeeded (`direct` or `refresh`) and gives more detailed failure reasons, such as `direct_failed_step`, `direct_skipped`, and `hook_incomplete`.

**Why**

A more direct installation path can make trusting the proxy's certificate more reliable, and the added detail makes it easier to see why installation failed when it does.

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

### Self-hosted runner now surfaces API error status codes from turn results

Self-hosted runner sessions now surface the API's numeric error status code when a turn fails

**What**

In the self-hosted runner (used when running Claude Code sessions on your own infrastructure), when a turn result comes back marked as an error and includes a numeric API error status code, a new callback is now invoked with that status code.

**Why**

This lets self-hosted runner integrations react to the specific API error status code behind a failed turn, rather than only knowing that a turn failed.

- Area: Self-Hosted Runner
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Marketplace refresh: keep-on-failure fallback now scoped to genuinely unreachable remotes

Marketplace refresh only keeps a stale local copy on failure when the remote is genuinely unreachable, not on every pull failure

**What**

When Claude Code refreshes a plugin marketplace, it now classifies the result of checking the remote as `current`, `unreachable`, or `stale` using a new helper. The `CLAUDE_CODE_PLUGIN_KEEP_MARKETPLACE_ON_FAILURE` environment variable, which keeps the existing local copy instead of failing, is now only consulted in the `unreachable` case, and only if the existing local clone still validates as a real marketplace. Previously it applied to any pull failure.

**Why**

This narrows the keep-on-failure fallback to cases where the remote is actually unreachable, rather than masking other kinds of pull failures by silently keeping a possibly outdated local marketplace copy.

- Area: Plugin Marketplace
- Names: `CLAUDE_CODE_PLUGIN_KEEP_MARKETPLACE_ON_FAILURE`
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### API error responses now carry a machine-readable `apiError` code

API error responses now include a machine-readable error code alongside the message

**What**

Many error responses from the API now carry a structured `apiError` code (and sometimes `apiErrorParams`) in addition to the plain-text message shown to you. This covers cases like tool-use concurrency conflicts, duplicate or orphaned tool_use IDs, requesting reasoning effort without thinking enabled, using an incompatible advisor model, disabled API-key authentication, and credential failures with cloud providers (Bedrock, Vertex, Foundry), which now also include a `remedy` suggestion.

**Why**

A machine-readable error code lets tooling and integrations detect and handle specific failure cases programmatically, rather than having to parse human-readable text.

- Area: API Errors
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Published-artifact tool description now scans referenced files for links and reports coverage

Artifact tool's action summary now scans referenced files for links and reports coverage

**What

When an artifact is created or updated, the human-readable summary of that action now scans each referenced or attached file for links, when a root path is available, and appends notes such as `[file N: ...]` or `[N listed file(s): ...]`. If some files were skipped because of scan limits, it now shows a count like `(K not examined for links)`. Large file lists are also now paginated differently, and base-path/root link information is included.

**Why

This gives you more visibility into what links were found (or missed) across the files involved in an artifact action, making it clearer when a summary is incomplete due to scan limits.

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

### Artifact file lists can now be read for public artifacts by non-org readers

Public artifacts' file lists can now be read by people outside the owning organization, with clearer errors when they can't

**What**

When fetching the list of files inside an artifact (a piece of code or content Claude generates and shares), Claude Code now handles public artifacts differently:

- If the artifact is publicly readable and the server declines to list files, the error now distinguishes a 'single_page' artifact (one with no separate file list) from a genuine refusal, where files simply aren't available to readers outside the artifact's organization

- Successful file-list results for public artifacts now carry additional fields marking them as public and possibly narrowed in scope

- A separate, distinct message now appears when a cloud-session artifact mount can't serve a specific file to an outside-org reader viewing a public artifact, rather than the generic 'no file published' message

**Why**

This makes it clearer to someone outside an artifact's organization why a file listing or file fetch failed, rather than lumping every failure into one vague error.

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

### Pane teammates can't run plugin-registered agent types

Subagents from plugin-registered agent types can no longer be spawned as pane-based teammates

**What**

When Claude Code tries to spawn a subagent as a pane-based teammate (a teammate running in its own terminal pane), it now checks whether the requested agent type was registered at runtime by a plugin. If so, it refuses and throws an error instead of trying to open a pane, telling you to spawn that agent with a different tool or to use an in-process teammate instead.

**Why**

This prevents a broken or unsupported launch attempt for plugin-registered agent types in pane mode, and points you toward the alternatives that do work: another spawning tool or in-process teammates.

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

### Runtime-registered plugin agents get merged into the active agent list

Agent types that plugins register while running now show up alongside built-in and file-based agents

**What**

Claude Code now merges agents that a plugin registers at runtime into the list of agents available for a session. These runtime-registered agents are tagged with `source: "plugin"` and `registeredAtRunTime: true`, and get added alongside the built-in agents and the agents discovered from files.

**Why**

This lets plugins add new agent types while Claude Code is running, and have them actually appear as usable agents in the session rather than being ignored.

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

### Retryable-error classifier reworked and widened

More API error codes are now treated as retryable instead of fatal

**What**

The logic that decides whether an API error should be retried rather than treated as fatal now treats any error in the 4xx range as retryable, except for 401 (unauthorized), 403 (forbidden), and 429 (rate limited). Previously only the specific codes 400, 404, and 405 were treated this way. The check also now reads the error's text body using a different helper function.

**Why**

This means more kinds of client-side errors from the API will be retried automatically instead of immediately surfacing as a failure, which should reduce the number of errors that interrupt a session unnecessarily.

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

### Explore agent no longer inherits model cap on non-first-party providers

The Explore agent no longer has its model capped when using non-Anthropic API providers

**What**

The built-in Explore agent (used for fast, read-only code searches) has logic that decides whether to cap which model it can use, or let it inherit the same model as the main session. That logic now immediately returns "inherit" (no cap) whenever the active authentication provider is not Anthropic's own first-party API, before even checking the `CLAUDE_CODE_DISABLE_EXPLORE_INHERIT_CAP` environment variable.

**Why**

Users connecting through a non-Anthropic provider will have the Explore agent run on the same model as the rest of the session, rather than being capped to a smaller model, regardless of that environment variable's setting.

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

### New managed-settings validation failure reasons

Org login and managed-settings failures now carry a machine-readable reason code alongside the existing policyUnreadable flag

**What**

`policyUnreadable`, which already signals that managed policy settings exist but can't be read, now appears together with a new machine-readable `reason` field on org login and managed-settings validation failures. Example reasons include `managed_settings_invalid` and `org_pin_api_key_conflict`, alongside the existing human-readable message.

**Why**

This gives more specific, code-checkable reasons for why an org login or settings validation failed, instead of just a flag and free-text message.

- Area: Managed Settings
- Names: `managed_settings_invalid`, `org_pin_api_key_conflict`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Plugin skill search gated behind HIPAA policy

Plugin and skill search is now gated by a HIPAA-specific policy check that denies it outright under HIPAA mode

**What**

A new capability check, `allow_plugin_skill_search`, controls whether plugin and skill search is available. It is explicitly denied under HIPAA, an org policy mode for healthcare-regulated accounts. The underlying check also denies search when the feature is explicitly turned off by the organization, when it's latched to a previous decision, when it's unregistered, or when HIPAA mode is on; otherwise it falls back to a normal read/eligibility check.

**Why**

This adds an explicit compliance gate so accounts under HIPAA policy cannot have Claude Code perform plugin or skill search, on top of the scope and policy checks already in place around search.

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

### Task notification coalescing added to print/headless mode

Background task completion notifications in print/headless mode can now be batched instead of shown one by one

**Unclear.** Whether and how the coalescing actually changes visible output in print/headless mode is not confirmed, only that the supporting code and telemetry event were added.

**What**

A new telemetry event, `print_task_notification_coalesce`, and related internal state (`heldCompletionChars`, `heldCompletionWorkload`) were added to the code that handles turns in print mode, Claude Code's non-interactive/headless mode. This suggests that notifications about completed background tasks can now be grouped together rather than emitted one at a time.

**Why**

Batching notifications this way could reduce noisy, repeated output when several background tasks finish close together in headless runs, though the exact user-visible effect is not confirmed by the evidence.

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

### Tool-result pairing repair now detects and reports 'misplaced' tool results

Tool-result repair now detects and reports 'misplaced' tool results in debug output

**What**

The internal pass that repairs mismatched tool calls and their results now includes a check for tool results that are "misplaced." When this happens, the debug information generated (both in telemetry and in the strict-mode error message) now includes a `misplaced_tool_results=[...]` list for each affected assistant message.

**Why**

This gives more detail when diagnosing cases where a tool's result got separated from or mismatched with its originating call, making it easier to understand what went wrong in a conversation's transcript.

- Area: Tool Use
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Artifact create-from-type: server can reject a client-supplied request_id and get a retry without it

Artifact creation retries automatically if the server rejects its request_id

**What**

When Claude Code creates an artifact from a type, it now attaches a `request_id` to the create request. If the server responds with a 400 error specifically rejecting that `request_id` field, Claude Code strips it and retries the creation once automatically, logging a `request_id_rejected` telemetry event. The result of a successful create can also now include a `provisioned` object.

**Why**

This means an artifact creation that would otherwise fail outright because of a rejected `request_id` now has a chance to succeed on retry, without the user seeing an error.

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

### Artifact 'live' republish tracking replaces reactive notice with passive version-heard tracking

Artifact republish tracking switches from a one-time notice to ongoing passive version tracking

**What**

Claude Code now tracks, per artifact, the newest version it has "heard" about versus the version the current session has itself published, to work out whether a locally held copy is behind. The message shown for this used to say only that Claude would be notified when the artifact is republished; it can now instead say Claude will keep track of new versions of the artifact published elsewhere.

**Why**

This moves from a single reactive notification to ongoing passive tracking of an artifact's version history, so Claude Code can tell when a live artifact has fallen behind a version published elsewhere.

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

### New structured `apiError` codes attached to rate-limit/format error responses

API error responses now carry structured error codes like pdf_too_large alongside plain-text messages

**What**

When the API returns a rate-limit or invalid-request error, Claude Code now attaches a structured `apiError` code identifying the specific cause, in addition to the existing free-text error message. New codes include:

- `model_requires_usage_credits`

- `long_context_credits_required`

- `pdf_too_large`

- `pdf_password_protected`

**Why**

Structured error codes let Claude Code (and anything reading these errors) distinguish specific failure causes, such as an oversized or password-protected PDF, rather than relying only on parsing a text message.

- Area: API Errors
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Typed API-error kinds for gateway/provider/TLS failures

API errors now get specific codes for gateway, provider, and TLS certificate failures instead of a generic message

**What**

The general API error handler now recognizes and labels more specific failure types instead of falling back to a generic "server error" message. New structured error codes include:

- `no_response`

- `tls_untrusted_ca` (an untrusted TLS/HTTPS certificate)

- `gateway_content_type` (a Bedrock proxy rewriting the streamed response incorrectly)

- `provider_credentials` (with a remedy pointing to a host-managed fix)

- `gateway_signin_required` and `gateway_session_expired` (with a remedy pointing to refreshing a gateway token when it came from the environment)

**Why**

These give more precise, machine-readable causes for connection and authentication failures that go through a gateway or custom provider setup, instead of a generic unexplained error.

- Area: API Errors
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Artifact 'copy_from' action gated behind a frozen/combined feature check

Artifact copy_from now also requires a combined feature check, or it fails outright

**Unclear.** What the two underlying checks (Qst and pme) actually gate is not stated.

**What**

The `copy_from` action, which copies assets (like files or images) directly between artifacts on the server, now requires two internal feature checks to both pass before it can run. If either check fails, the action is refused with an explicit message saying it is not enabled for the account, instead of running or falling back to the older permission-rule checks alone.

**Why**

This adds another gate on top of the deny/ask permission-rule checks introduced previously, so `copy_from` can be turned off for an account independently of those rules.

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

### Public-artifact live-subscribe now stops on org mismatch / not-found / public-outside-org, and boots the watch during subscribe

Live-subscribing to a public artifact now stops cleanly on org mismatch, not-found, or public-outside-org cases

**What**

The internal helper that live-subscribes to a public artifact now starts the artifact's watch (tracking for new versions) as part of subscribing, via a `watchBoot` setting. It also now recognizes three failure cases instead of two: `public_outside_org`, `not_found`, and `other_org`. In each case it stops any running task tied to that artifact and reports a `read_stopped_...` telemetry event along with advice text.

**Why**

This makes live-subscribing to a public artifact more robust: if the artifact turns out to belong to a different organization, doesn't exist, or is public but outside the current organization, Claude Code now stops cleanly and gives context about why, instead of the earlier handling that only covered two of these cases.

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

### Reading public artifacts from outside your org now goes through a consent check instead of a flat block

Reading files from public, out-of-org artifacts now goes through a consent check instead of being flatly blocked

**What**

Previously, reading any file from a public artifact created outside your organization was always blocked with a fixed message. Now the artifact tool distinguishes between cases:

- if the file is a "public file," it responds that the bytes aren't returned inline, but says a tool can be used to save it to disk instead

- if no one could be asked for consent ("public unasked"), it returns a specific explanation and logs a telemetry event marking the request as refused

A new `admitPublicRead` check is now wired into `list_files`, `read_file` (both single and batch), and general `read` actions on the Artifact tool. It consults whether the artifact or session was already granted access, whether the turn was started by a human, and the current mode (such as plan mode). Results that aren't fully admitted are tagged `public_read` and, where relevant, narrowed rather than returned in full.

**Why**

This replaces an all-or-nothing block with a more nuanced consent-aware system, allowing legitimate access to public artifact files (such as saving them to disk) while still refusing and logging cases where consent can't be established.

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

### Artifacts file listing can now report a narrowed (partial) file set for outside readers

Artifacts file listings can now be flagged as a narrowed, partial view for outside readers

**What**

When the Artifacts tool lists files, results can now carry a `narrowed` flag. When set, Claude is told that the listing shown is only the published subset that an outside reader can see, and that some files may be left out.

**Why**

This prevents Claude from assuming a file listing is complete when it's actually been filtered down to what an outside viewer is permitted to see.

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

### Prompt-suggestion generation can now reuse a precomputed 'turn brief' instead of a fresh model call

Prompt suggestions can now reuse a precomputed 'turn brief' instead of always making a fresh model call

**What**

When generating a suggested next prompt in SDK or print mode, Claude Code now first checks for a precomputed 'turn brief' - a short summary produced as part of a turn's post-turn classification. If that precomputed brief matches the current turn, it's used directly as the suggestion instead of triggering a new generation request to the model.

**Why**

This can make prompt suggestions appear faster and avoids an extra model call when a suitable summary is already available.

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

### Public-artifact roster gate: 'no person has approved reading it here'

New check refuses to fetch a public artifact from outside your org unless someone has approved it

**What**

New internal logic reads a cached, account- and organization-scoped list of approved public artifacts (a 'roster'). When fetching a public artifact from outside the user's organization and nobody has approved doing so, the request is refused with a specific message for that case.

**Why**

This adds a guard against pulling in public artifacts from outside your organization without explicit approval, reducing the chance of unapproved external content being fetched automatically.

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

### MCP OAuth "step-up" scope re-authorization is fully wired

MCP tool calls that need extra permission scope now prompt for a specific re-authorization instead of a generic message

**What

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

### Self-hosted-runner inference token refresh now retries proactively and on-demand

Self-hosted-runner inference tokens now refresh with backoff/jitter and can be refreshed immediately after an auth error

**What**

Self-hosted runners (machines you provide to run Claude Code's automated tasks outside Anthropic's own infrastructure) previously refreshed their inference tokens on a fixed schedule. That has been replaced with a more flexible refresh helper that uses exponential backoff (waiting progressively longer between retries), jitter (small random delays to avoid retry storms), a margin before expiry, and an on-demand 'refresh now' option.

This is wired so that if a runner's turn ends with an HTTP 401 or 403 error (authentication failures) from the model API, it immediately requests a fresh `inference_token` from CCR instead of waiting for the next scheduled refresh.

**Why**

This reduces downtime for self-hosted runners: instead of sitting on an expired or rejected token until the next scheduled refresh, a runner can recover right away after an auth failure.

- Area: Self-Hosted Runner
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Ultrareview shows remaining usage credits before running

Ultrareview now warns how much usage credit you have left before it runs

**What**

Before running an ultrareview (a deep, multi-agent code review), Claude Code now checks your remaining usage credits and, when they're getting low, shows a line like "About $X of usage credits left. A review usually uses about $Y and stops if credits run out," or "Less than $1 of usage credits left..." if you're nearly out.

**Why**

Ultrareview can use a meaningful chunk of usage credits, so this warns you up front instead of letting a review stop partway through because it ran out of budget.

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

### Quickstart flow gains a real 'document' Artifact type path

Artifact quickstart for 'document' now looks up a real matching document type

**What**

When the Artifact tool's quickstart flow handles a request for a 'document', it now goes through the same type-lookup process already used for 'slides' and 'design': it looks up a matching artifact type, lists candidates if the request is ambiguous, and handles the case where no type catalog is available. Previously, 'document' requests were hard-coded to always fall back to a first-party Docs connector or a generic quickstart.

**Why**

This makes document quickstarts behave consistently with slides and design, correctly picking a specific document type when one is available instead of always falling back to a generic path.

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

### MCP tool call reauth: new step-up scope handling for insufficient_scope 403s

MCP tool calls now show a specific re-authenticate message when a server needs extra permissions

**What**

When a connected MCP server (a Model Context Protocol server, an external tool provider) rejects a tool call with an "insufficient scope" error (a 403 response meaning your current permissions aren't enough), Claude Code now recognizes this as a distinct case rather than lumping it in with an expired or rejected credential. It shows a specific message naming the server and the missing permission scope, and tells you to run `/mcp` to re-authenticate.

**Why**

Previously any 401/403 from an MCP server was treated as a generic expired-credential problem. Now you get a clearer signal when the real issue is that your existing login lacks a specific permission, so you know to re-authenticate for additional access rather than just retry.

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

### Markdown links with unexpected URL schemes get 'defanged' in the terminal renderer

Markdown links using unrecognized URL schemes now render as plain text instead of clickable terminal links

**What**

When Claude Code renders markdown in the terminal, links are now checked against an allow-list of URL schemes (like `http` or `https`). Any link using a scheme not on that list — including links found inside tables and lists — gets marked as 'defanged,' meaning it's displayed as plain, non-interactive text instead of a clickable terminal hyperlink.

**Why**

This prevents potentially unexpected or unsafe URL schemes from being turned into clickable links in the terminal, reducing the risk of a malicious or unusual link being accidentally activated.

- Area: Terminal UI Security
- Tier: You'll notice
- Useful: 3/5
- Signal: 1/5

### Bash parameter-expansion safety checks tightened, gated by tengu_shimmying_mochi

Claude Code's bash-safety checker now rejects more risky variable-expansion patterns

**What**

The analyzer that judges whether a shell command's variable expansions are safe or need extra scrutiny now refuses two more patterns: `${!...}` forms used for name-listing or positional parameters, and `${ |...}` patterns. It also added a stricter "canonical form" check, requiring that the parsed pieces of an expansion reconstruct the original text exactly before it's treated as safe.

**Why**

This tightens the safety checks Claude Code runs on bash commands before executing them, catching more shell syntax that could behave unexpectedly.

- Flag `tengu_shimmying_mochi`: Not enough to say (read for one account on one subscription tier against v2.1.274; 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: Bash Safety
- Names: `tengu_shimmying_mochi`
- Tier: You'll notice
- Useful: 1/5
- Signal: 2/5

### Directory-descent symlink/mount verification hardened against races and EPERM/EACCES

Symlink and mount checks while walking into directories are hardened against races and permission errors

**What**

When Claude Code verifies that a file path's parent directories are what they're expected to be (checking they haven't been swapped out for a symlink, for example), it now walks the path one directory level at a time, re-verifying each level even if the normal file-status check fails with a permission error. As a fallback, it opens the directory directly with a flag that refuses to follow symlinks, in order to check it safely.

**Why**

This closes a race-condition window (called TOCTOU, time-of-check to time-of-use) where a symlink could be swapped in partway through a path check, and it makes the check more robust on systems where permission errors would otherwise have blocked verification entirely.

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

### Plugin ZIP install gets content-hash based preview caching

Plugin ZIP installs now reuse a cached extraction based on the archive's content hash

**What**

When installing a plugin from a ZIP file, Claude Code now computes a sha256 hash of the archive's contents. If a matching hash has already been extracted (or staged for preview) for that directory, it reuses that existing extraction instead of unzipping the file again. Otherwise, it extracts the plugin into a new directory named after the hash.

**Why**

This avoids repeatedly re-extracting the same plugin archive, speeding up installs and previews when the same ZIP is processed more than once.

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

### Task-notification wording now distinguishes lingering background work

Task-stop notifications now say when a result may still change because background work is ongoing

**What**

When an agent (a task Claude Code runs on your behalf) stops but still has background work of its own running, the task-notification message now says so explicitly: it warns that the result 'may be interim' and that the same task ID will send another notification once that background work finishes. Previously, all stop notifications used the same generic wording regardless of whether background work was still in progress.

**Why**

This prevents readers from mistaking a partial or provisional result for the final one, and tells them to expect a follow-up notification rather than assuming the task is fully done.

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

### Git tag signing for plugin release tags

Plugin release git tags now get signed using your git signing configuration

**What**

When Claude Code creates a git tag for a plugin release, it now reads your git commit/tag signing configuration and applies it when creating the tag. If that configuration can't be read, it falls back to creating an unsigned tag and shows a warning that the tag was created unsigned. The tag creation now also runs through a sanitized, isolated environment.

**Why**

This lets plugin release tags be signed the same way your other git tags are, instead of always being created unsigned, while still working (with a clear warning) if signing configuration isn't available.

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

### Artifact type/design-system file resolution now checks project/ prefix and supports installing saved design-system tokens directly

Artifact file lookups now also check a project/ prefix, and saved design tokens can be installed directly

**What**

When Claude Code looks up type or design-system files for an Artifact (things like `README.md` or `tokens.json`), it now checks both the plain path and a `project/`-prefixed version of that path.

It also lets the model install a previously-saved design system directly: instead of re-reading and re-typing the file's contents, it can send the saved `tokens.json` (and, for the 'design' type, `bundle.js`, `bundle.css`, and `index.d.ts`) as a `files` entry that just points `from` a path with a `contentType`. There's also special handling for the 'slides' type's `designSystems` `unpinned` flag.

**Why**

This avoids unnecessary re-reading and retyping of design-system content that's already saved, and makes file lookups more resilient by checking an additional common path location.

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

### New macOS-specific 'redirect' detection for staged/network/home paths

New macOS/WSL path-redirect detection feeds into file trust checks

**What**

Claude Code adds new internal checks that detect when a file path resolves through a redirect specific to macOS or WSL (Windows Subsystem for Linux) setups, including:

- macOS `/Volumes` network mount paths

- `/home` symlinks

- WSL UNC-style paths like `//wsl$/...`

These checks feed into the logic that decides whether a given path needs extra trust verification.

**Why**

Paths that quietly redirect to a network location or a different filesystem can be a way to sneak untrusted content past normal trust checks, so detecting these redirect patterns lets Claude Code apply extra scrutiny where it's warranted.

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

### Git subprocess environment hardened with stricter protocol/network controls

Git subprocesses launched by Claude Code now run with stricter network and protocol restrictions

**What**

Git commands that Claude Code runs internally now get a stricter set of environment variables applied:

- `GIT_ALLOW_PROTOCOL="none"`

- `GIT_NO_LAZY_FETCH="1"`

- `GIT_NO_REPLACE_OBJECTS="1"`

- `GIT_TERMINAL_PROMPT="0"`

- `GIT_SSH_COMMAND="false"`, unless SSH is explicitly allowed

**Why**

These settings block git from reaching out over disallowed network protocols, prompting interactively for credentials, lazily fetching missing objects, or substituting replaced objects, reducing the ways a git operation triggered by Claude Code could reach the network or behave unexpectedly.

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

### Bare-repo/gitdir-redirect trust gate reworked with WSL UNC path support

Bare-repo trust check now also recognizes WSL UNC-style redirect paths

**What**

The `git_bare_repo_gate` check, which looks at whether a `.git` symlink or gitdir file redirects somewhere untrusted, now uses a shared WSL UNC-path test instead of its own inline regular expression. This is part of a broader refactor of the logic that classifies paths as plantable, trusted, or oversized.

**Why**

Reusing a common, presumably more thorough path check makes this trust gate consistent with the other new redirect detection, reducing the chance of a WSL-style redirect path slipping past the bare-repo trust check.

- Area: Git Security
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Windows shell-tool-missing and invalid-proxy startup errors are now also reported via the stream-json failure channel

Two Windows startup failures (missing shell tool, invalid proxy config) are now also reported through Claude Code's structured stream-json output

**What**

On Windows, if Claude Code can't find a usable shell tool to run commands, or if its `CLAUDE_CODE` proxy configuration is invalid, it exits at startup. Previously this was only printed to the terminal's error output; now it is also reported through the structured stream-json failure channel, with reasons `shell_tool_missing` and `proxy_invalid`, before exiting.

**Why**

Tools and scripts that consume Claude Code's stream-json output can now detect and handle these two specific startup failures programmatically instead of relying only on parsing terminal text.

- Area: SDK
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Marketplace refresh now surfaces git-lfs warnings during clone

Marketplace refresh now surfaces git-lfs warnings while cloning plugins

**What**

When Claude Code clones a plugin repository from the marketplace, it now checks for git-lfs (Git Large File Storage, an extension for handling big files in git repos) related messages during the clone and logs them, prefixed with `[git-lfs]`, and reports them through the progress callback so they're visible during the refresh.

**Why**

If a plugin repository uses git-lfs and something goes wrong or needs attention, you'll now see a clear warning instead of the clone silently succeeding or failing without explanation.

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

### Transcript truncation-detection now covers queued-command and teammate-mailbox attachments

Transcript truncation now also applies to queued-command and teammate-mailbox attachments

**What**

The logic that decides whether a message row in the transcript should show as truncated or collapsible now specially handles two more attachment types: `queued_command` (checked by origin or prompt length) and `teammate_mailbox` (checked by message count). Plain assistant text messages can also now be collapsed based on their origin or length when the transcript isn't in verbose mode.

**Why**

This keeps long transcripts readable as more kinds of messages and attachments are introduced, collapsing ones that would otherwise clutter the view.

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

### Shell snapshot creation now takes plugin bin paths and gains a usability check

Shell startup snapshots now account for plugin binary paths and check they still exist before reuse

**What**

The code that builds the bash shell's startup snapshot now accepts plugin binary paths (`pluginBinPaths`) in addition to the existing storage data it used before. The shell object also gains a new `isSnapshotUsable()` method that re-checks the snapshot file still exists on disk before the snapshot is used.

**Why**

This keeps shell snapshots aware of plugin binaries and avoids trying to reuse a snapshot whose underlying file has disappeared.

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

### MCP server config now validates "sdk" type entries against an allowed channel

MCP server configs of type "sdk" are now validated against an allowed channel before loading

**What**

When Claude Code loads MCP (Model Context Protocol) server configuration at startup, entries with `type: "sdk"` are now checked against a validation function before being accepted. Entries that fail this check are dropped, with a warning, instead of being silently loaded.

Separately, Anthropic's documentation notes that in cloud sessions, Claude Code ignores server-delivered mid-session MCP updates reaching cloud sessions through cloud session configuration or SDK `setMcpServers()` calls, though in-process `type: "sdk"` entries stay exempt from that restriction.

**Why**

This stops `sdk`-type MCP server entries from loading outside the channel they're meant to run in.

- Area: MCP
- Names: `type: "sdk"`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Git LFS pointer-file detection with a new warning message

Claude Code now warns when Git LFS files were checked out as pointer files instead of real content

**What**

Claude Code now scans a project's git index, including nested `.gitattributes` files, for files tracked with `filter=lfs` (Git's Large File Storage). It checks whether these files were actually checked out as literal LFS pointer files, rather than their real content, by looking for the `version https://git-lfs.github.com/spec/v1` header. If so, it shows a warning telling the user that Claude Code never downloads Git LFS content itself, and to run `git lfs pull` to fetch it.

**Why**

This avoids confusion when Claude reads what looks like a file but is actually just an LFS placeholder, by pointing the user to the command that fetches the real content.

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

### New marketplace checkout freshness probe avoids unnecessary re-clones

Claude Code checks a plugin marketplace's remote git ref before re-cloning it, skipping the clone when nothing changed

**What**

Before refreshing a plugin marketplace's local git checkout, Claude Code now runs `git ls-remote` (a command that lists what commits a remote git repository currently has) against the configured ref, or HEAD, and compares the result to the commit the local checkout already has. It only re-clones when the sparse checkout paths changed, HEAD can't be read, the ref isn't advertised by the remote, or the commit hashes differ. Otherwise it reports the checkout as already current.

**Why**

This avoids unnecessary re-cloning of a marketplace repository when nothing has actually changed, saving time and network calls when Claude Code checks whether plugin marketplaces are up to date.

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

### Artifact watch tool description rewritten: republish conflicts now explained instead of implying live notification

The artifact tool's built-in help text now says a live republish elsewhere starts no turn and sends no notification, with instructions to re-fetch instead

**What**

The explanation Claude Code gives itself for the artifact watch tool no longer claims that when someone else republishes an artifact you're watching, it "arrives as a notification telling you to re-read it before editing." Instead, it now says such a republish starts no turn and sends no notification. It instructs that when an artifact result opens with a line saying a newer version was published, the model should re-fetch the URL and merge its edits onto that newer version, and should follow the refusal text if a publish attempt is rejected because the artifact changed underneath it.

**Why**

This corrects the model's own understanding of how artifact watching behaves, so it doesn't wait for a notification that will never come and instead knows to check for and merge onto newer versions itself.

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

### Worktree removal now distinguishes uncommitted work inside submodules

Deleting an agent's git worktree now shows separate messages for unverifiable submodule state versus ordinary uncommitted submodule changes

**What**

When removing an agent's git worktree, through `claude rm` or the ctrl+x flow, Claude Code now shows different messages depending on the submodule situation: one for work it can't verify, such as a nested repository or an unconfigured gitlink inside the worktree, and another for regular uncommitted changes inside a submodule. Each case has its own explanation and its own follow-up instructions for the command line.

**Why**

This gives clearer guidance when a worktree can't be safely deleted because of submodule content, telling the user what kind of check or cleanup is actually needed instead of one generic warning.

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

### Self-hosted runner: inaccessible context-source repos are skipped instead of failing the whole clone

Self-hosted runner now skips context-source repos it can't access instead of failing the whole clone

**What**

When a self-hosted runner (the `claude runner` binary used to run hosted or CI-style pools of sessions) prepares context sources for a session, it used to fail the whole clone if one repo couldn't be reached. Now, if a repo that isn't a work repo (it has no `push_targets` entry) can't be accessed through the git mount or proxy because of an authentication or permission problem, the runner logs a warning, records the skip as `context_source_access_denied`, and shows a step message telling the user to check their GitHub connection or ask an admin to check org access.

**Why**

This keeps one inaccessible repo from blocking an entire session's setup, and it gives users a clear next step (check GitHub access, or ask an admin) instead of an opaque failure.

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

### Git repository access errors are now classified into denial reasons

Git access failures during clone/fetch are now classified into specific denial reasons

**What**

When a git command fails while cloning or fetching a repository (for example, for git-backed connectors), Claude Code now matches the failure's error text against known patterns and classifies it as one of: `repo_not_found_or_no_permission`, `no_credentials`, `authentication_failed`, or `blocked_by_git_proxy`. This is attached to a new `RepositoryAccessError`.

**Why**

Classifying git failures this way means error handling and user-facing messages can be more specific about why access failed, instead of showing a generic git error.

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

### Terminal dialog schema gains a memories listing

Terminal status dialog can now list saved auto-memory entries

**Unclear.** The finding shows the schema gained this field but does not confirm the dialog UI itself displays it yet.

**What**

The data behind the CLI's terminal/status dialog now includes an optional `memories` list, showing saved auto-memory entries. These come from the `MEMORY.md` index and file modification times, capped at 200 entries, and use the same source that memory recall itself relies on.

**Why**

This makes it possible for the status dialog to show users what Claude Code has remembered about their project or preferences, rather than that information being invisible.

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

### New org-level 'starting effort' message distinct from default effort

Effort selector can now show a separate note when an org pins the starting effort for new sessions

**What**

The effort-level selector (where you choose how much reasoning effort a model uses) can now show a new note: that your organization pins the *starting* effort for new sessions on a given model. This is separate from the existing note about the organization's overall default effort.

**Why**

This distinguishes between an org-wide default effort and an org policy that only controls where a new session starts, so users see the correct explanation for why a particular effort level is preselected.

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

### Worktree removal warning now flags hidden submodule changes

Worktree removal warning now separately flags uncommitted submodule changes that git status wouldn't show

**What**

Before discarding a worktree's (an isolated working copy of a repo) uncommitted changes, Claude Code now shows a warning that separately calls out submodule work, via a new `submoduleWork` field, in addition to the regular git status information.

**Why**

Running `git status` inside a worktree doesn't reveal uncommitted changes inside its submodules, so without this callout a user could remove a worktree and lose submodule work without any warning about it.

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

### Memory-pressure banner split into separate 'high' and 'critical' tiers

Memory-pressure warning now shows separate 'high' and 'critical' banners instead of one combined one

**What**

The hook that checks memory usage and warns the user used to return a single status. It now takes a threshold and a flag for whether to emit telemetry, and runs twice: once to check the 'high' tier and once for the 'critical' tier, each producing its own banner in the interface. The `tengu_memory_threshold_crossed` telemetry event now only fires from the critical-tier check.

**Why**

Splitting the warning into two tiers lets Claude Code distinguish a milder heads-up (high memory use) from a more urgent one (critical), rather than treating both the same way, while only counting the more severe crossing in telemetry.

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

### Better error messages when Artifacts need a claude.ai login, especially in remote/injected-credential sessions

Error messages for Artifacts requiring a claude.ai login are now more specific about remote and host-injected-credential sessions

**What**

When Artifacts (Claude's rendered code/content outputs) need you to be signed in to claude.ai and you're not, Claude Code now shows a more precise error depending on your situation:

- A generic message telling you to run `/login`

- A remote-session message explaining that the host machine (the one actually running the session) needs to be signed in

- A message for sessions where credentials are injected by the host environment, noting this can't be changed locally

**Why**

Previously the login error was likely one generic message regardless of setup. Now, if you're in a remote session or one where your login comes from the environment rather than a local `/login`, the error tells you where the actual problem is instead of pointing you at a command that won't fix it.

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

### Artifact-watching notification and confirmation copy overhauled

Wording around artifact-watching notifications and confirmations rewritten to clarify that new versions and republishes don't interrupt Claude

**What**

Several pieces of text related to watching an artifact for changes have been rewritten:

- The notification banner shown for artifact updates

- The message sent to Claude explaining republish and comment behavior

- The confirmation-dialog text shown when approving artifact watching or auto-reply

The new wording centers on making clear that 'a new version starts no turn and sends no notification' and 'a republish starts no turn.'

**Why**

This clarifies, in the copy itself, that these artifact-watch events don't automatically trigger a new conversation turn or notification, which should reduce confusion about whether Claude will react to artifact changes on its own.

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

### 'Claude Code on the web' renamed to 'a cloud session' / 'cloud sessions' in user-facing strings

'Claude Code on the web' is renamed to 'cloud session(s)' across error messages, menus, and commands

**What**

Claude Code has renamed "Claude Code on the web" to "cloud session" (or "cloud sessions") throughout its user-facing text. This touches a wide range of places:

- The authentication-required error, now reading that "Claude Code cloud sessions require authentication" instead of "Claude Code web sessions require authentication"

- Menu options for launching work remotely, now saying "launch in a cloud session" instead of "launch in Claude Code on the web", including the remote-control disable option

- The self-hosted-runner onboarding prompt and teleport/remote-control conflict messages

- PR-comment posting failure reasons and self-hosted-runner diagnostics

- Ultrareview's unavailability messages, now saying it "runs in a cloud session"

- The `/web-setup` suggestion banner, GitHub-connection status labels, and the Ultraplan-approved notification

- Slack and task action labels, plan-review links, and confirmation prompts before launching a remote run (ultraplan, ultrareview, code-review's "post to PR" flow, teleport)

In some of these spots the wording instead points to "your browser" or "Open in browser" rather than "cloud session", depending on context.

**Why**

This is a terminology change rather than a functional one: anywhere Claude Code previously talked about running work "on the web", it now calls that a "cloud session" instead. Readers who are used to the old phrasing should expect to see the new term in error messages, menus, and prompts without any change in what actually happens.

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

### MCP server 'add' now rejects host-only transport types explicitly

Adding host-only MCP server types (sdk, sse-ide, ws-ide) via config now fails with a clear error

**What**

When adding an MCP (Model Context Protocol, a way of connecting external tools and data sources) server through configuration, Claude Code now checks whether its transport type is one of three host-only types: `sdk`, `sse-ide`, or `ws-ide`. If it is, the add now fails immediately with a clear error explaining that such servers are registered by the host application at runtime and can't be stored in configuration. This check runs before the existing enterprise-policy checks.

Relatedly, if a plugin declares one of these server types inline in its own `mcpServers` config, that server is now stripped out with a validation error, since only the host application is allowed to register those types.

**Why**

This prevents confusing failures later by rejecting an unsupported configuration up front, with an error message that explains why it isn't allowed rather than leaving the user to guess.

- Area: MCP
- Names: `sdk`, `sse-ide`, `ws-ide`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Cloud gateway settings failures now carry a structured reason and forbidden flag

Cloud gateway settings-load failures now report a specific reason and a 'forbidden' flag

**What**

When Claude Code's cloud gateway fails to load settings, the failure result now includes a `forbidden` boolean and a `reason` field, set to one of `gateway_signin_required`, `gateway_access_denied`, or `remote_settings_required_unavailable`. These are added alongside the existing `exitMessage` and `endedSession` fields, and cover the 401 (unauthorized), 403 (forbidden), and other error cases.

**Why**

This gives more precise, structured information about why a settings load failed, which should make it easier to distinguish an access-denied case from a sign-in problem or an unavailable service.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### git subprocess helper can now forward GIT_TERMINAL_PROMPT

Git subprocess calls can now opt in to allowing the terminal credential prompt

**What**

Claude Code's internal helper for building git commands gained a new `allowGitTerminalPrompt` option. Unless a git subprocess explicitly opts in, the `GIT_TERMINAL_PROMPT` environment variable is now stripped from the environment passed to that git process.

**Why**

`GIT_TERMINAL_PROMPT` controls whether git can prompt for credentials in the terminal. Stripping it by default, except where explicitly allowed, closes off a case where git subprocesses could previously pass it through unfiltered, keeping git commands from unexpectedly waiting on a credential prompt.

- Area: Git Security
- Names: `GIT_TERMINAL_PROMPT`
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Auto-memory: memory index now returned alongside status

Auto-memory status now also returns a list of the actual memory files

**What**

When Claude Code gathers context for its auto-memory and auto-dream status, the result now includes a `memories` array listing the memory files found, including the special `MEMORY.md` index file. This is returned whenever memory folders are present, alongside the existing `files`, `folders`, `auto_memory`, and `auto_dream` fields.

**Why**

This exposes the actual set of memory files rather than just folder-level status, which is presumably needed by other features that need to list or reference individual memories.

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

### Plugin tool registration can be withheld by a deny rule without waiting

Plugin tool registration blocked by a deny rule now fails instantly instead of waiting

**What**

When a plugin registers a new tool and a permission deny rule matches that tool by name (or by MCP server plus tool name), Claude Code now returns immediately saying the tool is withheld from the session, instead of polling and waiting for the tool to show up in the session's tool list.

**Why**

Previously this case likely caused a delay or timeout while Claude Code waited for a tool that was never going to appear because it's blocked. Failing fast avoids that wasted wait.

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

### MCP config 'sdk' server type now rejected outside SDK host registration

MCP servers of type 'sdk' in config files are now rejected unless registered by the SDK itself

**What**

An MCP server declared with type `"sdk"` in a configuration file is now explicitly rejected with a dedicated error, unless the configuration comes from the in-process SDK (marked as source `dynamic`). The general "unknown server type" error message also no longer lists `sdk` as a valid type unless the source is `dynamic`.

**Why**

This closes off a way of declaring an `sdk`-type server that only an SDK host application should be able to register, giving a clearer error instead of letting it fail as a generic unknown type.

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

### New startup_failure_reason field on stream-json startup-failure results

New 'startup_failure_reason' field records why a stream-json run failed to start

**What**

When a `stream-json` run exits early because of a known startup failure, its final result can now include a new field, `startup_failure_reason`, explaining what went wrong. This is only written when the host application sets a specific environment variable; without it, results look as before, with the failure information only in stderr.

**Why**

This gives host applications an opt-in, structured way to learn why a run failed to start, instead of having to parse stderr text. It only appears for known startup-failure cases, not for every failure or for older versions that produce results.

- Area: SDK
- Names: `startup_failure_reason`
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Auto-replies: new 'signed in outside the org' refusal reason for resume

Auto-replies to Artifact comments can no longer resume for accounts signed in outside the artifact's organization

**What**

Claude Code's automatic-reply system for Artifact comments gains a new refusal reason, `public_outside_org`. If an Artifact is public and the account currently signed in is outside the organization that owns it, automatic replies can no longer be resumed. When this happens, Claude Code tells the user about it and is instructed not to retry.

**Why**

This closes a case where an account outside an Artifact's organization could re-arm automatic replies on a public Artifact, which presumably isn't meant to be allowed across an organization boundary.

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

### Artifact republish notice changed from live notification to passive marker

Artifact republish notices now describe a passive note instead of promising an active notification

**What**

The message shown when attaching to a watched Artifact changed. It used to promise the user would be actively "notified" if the Artifact was republished elsewhere. It now says a republish (from another session, or someone saving from the page) "starts no turn" on its own, and instead some future Artifact tool results will simply open with a one-line note that a newer version was published.

**Why**

This sets more accurate expectations: republishing elsewhere doesn't proactively interrupt or notify a session, it just gets mentioned the next time an Artifact tool result happens to come up.

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

### Effort-level message notes organization session-start override

The effort-level confirmation message can now note that your organization forces new sessions to a different effort

**What**

When you set an effort level (how much reasoning Claude applies) for a model and your organization has capped it, the confirmation message can now add a note that although your choice was saved, your organization forces new sessions on that model to start at a different, organization-set effort level.

**Why**

This avoids confusion when a saved effort-level preference doesn't seem to take effect: the message now explains that the organization's policy overrides it at the start of each new session.

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

### apiKeyHelper failure now surfaced in status/settings display

Settings/status now shows a 'Failing' row with last-run time when your apiKeyHelper command errors

**What**

The settings and status display now shows a 'Failing' row when your configured `apiKeyHelper` (a command you set up to generate an API credential) fails to run. Normally this row includes the timestamp of the last run attempt, but in demo mode it just says 'Failing' without the timestamp.

**Why**

This makes it easier to notice when your `apiKeyHelper` command is broken, instead of failures happening silently.

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

### list_connected_browsers now reports onThisComputer and inUse

list_connected_browsers now reports whether a browser is on this computer and whether it's the one currently in use

**What**

The `list_connected_browsers` tool, which lists browsers connected to Claude Code, now reports two new pieces of information for each browser:

- `onThisComputer`: whether the browser's device is, or recently was, running on this computer. This is described as more reliable than the existing `isLocal` check, which only compares operating systems as a weak hint.

- `inUse`: whether this is the browser that the current session's browser actions are currently directed at, when that is known.

**Why**

These fields make it easier for Claude to pick the right browser automatically instead of guessing from a weaker signal or asking the user unnecessarily.

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

### Gateway open-request backpressure warning

Gateway now warns when too many client requests pile up relative to what it can forward upstream

**What**

The gateway process (which forwards requests upstream) now logs a rate-limited warning when it has too many client requests open at once compared to how many it can actually forward upstream concurrently. The warning suggests adding replicas or raising the `BUN_CONFIG_MAX_HTTP_REQUESTS` setting together with the replica's memory limit.

**Why**

This surfaces a backpressure problem that could otherwise cause slow or stuck requests without explanation, and points operators toward the specific settings to fix it.

- Area: Gateway
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### New 'outside_org' case in the read-permission decision tree

Read-permission checks now have a dedicated 'outside_org' case that requires approval

**What**

The internal logic that decides whether a file or content read needs approval now has an explicit case for content flagged as `outsideOrg`. This returns a `foreign_read` decision, tagged with `about: "outside_org"`, before falling through to the existing checks for ownership and network settings.

**Why**

This adds a distinct, explicit approval path for reads involving content outside the user's organization, rather than relying on the more general checks that existed before.

- Area: Permissions
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Background shell 'stopped for memory pressure' message rewritten to strongly discourage auto-restart

Low-memory shutdown message for background shells now firmly tells Claude not to auto-restart them

**What**

When Claude Code kills a background shell because the system is critically low on memory, the message now shown to Claude is much more explicit: don't try to debug the killed command, don't restart it automatically, report what happened to the user, and only restart it if the user actually asks. It also now mentions the environment variable available to opt out of this behavior.

**Why**

This reduces the chance that Claude reflexively restarts a command that was just killed for using too much memory, which could otherwise repeat the same memory pressure problem.

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

### Two new memory-write rejection reasons: index too large and content screened

Shared memory writes can now fail because the index file is too large or content was screened out

**What**

Claude Code's shared memory write path now recognizes two additional rejection reasons from the server, each with its own guidance shown to the agent:

- the `MEMORY.md` index file exceeding a size cap that is separate from the limit on individual files

- content being rejected by an unspecified safety screening check

**Why**

This gives clearer, more specific feedback when a memory write is rejected, so the agent (and by extension the user) understands whether the problem is the index file being too big or content being blocked, rather than a generic failure.

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

### Governed mount read failures now return typed reasons instead of null

Governed mount read failures now report a specific reason instead of a generic null

**What**

For self-hosted deployments that use a governed mount (a controlled file location Claude Code reads from), a failed read used to just return nothing (`null`) with no explanation. Now it returns a result like `{ok: false, reason: ...}`, with the reason being one of `not_regular_file`, `read_error`, or `absent`.

**Why**

This lets the code that calls this function tell the difference between a missing file, a file that isn't a regular file, and a read error, instead of treating every failure the same way.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Background task exit now flushes buffered output into its notification

Background task exit notifications now include any output that hadn't been flushed yet

**What**

When a task running in the background finishes, Claude Code sends a notification about it. There's now a `reportExit()` step that, on exit, drains any output that was still sitting in the buffer and hadn't been shown yet, and folds it into that exit notification. If no notification had been created yet, a new one is created to carry this output.

**Why**

Previously, output produced right before a background task exited could be left out of the notification. Now the final notification reliably reflects everything the task printed, even in its last moments.

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

### Cloud gateway sign-in error now a structured error code

Cloud gateway sign-in failure is now a structured error with a 'signin_required' code

**What**

When Claude Code isn't signed in to the Cloud gateway, the resulting failure is now thrown as a typed error carrying the code `signin_required`, instead of a plain, generic error. The message shown still tells the user to run `/login`.

**Why**

A structured error code lets other parts of the code detect and handle this specific failure (for example, prompting sign-in) rather than only being able to match on the error's text.

- Area: Elsewhere
- Names: `/login`
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### New git worktree-create refusal for unsafe LFS config keys

Creating a git worktree can now be refused if the repo's git config sets an unsafe Git LFS-related key

**What**

Claude Code can now refuse to create a git worktree or checkout with a new reason, `unsafe_key`, when the repository's own git config sets an LFS (Git Large File Storage)-related config key that names a program git-lfs would run during checkout or status.

**Why**

A repository's git config can be crafted to make git-lfs automatically run an arbitrary program. Refusing the worktree creation in that case stops Claude Code from triggering that program without the user knowing.

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

### New auth error message for unverifiable org token

New error message tells users when their organization can't be verified for their current auth token

**What**

Claude Code now shows a specific error message when it can't verify the organization tied to a user's current authentication token, telling them to retry or run `claude auth login`.

**Why**

This gives a clearer, actionable message when organization verification fails, instead of a generic error, so the user knows exactly what to do next.

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

### New version-mismatch update prompt

New message tells users their Claude Code version must be updated before continuing, with the exact update command

**What**

A new message tells the user that their current version of Claude Code is too old, states the minimum version now required, and tells them to run `claude update`.

**Why**

This makes clear why Claude Code has stopped working and gives the exact command to fix it, instead of leaving the user to guess what to do.

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

### Git env allowlist changed: config-override vars removed, namespace/worktree vars added

The GIT_* environment variables Claude Code sanitizes before running git changed: config-override vars dropped, namespace/worktree vars added

**Unclear.** It isn't clear why the config-override variables, previously called out for safety reasons, were removed from this list.

**What**

The set of `GIT_*` environment variables that Claude Code scrubs before running git commands changed:

- Removed: `GIT_CONFIG_COUNT`, `GIT_CONFIG_PARAMETERS`, `GIT_CONFIG_GLOBAL`, `GIT_CONFIG_SYSTEM`, `GIT_CONFIG`

- Added: `GIT_NAMESPACE`, `GIT_IMPLICIT_WORK_TREE`

**Why**

This changes exactly which environment-based ways of redirecting a git command's behavior Claude Code sanitizes against before running it, dropping the config-override variables from the list and adding namespace and work-tree ones instead.

- Area: Git Security
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Certificate errors now classified for cert-chain failures

TLS certificate errors are now classified into specific known cert-chain failure codes

**What**

A new list of known TLS certificate error codes, `UNABLE_TO_VERIFY_LEAF_SIGNATURE`, `UNABLE_TO_GET_ISSUER_CERT`, `UNABLE_TO_GET_ISSUER_CERT_LOCALLY`, `DEPTH_ZERO_SELF_SIGNED_CERT`, and `SELF_SIGNED_CERT_IN_CHAIN`, is now used with a new helper function to extract a readable reason string from certificate errors.

**Why**

This lets Claude Code recognize and report specific certificate chain problems, like self-signed or unverifiable certificates, with a clearer reason instead of a generic connection failure.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Usage-credits 1M-context guidance message reworked with new eligibility checks

1M-context usage-credits message now varies based on whether /usage-credits is actually available to you

**What**

The message shown when using a 1 million token context window requires usage credits now checks whether you're in a suitable environment (interactive, not self-hosted in a way that blocks it) and whether the `/usage-credits` command is actually available (it can be turned off via `DISABLE_EXTRA_USAGE_COMMAND`). Depending on the result, the message either offers `/usage-credits` to turn credits on, or only points to `/model` to switch to a standard context window.

**Why**

This avoids telling someone to run `/usage-credits` when that command isn't actually usable in their setup, giving a more accurate next step instead.

- Area: Elsewhere
- Names: `/usage-credits`, `/model`, `DISABLE_EXTRA_USAGE_COMMAND`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Model-switch suggestion text now considers config sources beyond gateway

Model-unavailable suggestions now weigh more context before recommending /model or --model

**What**

When a requested model isn't available, Claude Code now decides whether to suggest the `/model` command or the `--model` flag using new logic that considers whether the session is interactive, additional configuration sources, and whether it's running in an `sdk-cli` or `claude-code-github-action` context. In those two contexts specifically, it now suggests `--model` instead of `/model`.

**Why**

This makes the suggested fix more accurate for automated or non-interactive contexts like the SDK CLI or a GitHub Action, where `/model` (an interactive command) wouldn't apply but `--model` (a flag) would.

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

### System-prompt/tool-schema info is now cached and hashed

System prompt and tool schema extraction is now cached and hashed instead of reparsed each time

**What**

The internal function that extracts the active system prompt, tools, and tool schemas now caches its parsed result instead of redoing the work on every call, and adds a `systemPromptHash` field computed by a new hashing function.

**Why**

Caching avoids repeatedly re-parsing the same system prompt and tool information, and the new hash gives a quick way to check whether the system prompt has changed.

- Area: System Prompt
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### New prompt_render_point cause 'set_model_system_prompt'

A new marker tracks when the system prompt was re-rendered specifically because the model changed

**What**

Claude Code now records a marker in the conversation, tagged `cause: 'set_model_system_prompt'`, when the system prompt is regenerated as a result of a model change. New logic uses the position of these markers in the conversation history to decide whether the system prompt needs to be re-rendered again after a model switch.

**Why**

This helps Claude Code avoid unnecessarily re-rendering the system prompt, by keeping track of exactly when it was last regenerated due to a model change.

- Area: System Prompt
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Startup now fails gracefully with a structured result when cwd is unavailable

Claude Code now exits with a structured JSON error, not just a printed message, when its working directory is unavailable at startup

**What**

If Claude Code starts up and finds that its current working directory is missing or unreadable, it now produces a structured result with the reason `cwd_unavailable` before exiting, instead of just printing an error message. This puts it in line with other startup failure reasons like `temp_dir_unusable` (temporary directory can't be used) and `shell_tool_missing` (required shell tool not found).

**Why**

A structured, machine-readable failure result makes it easier for scripts, integrations, or tools that launch Claude Code to detect exactly why startup failed and react accordingly, rather than having to parse free-form error text.

- Area: Startup
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### New guard on artifact file reads triggered by unattended auto-reply notifications

Artifact file reads triggered by unattended auto-reply notifications are now blocked outside background/subagent contexts

**What**

The permission check for reading artifact files now explicitly refuses to allow the read when it was queued as a result of an unattended auto-reply notification, unless the current context is a background or subagent context.

**Why**

This closes off a path where an automatic, unattended notification reply could trigger a file read outside of a controlled background process, keeping such reads confined to contexts where they're expected.

- Area: Artifacts
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Worktree/job deletion now detects in-progress submodule work before removing

Deleting a job's worktree now checks for in-progress submodule work before removing it, instead of only tracked-file state

**What**

When Claude Code deletes a job and cleans up its associated git worktree (a separate working copy tied to a branch), it now also checks the status of any git submodules. If submodule state can't be verified, the worktree is kept rather than deleted, with a new 'submodule' reason recorded for why it was kept. Previously this check only looked at whether tracked files were dirty or whether there was a nested repository.

**Why**

This avoids accidentally deleting a worktree that has in-progress or unverifiable submodule work, reducing the risk of losing uncommitted changes inside a submodule.

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

### First query now waits briefly for SDK MCP servers still connecting

The first query of a turn now briefly waits for SDK-configured MCP servers that are still connecting

**What**

When a turn begins, if any SDK-configured MCP (Model Context Protocol) servers haven't finished connecting yet, Claude Code now waits briefly for them — up to the MCP connect timeout, which defaults to 5 seconds. It logs whether the wait timed out and which servers were still pending. If some servers still aren't connected after the wait, the turn proceeds without their tools and a warning is shown.

**Why**

This reduces the chance that a turn starts before its MCP tools are ready, while still making sure the turn doesn't hang indefinitely if a server is slow or fails to connect, surfacing a warning instead.

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

### Headless SDK sessions now detect and re-inject a changed system prompt mid-session

Headless SDK sessions now detect a changed system prompt mid-session and re-inject it into the transcript

**What**

In headless SDK sessions (Claude Code used programmatically rather than interactively), a new check compares whether the system prompt was already sent against whether the caller's `systemPromptSnapshot` has since changed. If it has changed, the new system prompt is pushed into the session transcript as an event and telemetry is recorded, before the system prompt is applied for that turn.

**Why**

This lets a long-running headless session pick up a system prompt change partway through, rather than being stuck with whatever prompt was set at the start of the session.

- Area: SDK
- Names: `systemPromptSnapshot`
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### list_connected_browsers marks the currently in-use device and gives a fuller selection prompt

list_connected_browsers now marks which browser is in use and shows a fuller selection prompt

**What**

The `list_connected_browsers` tool, which lists browsers connected to Claude Code, now marks the currently selected device with `inUse: true` in its results. It also translates raw operating system identifiers into readable names like macOS, Windows, and Linux, and shows a fuller prompt when multiple browsers are connected instead of the previous flat message.

**Why**

This makes it clearer, when several browsers are connected, which one is currently active and what platform each one is running on.

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

### Agent-summary generation now rejects unusable replies and tracks consecutive rejects

Background-agent summaries now get rejected outright if unparseable, with a running count of failures

**What**

When Claude Code generates a short summary of what a background agent (a subagent running a task in the background) is doing, it now parses the model's reply and, if that parsing fails, throws the reply away instead of storing it as the summary. Previously it would just trim any non-empty reply and use it regardless. A count of consecutive rejected replies is now tracked and reported.

**Why**

This avoids showing garbled or unusable text as a background agent's summary, at the cost of sometimes having no summary at all when the model's reply can't be parsed.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Artifact design-system/start-kit flow: REPL tool pooling and richer 'not saved' messaging

Design-system/start-kit artifact saves now give clearer reasons when a file wasn't saved, and track REPL tool availability separately

**What**

When saving files through the design-system/start-kit artifact flow, if a file was not actually saved, the response now explains why with a structured reason, such as suggesting to list files directly, read them with your own tool calls, or state plainly that it's unclear rather than guessing. Previously this case returned a simpler, generic fallback message.

Separately, the start kit now tracks two things independently: whether a REPL tool (a tool for interactively running code) is available in the current tool pool, and whether start-kit mode itself is turned on. These were previously combined into a single flag.

**Why**

Clearer 'not saved' messages help avoid the assistant guessing about file state when a save didn't go through. Tracking REPL availability separately from start-kit mode lets the two be checked independently instead of conflating them.

- Area: Artifacts
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Artifact comment-read errors now carry structured, more specific explanations

Artifact comment-read failures now show specific reasons instead of one generic error

**What**

When Claude Code can't read comments on an artifact (a shared document or file created in a conversation), it now explains why in more detail. A new internal helper translates specific failure reasons, such as the artifact belonging to another organization, not being a shared link, not currently being served, being blocked by a permission rule, having a pending notice, or a check failing, into a plain-language explanation plus a suggested next step (like saying so, making your own calls, or listing available items).

**Why**

Previously all these situations produced the same generic "its sharing could not be checked" message. Now you get a more specific reason and a hint about what to try next, making it easier to understand why an artifact comment couldn't be read.

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

### Worktree exit dialog now vets git config before counting changes, and checks submodules

Exiting a worktree now checks git config safety and submodules before counting uncommitted changes

**What**

The confirmation dialog shown when exiting a worktree (a separate working copy of a git repository) used to just run `git status --porcelain` to count uncommitted changes. It now first checks the worktree's git configuration for unsafe settings, such as conditional includes or custom Git LFS transfer agents. If the worktree can't be safely read, it shows a generic warning about "uncommitted files that could not be counted" instead of a precise count.

- It also now checks submodules for uncommitted work using a `--submodule=short` diff.

- If a submodule's status can't be checked, it appends a warning line saying so.

**Why**

This avoids running git commands against a worktree whose configuration could behave unsafely, and it makes sure uncommitted changes hidden inside submodules aren't silently missed when deciding whether it's safe to exit a worktree.

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

### Git bundle upload now auto-falls-back to a squashed snapshot for partial/promisor clones

Git bundle uploads now fall back to a squashed snapshot when the repo uses partial or promisor clones

**What**

When creating a `git bundle` fails on a repository that isn't hardened and wasn't deliberately aborted, Claude Code now checks the repo's git config for signs it's a partial or promisor clone (settings like `extensions.partialclone`, a `remote.*.partialclonefilter`, or a `remote.*.promisor` entry). If any of these are present, it automatically retries, forcing the operation into a "squashed" mode that bundles a snapshot of the working tree instead, and marks the result as a promisor fallback.

**Why**

Partial and promisor clones don't have all the git objects needed to build a normal bundle, which used to just fail. Now Claude Code recovers automatically by bundling a snapshot instead, so the upload still succeeds.

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

### MCP prompts/resources list-changed listeners no longer require the server to advertise listChanged

Claude Code now listens for MCP prompt/resource list-changed updates whenever a server offers prompts or resources at all

**What**

When connecting to an MCP server, Claude Code used to only subscribe to notifications that a server's list of prompts or resources changed if the server explicitly advertised support for that (`listChanged`). Now it subscribes as soon as the server declares the `prompts` or `resources` capability at all, whether or not it explicitly says it supports change notifications.

**Why**

This means Claude Code can pick up updates to a server's available prompts or resources from more servers than before, including ones that didn't explicitly flag support for change notifications.

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

### quickstart tool can save Artifact/design-system files to the session scratchpad

The quickstart tool can now save an artifact type's or design system's published files to the session scratchpad

**What**

The description of the Artifacts quickstart tool now says that, when possible, it saves the matched artifact type's published files to the session's scratchpad (a temporary working area for the session) and lists them, instead of only reading titles, descriptions, and README text. For slides or design-related requests, it can also save the default design system's files the same way.

**Why**

This gives the agent direct access to the actual published files for an artifact type or design system, rather than just summaries of them, which should make it easier to build on them accurately.

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

### Artifact provenance text-normalization gets a new "created by this session" tag and looser matching

Artifact text scrubbing now recognizes more phrasings of 'created in this session'

**What**

The internal helper that detects and scrubs artifact-provenance phrases (text describing where an artifact's content came from) now also recognizes phrases like "created ... by ... this ... session" with any punctuation or non-letter separator between the words, not just plain whitespace. It also adds new fixed annotation strings for marking artifact ownership and for flagging screened destinations.

**Why**

This broadens the matching so more real-world phrasings of session-provenance text get caught and handled consistently.

- Area: Artifacts
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Publish now detects a known-behind base version, not just a missing one

Artifact publish now refuses when the client's tracked version is known to be stale, not just missing

**What**

When publishing an artifact, Claude Code now checks not just whether it has no tracked base version, but also whether its tracked base version is known to be behind the live version. If it's behind, it performs a read using a "known_behind" route, and if that read still finds content, the publish is refused with a "known_behind" reason instead of overwriting the newer live version.

**Why**

This closes a gap where a client with a stale but non-empty version reference could have silently overwritten someone else's newer published changes.

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

### Bridge/headless session gets a bearer-token "projects door" that iterates all active hosts

Bridge and headless sessions now aggregate a 'projects door' across all active mount hosts instead of just one

**What**

Claude Code sessions running in bridge or headless mode (no interactive terminal) now set up a global hook that checks every active mount host and returns the first one that offers a 'projects door' - a bundle containing a channel ID, session ID, API base URL, and a function to get a bearer token (a credential used to authenticate requests). Previously this lookup only checked a single host.

This matters for multi-agent or bridge setups where more than one host connection (called a 'hearth mount') can be active at the same time.

**Why**

With multiple hosts potentially live at once, this ensures the correct credentials and connection details are found regardless of which host is currently serving the session, rather than assuming there is only ever one.

- Area: Sessions
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### OAuth gateway device-flow rate-limit errors get clearer network-attribution messaging and a metric

Self-hosted gateway's OAuth device-login rate-limit errors now explain shared-network causes and point to specific settings

**What**

When the self-hosted gateway's device-authorization or device-verification sign-in endpoints hit their rate limits, the error message no longer just says 'Too many attempts.' It now explains that the limit may have been triggered by other people sharing the same network address, and tells administrators which specific settings to adjust: `listen.trusted_proxies` or `rate_limits.device_authorization`. Each rate-limited request now also sends a telemetry event before returning the error.

**Why**

This helps administrators diagnose and fix false rate-limit blocks caused by shared network addresses (such as behind a corporate NAT or proxy) instead of leaving them with a vague error and no next step.

- Area: Elsewhere
- Names: `listen.trusted_proxies`, `rate_limits.device_authorization`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Fast-mode policy override no longer requires the request flag

Fast mode now switches to 'preference' whenever policy settings disable it, even if this request didn't ask for it

**What**

`fastMode` (also called 'penguin mode') lets a session run in a faster response mode when it's available. A policy check that decides whether fast mode should fall back to the account's saved preference now fires any time `policySettings.fastMode` is set to `false`. Previously this fallback only kicked in if the current request had already asked for fast mode; now it applies regardless of what the request asked for.

**Why**

This closes a gap where a policy that disables fast mode could be bypassed by a request that didn't explicitly opt in. Now the policy setting consistently overrides, so an account-level restriction on fast mode can't be sidestepped by request shape.

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

### get_memory_dialog control response gains a full memories list

get_memory_dialog now returns a full list of saved auto memory files, not just folders

**What**

The internal `get_memory_dialog` response, used by host applications that build their own `/memory` interface, now includes a `memories` array. It lists each saved auto memory file with its name, path, description, type, and last-modified time, in addition to the folder list it already returned.

**Why**

Hosts that draw a custom `/memory` screen can now show the actual saved memory entries, not just the folders that contain them, giving users a fuller picture of what auto memory has stored.

- Area: Memory
- Names: `get_memory_dialog`
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Self-hosted gateway warns when open upstream requests exceed BUN_CONFIG_MAX_HTTP_REQUESTS

Self-hosted gateway now warns when it has more open client requests than its outbound limit allows through at once

**What**

The self-hosted runner's gateway process (used when running Claude Code's automated tasks on your own infrastructure) now tracks how many incoming requests are open versus how many it is allowed to forward upstream at once, based on `BUN_CONFIG_MAX_HTTP_REQUESTS` or its default. When the number of open requests exceeds that outbound limit, it logs a warning, throttled so it doesn't repeat constantly.

**Why**

Requests beyond the outbound limit already had to wait inside the gateway for a free slot; this change just makes that backlog visible in the logs instead of happening silently, which helps diagnose slowdowns on self-hosted setups.

- Area: Gateway
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Multi-browser device selection state added to the Chrome bridge connector

Chrome bridge now re-runs device discovery while a multi-browser selection is pending

**What**

The browser bridge tool, which connects Claude Code to a browser like Chrome, gained a new `multiBrowserPendingSelection` flag. Device discovery (finding connected browser instances) now also runs, or re-runs, whenever a multi-browser selection is pending, not only when discovery had never completed before.

**Why**

This should make browser selection more reliable when multiple browsers are connected and a choice between them is still awaiting an answer, rather than getting stuck on stale discovery results.

- Area: Chrome Control
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Self-hosted gateway retries Postgres connection at boot

Self-hosted gateway now retries the Postgres connection up to 3 times at startup instead of failing immediately

**What**

A new retry wrapper, internally called `Ote`, has been added around the Postgres database connection that the self-hosted gateway makes while loading its configuration at startup. If the connection attempt fails with a connection-refused-style error, it is retried up to 3 times before the gateway gives up.

**Why**

This helps the gateway start up cleanly in cases where Postgres isn't quite ready yet (for example if the database container is still starting), instead of failing on the first attempt.

- Area: Gateway
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Teleport git operations now scoped to the correct worktree cwd/env, plus new auto-stash flow

Teleport's git operations now target the correct folder and can auto-stash uncommitted changes before switching

**What**

The 'teleport' feature (which switches your working session between git worktrees, separate checkout folders for different branches) had its internal git operations reworked. Setting the upstream branch, checking out a branch, and looking up the current branch now resolve a specific working directory and environment instead of relying on whatever git considered the ambient root. A new check confirms a checkout's `.git` folder genuinely points back to itself.

Alongside this, a new 'Teleport auto-stash' flow can stash (temporarily set aside) uncommitted changes by running a git add followed by `stash push --message` before a teleport happens.

**Why**

Scoping git commands to the exact worktree avoids operating on the wrong folder when multiple checkouts are in play, and auto-stashing means uncommitted work no longer blocks or gets mixed up during a teleport switch.

- Area: Git Teleport
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Project/artifact comment sync reworked to hash message text, tracking edited/re-sent content

Comment syncing for projects/artifacts now tracks message content by hash so edited comments are noticed again

**What**

The logic that avoids re-processing comments it has already seen ('judged' or 'sightings') on projects and artifacts previously tracked comments by their ID and timestamp alone. It now also hashes the comment's text. A new `textsForgotten` flag and a map of last-seen text can detect when a comment's content has changed since it was last handled, even if its ID stayed the same.

The same change applies to the artifact autoreact logic, which decides whether to automatically react to comments.

**Why**

Previously, editing a comment after Claude had already reacted to or judged it may not have triggered a fresh look, since the ID and timestamp hadn't changed. Tracking the text itself means edited or re-sent comment content gets noticed and handled again.

- Area: Projects
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Mid-session policy-helper remote failure re-announces tier change on config change

Mid-session managed-settings re-checks now also announce a tier change when the remote failure configuration itself changes

**What**

During a session, Claude Code periodically re-checks its remote managed-settings helper. This re-check now also announces a tier change whenever the recorded remote failure configuration changes, in addition to the previous triggers (new retired helper paths, or a flip in whether settings came from the remote).

**Why**

This keeps the tier-change announcement in sync with a wider set of conditions, so a changed failure state during a session is reflected promptly rather than only on the next full check.

- Area: Managed Settings
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Old version folders under a 'claude-test' staging area now get proactively cleaned up

Claude Code now automatically cleans up old version folders left behind in its 'claude-test' staging area

**What**

A new cleanup routine runs against the staging directory used by the `claude-test` feature: it updates the directory's modification time, then, once a version check succeeds, deletes sibling version folders that are older than the currently installed version's own folder. If cleanup fails, it logs `claude-test: old version folders not cleaned up` rather than stopping.

**Why**

This keeps old, unused version folders from accumulating in the claude-test staging area over time.

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

### Gateway server gains a graceful drain/shutdown path

Local managed-gateway server gains a graceful drain step before shutdown

**What

The local gateway server that Claude Code runs to manage API requests now tracks how many requests are still in flight and adds a `drain` method (alongside the existing `stop`) that stops accepting new work, waits for pending requests up to a timeout, flushes billing/metering data, and reports how many requests were still pending when it finished. The server also now checks whether a request originated from an internal/in-VPC address for logging purposes, and its housekeeping reports now include an `outboundLimit` value.

Separately, the server-side billing and spend-limit code now tracks in-flight spend-check and metering work and exposes a `flush` function that waits for all of it to finish before the process exits, using a timeout-bound abort mechanism for the spend-check request itself.

**Why

This reduces the chance of losing in-flight requests or billing/metering data when the gateway shuts down, ensuring usage is accurately recorded rather than dropped mid-request.

- Area: Gateway
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Force-login-org / policy validation failures now get logged and reported with a reason

Failed org/policy validation during headless startup now gets logged with a reason

**What

When Claude Code runs in headless mode (`--print`) and account or organization policy validation fails, it now records a report before erroring out. If the policy couldn't be read (`policyUnreadable`), a `policy_invalid` event is reported. In the final force-login-org check, a failure now also logs the session ID, message, and reason, and runs an additional cleanup step.

**Why

This gives better visibility into why a headless session was blocked by organization policy, making these failures easier to diagnose instead of just failing silently.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Worktree removal failure reason "nested_repositories"/"nested_unverified" merged into a single "submodule" case

Two separate nested-repository worktree-removal errors were merged into one "submodule" case with clearer wording

**What**

When Claude Code refuses to remove a git worktree because of nested repositories, it used to report two separate reasons internally (`nested_repositories` and `nested_unverified`). These are now merged into a single "submodule" case, with wording that tells apart a worktree holding a separate git repository, which should be moved or deleted, from a submodule whose state can't be verified, which needs a manual check.

**Why**

This gives clearer, more consistent guidance when a worktree removal is blocked by nested repository content, telling the user directly whether they need to move or delete something versus check it manually.

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

### Artifact 'watch' tool description reworded to de-emphasize 'notification'

The artifact watch tool's help text now describes "keeping track of" new versions instead of "notifying" about them

**What**

The built-in help text describing the artifact watch, unwatch, and status tool, shown to the model in sessions where republish notifications aren't used (plain "none" mode), was reworded. It no longer talks about "notify" semantics; it now says the tool "keeps track of new versions of an artifact published elsewhere," and clarifies that in live mode, a republish starts no turn and sends no notification.

**Why**

This keeps the model's understanding of the watch tool accurate: it should know that watching an artifact tracks new versions quietly rather than expecting an active notification.

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

### /review's help text now hedges on which cleanup categories are covered

/review's description now says cleanup suggestions are covered only where the review recipe supports them

**What**

The help text for `/review` no longer unconditionally promises that it covers reuse, simplification, and efficiency cleanups alongside correctness bugs. It now says those cleanups are included only 'where the model's review recipe covers them.'

**Why**

This sets more accurate expectations: `/review` may not always surface reuse, simplification, or efficiency suggestions, depending on which review recipe is in use, whereas the previous wording implied it always would.

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

### Shell snapshot invalidation tracks plugin bin/ PATH changes

Cached shell snapshots are now invalidated when plugin bin/ directories change what's on PATH

**What**

Claude Code caches a snapshot of your shell environment for performance. New logic now decides whether to drop that cached snapshot whenever plugins refresh, checking for any of these conditions:

- Whether plugin `bin/` directories added to your `PATH` have changed

- Whether the shell configuration's snapshot has become unusable

- Whether the shell configuration was still in the process of building

One of these specific reasons is logged before the snapshot is invalidated.

**Why**

This keeps the cached shell snapshot from going stale when plugins change what commands are available on `PATH`, so Claude Code doesn't keep using outdated shell state after a plugin refresh.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Live-subscribe 'flag off' wording softened from an explicit capability claim

Message about disabled live-updates on Artifacts reworded to avoid overpromising

**What**

When the live-subscribe feature is turned off for a session, the message shown changed wording. It used to say Claude "will not be notified" about new versions of an Artifact; it now says "this session does not keep track of new versions of this artifact" instead.

**Why**

The new wording is more neutral and accurate about what's actually happening: the session isn't tracking new versions, rather than making a specific claim about notifications.

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

### Auto-selected browser message when only one option exists

New helper text tells Claude not to ask which browser to use when only one qualifies, and explains tool-response timeouts better

**What**

Two new pieces of user-facing text were added for browser selection:

- When exactly one browser qualifies to be automatically selected, Claude is now told 'No question is needed unless the user wants a different browser,' with guidance to use `select_browser` or `switch_browser` if the user wants a different one.

- A new timeout message, shown when a browser tool call isn't responding, now varies its explanation depending on whether a routing acknowledgment was received, including a note that Chrome may be on another, sleeping computer.

**Why**

These changes reduce unnecessary questions when there's an obvious browser choice, and give a clearer explanation when a browser action stalls because the target device is elsewhere or asleep.

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

### Artifact 'auto_open' tool param description simplified

The artifact tool's auto_open parameter description dropped a conditional sentence that used to appear when a feature flag was on

**What**

The description of the `auto_open` parameter on the artifact-creation tool no longer includes a trailing sentence that previously appeared with extra guidance when a certain feature flag was enabled. The description now ends simply with 'it opens when created.'

**Why**

This trims the tool description to its core behavior, removing conditional wording that depended on an internal flag.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Prompt hook blocking-error truncates overly long prompt commands

Prompt hook error messages now truncate overly long prompt text instead of embedding it in full

**What**

When a prompt hook's condition isn't met, the resulting blocking-error message now truncates the prompt command or label if it's too long, instead of always embedding the full raw prompt text.

**Why**

This keeps error messages from a prompt hook readable and prevents very long prompt text from bloating the error output.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Memory-sync 'empty file restored' notice suppressed for account-scoped memory

Notice about memory sync restoring empty files is now suppressed for account-scoped memory

**What**

Claude Code can warn users when memory sync restores a file that turned out to be empty (0 bytes) from shared memory storage. That notice is now routed through a helper that skips showing it entirely when the memory store's scope is "account".

**Why**

This avoids surfacing a notice about empty restored files in the account-scoped memory case, where it apparently isn't useful or applicable, cutting down on notifications that don't need the user's attention.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Public artifact-consent tracking distinguishes person-answered vs other consent

Artifact "always allow" consent checks now use a different lookup depending on whether a person or something else answered

**Unclear.** It's unclear what practical difference the two lookup helpers produce beyond using separate storage.

**What**

When Claude Code checks whether a previous "remember: always allow" decision covers a new artifact write or store request, it now looks at who gave that original consent. If a person answered, it uses one lookup helper; if the answer came from something else, such as an automated classifier, it uses a different one.

**Why**

Separating the two paths means consent given directly by a person is tracked separately from consent inferred automatically, which matters for making sure "always allow" only kicks in where it's actually safe to skip asking again.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact watch/attach status text simplified

The message shown after tracking an artifact version was reworded from a republish promise to a general statement

**What**

The confirmation text shown after attaching to a watched artifact or version was reworded. It no longer promises to notify the user specifically about republishing, and instead just states that Claude keeps track of new versions.

**Why**

The new wording is a more general description of what the tracking feature does, rather than a specific promise about republish notifications.

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

### More shell env vars blocked from bash tool

The bash tool now also blocks SHELLOPTS, BASHOPTS, BASH_VERSINFO, and BASH_ARGV0 environment variables

**What**

The list of environment variables the bash tool refuses to let a command set now also includes `SHELLOPTS`, `BASHOPTS`, `BASH_VERSINFO`, and `BASH_ARGV0`, in addition to the existing blocks on variables like `PS4` and `IFS`.

**Why**

These shell variables can change how bash itself parses and runs commands, for example turning on debugging or tracing options, so blocking them closes off ways a command could alter shell behavior unexpectedly.

- Area: Bash Safety
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### WAYLAND_DISPLAY now cleared alongside DISPLAY on Linux

Claude Code now clears WAYLAND_DISPLAY along with DISPLAY when forcing headless behavior on Linux

**What**

On Linux, when Claude Code strips graphical display environment variables to force headless or command-line browser behavior, it now clears `WAYLAND_DISPLAY` in addition to `DISPLAY`.

**Why**

This closes a gap where a Wayland desktop session could still cause graphical behavior to leak through even after `DISPLAY` was cleared, since Wayland systems use `WAYLAND_DISPLAY` instead of (or alongside) `DISPLAY`.

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

### Explicit allowGitTerminalPrompt control on git push operations

Git push commands now explicitly control whether they can prompt for terminal login

**What**

Internal git push operations now explicitly set `allowGitTerminalPrompt`, a setting that controls whether git is allowed to interactively prompt for credentials in the terminal. Background worktree pushes now have this disabled, while interactive plugin tag pushes have it enabled.

**Why**

This prevents background operations, like managing worktrees (separate working copies of a repository), from hanging on an invisible credential prompt, while still letting user-initiated actions like creating a plugin tag prompt for login when needed.

- Area: Git
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Ultraplan web-session wording changed to "cloud session"

Ultraplan now says "a cloud session" instead of "Claude Code on the web" in its prompts

**What**

User-facing text in Ultraplan, including the option to refine a plan and the startup message, was reworded from "Claude Code on the web" to "a cloud session."

**Why**

This is a wording change only; it does not change what Ultraplan does, just how it describes running elsewhere than the local machine.

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

### More bash reserved/protected variable names added

More bash variable and config key names are now protected from being overwritten

**What**

The list of protected bash shell variable and configuration names grew to include:

- `BASH_MONOSECONDS`

- `BASH_TRAPSIG`

- `BASH_SOURCE_PATH`

- `bash_cmds`

- `bash_aliases`

- `execignore`

- `bash_source_path`

**Why**

Protecting these names prevents Claude Code, or commands it runs, from accidentally overwriting bash internals or configuration keys that could break shell behavior.

- Area: Bash Safety
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### skipLowCreditsNote added to overage confirmation flow

A new skipLowCreditsNote flag now controls whether a low-credits note appears when confirming overage

**Unclear.** Exactly which flows count as "single-pass" and how the note's suppression is experienced by the user is not detailed in the finding.

**What**

When a user confirms going over their usage credits, a new `skipLowCreditsNote` flag is now computed (true when confirming and not in single-pass mode) and used to decide whether a low-credits note is shown.

**Why**

This avoids showing a redundant low-credits warning in situations where the user has already confirmed the overage outside of single-pass mode.

- Area: Elsewhere
- Names: `skipLowCreditsNote`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### OTEL raw request/response body dumping rewritten to atomic writes

OTEL debug logging of raw request/response bodies now writes files atomically instead of writing then handling errors after the fact

**What**

When Claude Code is configured to log raw request and response bodies for OpenTelemetry (OTEL, a standard for exporting logs and metrics), the internal code that writes those dump files now builds its file paths differently and writes the file using an atomic 'replace' operation, instead of writing the file directly and catching errors afterward.

**Why**

An atomic write means the file is either fully written or not written at all, which avoids leaving behind a half-written or corrupted dump file if the write is interrupted. This is an internal reliability fix for anyone relying on these OTEL debug logs.

- Area: Telemetry
- Names: `OTEL_LOG_RAW_API_BODIES`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### 403 handling in bearer-token auth retry now gated by Nk(s)

An extra check now gates whether a 403 response with a sent bearer token triggers an authentication retry

**Unclear.** What condition the new Nk(s) check actually verifies is not specified.

**What**

When a request fails with a 403 response after sending a bearer token (a type of authentication credential), Claude Code's retry logic previously retried whenever the token had been sent. It now also requires a new additional check, `Nk(s)`, to pass before retrying.

**Why**

This narrows when a 403-with-token failure is treated as retryable, though the finding doesn't specify what the new check verifies.

- Area: Auth
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### GitHub connect dialog copy changed to 'cloud sessions'

GitHub connection dialog now says 'Connect cloud sessions to GitHub?' instead of referencing 'Claude on the web'

**What**

The dialog shown when connecting GitHub now reads 'Connect cloud sessions to GitHub?', replacing earlier wording that asked about connecting 'Claude on the web' to GitHub.

**Why**

This is a wording update to the connection prompt, aligning its terminology with 'cloud sessions.'

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

### Worktree resume: git reset now uses '--' separator and per-directory env; new verified-worktree check gates fast-resume

Worktree fast-resume now checks the worktree is verified before resetting, and handles reset failure more safely

**What**

When resuming a git worktree (a separate working copy of a repository) quickly, the code now:

- builds its git environment per working directory instead of sharing one environment across worktrees

- adds a `--` separator to the `git reset --hard` command, which prevents a branch or ref name from being misread as a file path

- checks that the worktree is in a verified state with no pending marker before attempting the fast reset

- on reset failure, returns nothing and logs a warning instead of silently continuing as if the reset had worked

**Why**

These changes make worktree resume safer: a failed or unverified reset no longer proceeds silently, which could otherwise leave a worktree in an unexpected state without any warning.

- Area: Git Worktrees
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact read permission messages can now include an additional public-read admission note

Artifact read permission prompts can now include an extra note about public-read admission

**Unclear.** The finding does not say what the added clause's text says or exactly when it appears, only that a condition can trigger it.

**What**

The permission prompt Claude shows before reading an artifact ("Claude wants to read...") can now include an additional sentence under certain conditions, alongside existing flags used to build that prompt.

**Why**

This gives you more context in the permission prompt itself when a specific public-read condition applies, rather than a generic ask.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact auto_open guidance now excludes connector-backed types like Claude Docs

Claude is now told never to use auto_open after first write for connector-backed artifact types like Claude Docs

**What

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### MCP OAuth-token fallback now requires a design-server URL match

MCP OAuth-token reuse now also requires the server's URL to match design-connector rules

**What**

When Claude Code decides whether an SSE or HTTP MCP (Model Context Protocol) server can skip its own OAuth check because a suitable access token already exists, it now also requires that server's URL to match the design-connector check before falling back to a generic OAuth probe.

**Why**

This narrows when an existing access token can be reused to satisfy an MCP server's authentication, tying that shortcut specifically to design-connector servers rather than any server with a token available.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### OAuth failure messages during tool-triggered MCP connect now include richer context

OAuth failure messages from tool-triggered MCP connections now include richer context

**What**

When an OAuth authentication flow fails after being started by a tool call (for example, connecting to an MCP server), the error that gets logged and shown is now wrapped with additional context via a new helper before being reported, instead of showing the raw error text.

**Why**

This should make failures during tool-triggered OAuth connections easier to diagnose, since the reported error carries more context about what triggered it.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact watch wording clarified: no turns, no notifications from new versions

Artifact watch messages now clarify that new versions don't start a turn or send a notification

**What**

The text shown for an active artifact watch (`watch.watches`/`watch.status`) was reworded. It previously said the session would be "notified if it is republished elsewhere." It now says explicitly that a new version "starts no turn and sends no notification," and that the session merely "keeps track of" new versions published elsewhere.

**Why**

This clears up a possibly misleading implication that watching an artifact would actively alert you or interrupt the conversation when a new version appears. It now makes clear that watching only keeps a record, without triggering any action.

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

### First-party MCP auto-auth fallback narrowed to design servers requiring consent

Automatic MCP re-authentication using a stored design token now only applies to /v1/design/ server URLs, not other first-party servers

**What**

For first-party MCP (Model Context Protocol, the system Claude Code uses to talk to external tool servers) servers, Claude Code previously had a fallback that could automatically re-authenticate using a consent-gated callback for any first-party-looking server. Now that fallback only fires when the server's URL is https, first-party, and its path starts with `/v1/design/`. A separate check for what counts as a matching first-party URL was also widened to include a new `/v1/claude/test/` path, but the actual token-fallback behavior still only applies to `/v1/design/` URLs.

**Why**

This narrows automatic authentication so that other first-party MCP servers no longer silently pick up a stored design-related credential; only design servers get that fallback now.

Gate state

No sentence about `tengu_mcp_first_party_auto_auth` since nothing has been read about it yet.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### task_status system-reminder text now sanitizes task fields before insertion

Background task status messages now sanitize task fields before inserting them into the model's reminder text

**What**

When Claude Code reports the status of a background task or agent (running, stopped, a summary of changes, or an output path) back to the model as a system reminder, the task's description, id, type, and delta summary now pass through a sanitizing function before being inserted into that text.

**Why**

This guards against task data containing content that could otherwise be inserted unsafely into the text sent to the model.

- Area: Background Tasks
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### MCP credential-rejection reconnect now checks an explicit reason code

MCP reconnect-and-retry on credential failure now checks for a specific "credential_rejected" reason rather than any generic failure

**What**

When an MCP tool call fails, Claude Code has logic to clear the cached connection and retry once. This retry used to trigger on a generic boolean condition, but now it only triggers when the failure reason is specifically `credential_rejected`.

**Why**

This makes the reconnect-and-retry behavior more precise, so Claude Code only clears and retries the connection when the failure was actually a credential rejection, rather than any other kind of failure.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### --skip-lfs marketplace option documented as a no-op

The --skip-lfs marketplace option is now documented as having no effect, since Claude Code's git never downloads LFS content anyway

**What**

The description of the `skipLfs` marketplace add/update option was rewritten to say it now has no effect. Claude Code's own git never downloads Git LFS (Large File Storage) content regardless of this setting, and LFS-tracked files are always checked out as pointer files rather than their real content. The setting is still accepted so that existing configurations using it don't break. To get the actual LFS file content, a user needs to run `git lfs pull` manually inside the marketplace checkout.

**Why**

This clarifies that `skipLfs` is now purely a compatibility no-op, and tells users who need real LFS file contents that they must fetch them manually with `git lfs pull`.

- Area: Plugin Marketplace
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Slash-command/title extraction from transcript text now strips XML-like tags first

Session titling now strips XML-like tags before extracting slash commands from transcript text

**What**

The internal helper that pulls a slash command or bash-input line out of a stored message (used for things like naming a session or listing recent commands) now first runs the message text through a cleanup step that strips out matched `<tag>...</tag>` blocks, before it tries to extract the command with its usual pattern matching.

**Why**

Without this, leftover XML-like tags in a message could interfere with correctly detecting the slash command or bash input inside it, leading to wrong or missing session titles and recent-command entries.

- Area: Slash Commands
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact repeated-failure warning now exempts certain rejection reasons

Artifact tool's 'stop retrying' warning now skips certain rejection reasons

**Unclear.** The finding does not say which reasons are exempted or why.

**What**

When an Artifact tool call fails with the same reason three times in a row, Claude Code appends an escalating warning telling it to stop retrying. Now, before attaching that warning, it also checks that the failure reason isn't in a new exemption list, and skips the warning if it is.

**Why**

This prevents the "stop retrying" warning from being shown for certain failure reasons where it presumably isn't appropriate or useful.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### read_page_data now refuses on public, out-of-org artifacts

read_page_data now refuses to return data for public artifacts from outside your organization

**What**

The `read_page_data` action, which reads an artifact's structured page data, now explicitly refuses to return that data when the target artifact is a public artifact created outside the caller's organization. This returns a dedicated error with its own reason code instead of proceeding.

**Why**

This closes a gap where structured page data for public, out-of-org artifacts could otherwise be read that shouldn't be accessible here.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact egress probe now distinguishes 404 from 403

Artifact content-fetch probe now handles a 404 'not found' response alongside the existing 403 handling

**What**

Before fetching artifact content, Claude Code probes the content host to check if it's reachable. This probe previously only special-cased an HTTP 403 (forbidden) response to decide whether the host should be treated as reachable but access-denied. It now also handles an HTTP 404 response, checking for a plain-text media type and a 'not found' reason, alongside the existing forbidden-response check.

**Why**

This lets Claude Code distinguish a host that's reachable but denies access from one that reports the content simply doesn't exist, rather than treating both the same way.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### request_id validated with a strict pattern in control-protocol payloads

Bridge control-protocol messages now validate request_id against a strict pattern before forwarding it

**What**

Claude Code's bridge control-protocol message handling now includes a helper that only forwards a `request_id` field if it matches the pattern `req_` followed by 4 to 128 letters, digits, underscores, or hyphens. A companion helper checks whether a JSON payload textually contains a given key.

**Why**

Validating the shape of `request_id` before forwarding it guards against malformed or unexpected values being passed through the bridge's control-protocol messages.

- Area: Remote Control
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### CLI startup errors now carry a machine-readable startupFailureReason

Headless Claude Code errors now include a machine-readable startupFailureReason field like session_held_by_background

**What**

When a headless (non-interactive, `--print`) session fails to start, the JSON error output can now include a `startupFailureReason` field, for example `session_held_by_background` when another process already holds the session.

**Why**

This gives scripts and tools that parse Claude Code's JSON output a reliable, machine-readable code for why startup failed, instead of having to parse human-readable error text.

- Area: Headless Mode
- Names: `startupFailureReason`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Browser-selection tools gain onThisComputer / inUse hints

Browser list tool now flags which browser is running locally and which one actions currently target

**What**

The `list_connected_browsers` tool, which lists browsers connected to Claude Code, now carries two new pieces of information for each browser:

- `onThisComputer`: whether that browser is recently or currently running on this machine

- `inUse`: which browser session current actions are targeting

New helper text also tells the model which browser will be picked automatically versus which situations require asking the user to choose.

**Why**

This helps Claude Code pick the right browser automatically when it's obvious, and know when to ask the user instead of guessing, especially when multiple browsers are connected.

- Area: Chrome Control
- Names: `list_connected_browsers`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Builtin plugin availability now also respects prior load failures

Builtin plugins that previously failed to load are now also treated as unavailable

**What**

The check for whether a builtin plugin is enabled and available now also returns false if that plugin's name is recorded in a list of past load failures, in addition to the existing availability check.

**Why**

A builtin plugin that failed to load before is now consistently treated as unavailable, rather than potentially being retried or shown as usable when it previously failed.

- Area: Plugins
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Postgres query gains an explicit statement timeout under a wrapped transaction

A Postgres query now runs with an explicit 2-second statement timeout inside a wrapped transaction

**What**

A rewritten internal database query helper now wraps its work in an explicit transaction: `BEGIN`, then `SET LOCAL statement_timeout = '2s'`, then `COMMIT`, run with `Promise.allSettled` and an abort check before it even starts. This replaces an older version that made a single call without this wrapping.

**Why**

This puts a hard 2-second cap on how long this particular database query can run, preventing it from hanging indefinitely and holding up whatever depends on its result.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### --force-remove-worktree help text now mentions submodules

--force-remove-worktree help text now clarifies its 'no uncommitted changes' rule covers submodules too

**What**

The command-line help text for `--force-remove-worktree` now clarifies that its safety requirement of having no uncommitted changes applies to tracked files, including submodules.

**Why**

This makes the existing safety rule clearer, so users understand that submodule changes count toward blocking a forced worktree removal, not just changes to regular tracked files.

- Area: Git Worktrees
- Tier: You'll notice
- Useful: 1/5
- Signal: 0/5

### Permission approval message for copied files simplified

The approval prompt for copying local files dropped its "so only you can approve this" wording

**What**

When Claude Code asks for your approval before copying local files, the message it shows has been reworded. It used to end with a phrase explaining that the approval step exists so only you can approve the action; now it just lists the files and ends with a period.

**Why**

This is a wording tweak to the permission prompt you see when Claude Code needs your OK to copy files. The approval step itself works the same; only the phrasing changed.

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

### Worktree cleanup git calls now pin an explicit --git-dir

Worktree cleanup git commands now explicitly pin the git directory instead of relying on current folder

**What**

The logic that removes or verifies worktrees (used when exiting or cleaning one up) now resolves the git directory up front and passes it explicitly via `--git-dir` to every subsequent `git worktree list` and `git worktree remove` command, instead of letting git discover it based on the current working directory.

**Why**

This makes worktree cleanup more reliable by pointing git at the correct repository directly, avoiding cases where relying on the current directory could pick the wrong git directory.

- Area: Git Worktrees
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Policy-helper refresh failures no longer re-announce a tier change on every retry

Repeated policy-refresh failures no longer re-fire a tier-change notification on every retry

**What**

When Claude Code's background policy-settings refresh fails repeatedly with the same error code, it now only announces a tier change (an internal `policySettings` change event) the first time that failure code appears, instead of re-announcing it on every retry attempt.

**Why**

This cuts down on repeated, redundant change notifications when a policy refresh is stuck failing for the same reason, so downstream listeners aren't flooded with duplicate events.

- Area: Managed Settings
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Git diff baseline for cloud/session diffing now computed lazily

Git diff baseline for cloud/session diffing is now computed lazily on first use instead of upfront

**What**

The object that computes diffs against a baseline (used for cloud sessions and session diffing) used to compute that baseline immediately when created. It now computes the baseline only once, the first time a diff is actually requested, and a related lookup path can explicitly skip computing it altogether.

**Why**

This avoids doing potentially unnecessary work up front when a diff baseline is never actually needed, which should make constructing these diff sources cheaper in cases where no diff is fetched.

- Area: Cloud Sessions
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

## Bug Fixes

### Orphaned background-task recovery on resume now restricted to remote transport

Recovering interrupted background tasks on restart now requires a remote session

**Unclear.** The finding doesn't say why recovery is now restricted to remote sessions specifically, only that the condition was added.

**What

On startup, Claude Code can recover background tasks that were still running when a previous session was interrupted, controlled by the `CLAUDE_CODE_RESUME_INTERRUPTED_TURN` setting. This recovery now also requires that the session is using remote transport, meaning it won't attempt this recovery for local sessions.

**Why

This narrows automatic recovery of interrupted background work to remote sessions, presumably because that's where recovering an orphaned task makes sense; local sessions no longer attempt it.

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

### Global config read errors now surface instead of being silently swallowed

Errors reading the global config file are now shown instead of being silently hidden

**What**

The function that reads account login information (`oauthAccount`) from Claude Code's global configuration file now throws explicit errors, 'global config not readable through storage' and 'global config not parseable', when something goes wrong. Previously, any error in this process was caught and the function simply returned nothing, without explaining why.

**Why**

Surfacing the actual error makes it much easier to diagnose problems with a corrupted or inaccessible config file, instead of silently behaving as if no account were logged in.

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

### OAuth device-flow login handles 'slow_down' rate limiting

Login now shows a clear message when sign-in attempts are being rate-limited

**What**

When logging in via the device-code flow (the "go to this URL and enter this code" sign-in method), Claude Code now detects a `slow_down` response from the server and shows "The gateway is limiting sign-in attempts right now. Wait a few minutes and try again," instead of a generic error.

**Why**

This gives a clear, actionable message when sign-in is being rate-limited, instead of a confusing generic failure.

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

### File-publish source verification hardened against symlink/hardlink spoofing, with an explicit refusal path

File-publish source verification now has a dedicated refusal for files it can't safely confirm, guarding against symlink spoofing

**What**

Before publishing a staged file, Claude Code verifies that the source file is what it appears to be. This check now uses a dedicated refusal response when a file's path can't be safely verified, for example because a symbolic or hard link makes the true source unclear. Previously this case was handled by a separate, duplicated deny object.

**Why**

This hardens the publish path against symlink or hardlink tricks that could otherwise be used to substitute a different file than the one that was actually staged.

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

### Plugin sync now tolerates unsettled remote managed-plugin config

Plugin config sync no longer drops managed plugin entries when remote policy settings haven't caught up yet

**What**

When Claude Code syncs its `installed_plugins.json` file, it now checks whether a plugin's remote-managed policy has simply not settled yet, and if so, keeps that plugin's managed entry instead of dropping it as orphaned. It logs a specific message, "Remote managed settings not settled; keeping managed record(s) for...", in this case.

**Why**

This avoids incorrectly discarding managed plugin records due to a temporary lag in remote policy settings, which could otherwise cause plugins to appear unmanaged or missing.

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

### Ink renderer: scroll-hint fast-path now avoided when absolute-positioned overlays are present

Ink's terminal renderer skips a scroll shortcut when overlay elements are on screen

**What**

Claude Code's terminal UI is built with a rendering library (Ink) that has a performance shortcut for scrollable boxes: instead of redrawing everything, it can just shift existing content up or down. That shortcut is now skipped whenever the box overlaps with an absolutely-positioned element (like a popup or overlay) that was present in the previous frame.

**Why**

This avoids visual glitches where an overlay would be left behind or drawn incorrectly when the terminal tried to take the fast scrolling path instead of a full redraw.

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

### Fork-conversation now rejects targets that split a tool call

Forking a conversation now refuses fork points that would split a tool call from its result

**What**

When forking a conversation at a specific message, Claude Code now checks whether that fork point would separate a tool call (`tool_use`) from its result (`tool_result`). If it would, the fork is refused with an error instead of proceeding.

**Why**

This prevents creating a forked conversation whose transcript would be invalid because a tool call is missing its matching result.

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

### TUI hit-testing now respects overflow:hidden/scroll clipping

Clicking in the terminal UI no longer registers hits on elements clipped outside their scrollable or hidden container

**What**

In Claude Code's terminal interface, figuring out what you clicked on now respects `overflow:hidden` and `overflow:scroll` styling. If you click at a spot that falls outside a container's visible box on an axis where that container hides or scrolls its overflow, Claude Code no longer looks inside that container for something to match, even if a child element is technically positioned there.

**Why**

Before this, a click could accidentally register on a child element that was rendered outside the visible, clipped area of its parent (for example, scrolled out of view), causing clicks to land on the wrong thing. Now clicks only match what's actually visible.

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

### Git-worktree safety vetting: relative gitdir path check reworked

Worktree safety check for the 'gitdir' pointer file was reworked to correctly detect unsafe relative paths

**What**

The routine that validates a worktree's `gitdir` pointer file, used to decide whether it's safe to treat as a real git directory, now normalizes the path relative to the repository's common directory before checking it for `..` or `.` segments. This replaces a previous check that appeared buggy, since it searched the wrong variable (`r`) instead of the freshly-split path.

**Why**

This fixes a worktree safety check so that suspicious relative paths in a `gitdir` file (the kind git itself would not normally write) are properly detected, reducing the chance of treating an unsafe location as a legitimate git directory.

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

### Cancelled composer text now filters/normalizes leading '/' commands separately

Cancelling a queued message now avoids accidentally turning its text into a slash command

**What**

When you cancel a message that was queued up in the composer, Claude Code puts its text back for you to edit. That text now goes through a cleanup step that normalizes things like image placeholders. If that cleanup happens to make the text start with a `/` (which would make Claude Code treat it as a slash command) but the original raw text didn't start with `/`, Claude Code now keeps the original raw text instead.

**Why**

This prevents a queued message from being misinterpreted as a slash command just because of how its text was cleaned up, which could otherwise trigger unintended command behavior when a cancelled message is restored.

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

### New device-ID validation before trusting bridge/session peer

Device IDs are now validated against a pattern before being trusted for bridge/session connections

**What**

When a device ID is used to identify a peer (another connected device or session, such as over a bridge connection), Claude Code now checks it against a regular expression before accepting it. This applies both to the general device-ID validity check and to the step that pushes external configuration to a peer. Previously any non-empty string was accepted as a valid device ID.

**Why**

This stops malformed device IDs from being treated as valid, which could otherwise let unexpected or malformed values flow into peer connections and configuration syncing.

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

### Long-running proxied requests now suppress fetch's own timeout

Very long proxied requests can now skip the HTTP client's own timeout when a longer timeout is requested

**What**

Two internal network request helpers now disable the underlying HTTP client's built-in timeout whenever the caller asks for a timeout longer than 300000 milliseconds (5 minutes). Previously, the client's own timeout could still cut the request short even when a longer timeout was requested.

**Why**

This lets requests that are meant to run for a long time, such as slow or heavily proxied operations, actually run that long, instead of being cut off by a timeout mechanism the caller never intended to trigger.

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

### Worktree keep/reap dirty-check reworked around .git existence

Worktree cleanup now checks whether the .git file still exists before assuming a worktree is safe to remove

**What**

The internal function that decides whether to keep or discard a git worktree (a separate working copy of a repository) now checks whether the worktree's `.git` file still exists before treating it as clean. Previously, the fast path assumed a worktree was clean whenever it had no recorded head commit, without this check.

**Why**

This avoids incorrectly treating a worktree as safe to discard just because its head commit info is missing, reducing the risk of losing work in edge cases where the worktree's git link is in an unusual state.

- Area: Git Worktrees
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Draft restoration now preserves pasted-content mode correctly

Restoring a saved draft now correctly preserves pasted content only for prompt-mode drafts

**What**

When Claude Code restores a previously saved draft of your input (for example after using summarize or undo), it now checks what kind of draft it is:

- `prompt` drafts are re-parsed so any pasted-content placeholders are correctly restored

- other kinds of drafts, such as bash input, keep their raw text and are treated as having no pasted content

- the function that restores pasted content is only called when there is actually pasted content to restore

**Why**

Previously, restoring a draft could mishandle pasted content depending on the draft's mode. This fix makes sure pasted text (like a block of code or file contents you pasted in) comes back correctly when you return to a prompt draft, without incorrectly applying pasted-content logic to non-prompt drafts like bash commands.

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

### File chunk reads no longer split a multi-byte UTF-8 character at the boundary

File chunk reads no longer cut a multi-byte character in half at the boundary

**What**

When Claude Code reads a file in chunks (for example, reading just the end of a large file), it now checks up to 3 bytes before a chunk boundary to see whether it would split a multi-byte UTF-8 character (used for non-ASCII text like accented letters, emoji, or non-Latin scripts) in half. If so, the chunk is trimmed to avoid cutting the character apart. It also strips a leftover byte that can result from a byte-order-mark (a marker some files use at the start to indicate text encoding).

**Why**

Previously, reading a chunk of a file could end mid-character, producing garbled or invalid text in the output. This fix ensures chunked file reads always end on a clean character boundary.

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

### Stdio MCP servers that exit mid-initialize after a probe timeout now get one restart

Stdio MCP servers that exit right after a startup probe times out now get one automatic restart

**What**

When Claude Code connects to an MCP server over stdio (standard input/output, used for local server processes), it sometimes runs a version-negotiation probe first. If that probe times out and the server process then closes while still initializing, Claude Code now recognizes this specific pattern - a likely slow-starting server that exits on requests sent before it's ready - and restarts the server once without the probe, using whatever time is left in the connection budget.

Previously, only a different failure (a version-negotiation error causing the connection to close) triggered a stdio server restart; a probe-timeout-induced close was not handled.

**Why**

This reduces false failures for MCP servers that are simply slow to start up, giving them a second chance to connect properly instead of failing outright.

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

### Many-image dimension error no longer suggests /compact when compaction is disabled

Image-too-large error stops suggesting /compact when compaction is disabled

**What

When an image in your conversation exceeds the size limit for many-image requests (2000px), Claude Code normally tells you to run `/compact` to remove old images from context. Now it checks whether compaction has been disabled (via the `DISABLE_COMPACT` environment variable) first, and if so, tells you to start a new session instead of suggesting `/compact`.

**Why**

This avoids pointing you to a command that won't work if compaction has been turned off, giving you a suggestion that will actually resolve the problem.

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

### Bug fix: artifact-bundle text extraction used the wrong loop variable

Fixed a bug where artifact text extraction always checked the same wrong item

**What

When building the list of text content for an artifact's initial bundle, the code that extracts `text` fields from a list of items had a bug: it referenced the outer loop variable instead of the current item being processed, so it effectively checked the same item repeatedly rather than each item in turn. This has been fixed to correctly reference each item.

**Why

This bug could have caused artifact text content to be extracted incorrectly or incompletely; the fix ensures each item in the list is actually checked for its own text content.

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

### Worktree cleanup gains an extra path-resolution step before chdir/removal

Worktree cleanup now resolves the worktree path with a fallback before using it

**What**

When cleaning up a git worktree, the code now computes a resolved version of the worktree path (falling back to the original path if resolution fails) before proceeding, and uses that resolved path consistently in the subsequent steps, including changing directory and running `git worktree remove`.

**Why**

This makes worktree cleanup more robust in cases where the raw path and its resolved form differ.

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

### OTEL raw API body writer now guards against symlink/hardlink tampering

OTEL raw API body logging now refuses to write if the target file is a symlink, has multiple hard links, or changes identity mid-write

**What**

When the `OTEL_LOG_RAW_API_BODIES` setting is on, Claude Code writes raw API request and response bodies to a file for telemetry. That writer now checks the target file's identity, its device and inode numbers, both before and after opening it, and refuses to write if the file isn't a regular file with a single hard link, has multiple hard links, is a symlink, or changed identity between the check and the write. It throws errors like "OTEL raw body target is not a regular single-link file; not writing" or "...changed identity around the open; not writing" instead of writing in those cases.

**Why**

This prevents the raw-body log file from being tampered with via a symlink or hardlink swap between the check and the actual write, which could otherwise let API request or response content leak to, or be manipulated at, an unintended location.

- Area: Telemetry
- Names: `OTEL_LOG_RAW_API_BODIES`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### IDE lockfile discovery also checks the home directory when cwd is blank

IDE lockfile discovery now also checks the home directory when the working directory is blank

**What**

Claude Code scans certain directories to discover IDE lockfiles (used to detect a running IDE integration). That scan already included the home `.claude/ide` directory when `CLAUDE_CONFIG_DIR` was set; it now also includes it whenever the resolved working directory is an empty string.

**Why**

This closes a gap where IDE lockfile discovery could miss the home directory location in cases where no working directory was resolved, helping the IDE integration connect reliably in more situations.

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

### file: URL resolver now also normalizes bare absolute paths

The file: URL resolver now also accepts plain absolute paths, not just file:// URIs

**What**

The internal function that converts `file://` URLs into filesystem paths now also accepts plain paths that already start with `/`, as long as they aren't already recognized in another form, rather than requiring a full `file:` URI.

**Why**

This means code paths that expect a `file:` URL will now also correctly handle a bare absolute path being passed in, instead of failing or mishandling it.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### HIPAA cache restamp now checks a session-generation token

HIPAA cache restamping now checks a session-generation token to avoid stale writes

**What**

The function that restamps the HIPAA-related cache (`restampConfirmedCache`) now takes a new session-generation parameter, and checks it twice: once before and once after performing an asynchronous write. If the current session generation doesn't match the one passed in, the restamp bails out.

**Why**

This prevents a restamp write from a superseded, older session generation from landing late and overwriting the cache with stale data after a newer session generation has already taken over.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Auth middleware now clears pending step-up on a fresh 401, and skips unauthenticated requests

Auth middleware now clears pending step-up verification on a fresh 401 and ignores requests with no Authorization header

**What**

The internal API code that watches for authentication challenges was updated in three ways:

- It now ignores responses to requests that had no `Authorization` header at all.

- It parses the scope from the `WWW-Authenticate` response header using a shared helper function instead of an inline regular expression.

- It now explicitly clears any pending 'step-up' authentication requirement when it sees a 401 response (as opposed to a 403).

**Why**

These changes make the authentication-challenge handling more precise, avoiding reactions to unauthenticated requests and ensuring a stale step-up requirement doesn't linger once a fresh 401 is seen.

- Area: Auth
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Bash-input command extraction bug fix

Fixed a bug where extracting a bash command from message text checked the wrong variable

**What**

Claude Code has an internal helper that looks for a fallback bash command embedded in message text (inside `<bash-input>` tags). It was mistakenly checking an outdated variable left over from a previous loop iteration instead of the current one, so it could look at stale text. It now consistently checks the correct, current text.

**Why**

This fixes a bug that could cause the wrong bash command to be extracted from a message, since the check was looking at leftover data instead of the actual current input.

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

### Extraction-swap failure path now distinguishes a superseded extraction from a genuine restore failure

Failed extraction restores now tell you if the backup was superseded rather than truly broken

**What**

Claude Code installs plugins and tools by swapping in a new "extraction" (an unpacked copy of the files) and moving the old one aside as a backup. If that swap fails and the code tries to restore the old backup, it now first checks whether a newer extraction has already been put in place. If so, it reports that a newer extraction is live and the backup was simply moved aside, instead of reporting a generic restore failure.

**Why**

This prevents a confusing false alarm: previously any error thrown while restoring the backup was treated as "could not restore," even when the real story was that a newer version had already taken over and restoring the old one wasn't needed or possible. The new message tells you what actually happened.

- Area: Plugins
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Frame tunnel auth switched from 'none' to 'session-jwt'

Frame/tunnel requests now authenticate with a session JWT instead of no authentication

**What**

An internal helper used for frame or tunnel requests now authenticates using `session-jwt` (a signed session token) rather than sending no authentication at all.

**Why**

Requiring a valid session token instead of allowing unauthenticated requests makes this internal communication path more secure.

- Area: Permissions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Branch checkout commands now use `--` end-of-options guard

Branch checkout git commands now add a trailing -- to prevent branch names being misread as options

**What**

Git `checkout` commands run internally, including plain checkout, checkout with a new branch tracking a remote, and checkout tracking a remote branch, now append a trailing `--` argument.

**Why**

The `--` tells git that everything after it is a file or branch name, not an option flag. This prevents a branch name that happens to look like a flag (for example, one starting with a dash) from being misinterpreted as a git option.

- Area: Git
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Ordered-list markdown rendering preserves the original marker punctuation

Ordered markdown lists now keep their original marker style, like '1)' versus '1.', when re-rendered

**What**

When Claude Code re-serializes an ordered (numbered) list item back into markdown text, it now tries to reuse the original list marker punctuation captured from the raw source text — for example keeping `1)` as `1)` rather than converting it to `1.` — and only falls back to a computed numbering scheme if the original marker isn't available.

**Why**

This preserves the original formatting style of numbered lists instead of silently normalizing all markers to the same punctuation.

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

### Design-consent 403 handling scoped to first-party design MCP URLs only

Design-consent error handling now only triggers for genuine first-party design MCP requests

**What**

When a request to the design MCP server (used for design-related integrations) fails with a 403 error, Claude Code turns that into a "needs consent" error. Now it only does this after also confirming the request actually went to the first-party design MCP endpoint, rather than reacting to any 403 with a matching token.

**Why**

This prevents the consent-error handling from firing on unrelated 403 responses that happen to look similar, keeping the consent prompt tied specifically to the real design MCP service.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Parked-permission strict-answer handling gets a clearing step and new outcomes

Parked permission approvals now clear pending state first, with new outcomes if that fails

**What**

When Claude Code resolves a previously saved ("parked") permission answer, it now performs an additional clearing step before applying the answer, and tracks a flag to avoid race conditions during that process. If the clearing step can't be confirmed, the answer is now dropped, recorded under new outcome labels such as `clear_pending` and `clear_unconfirmed`.

**Why**

This is meant to prevent a stale or conflicting permission state from being acted on incorrectly, at the cost of sometimes dropping an answer if the system can't confirm it's safe to apply.

- Area: Permissions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Project-thread messages now track a text hash to detect edited/resent content

Project-thread message dedup now hashes message text, so an edited message with the same id and timestamp is treated as new

**What**

When Claude Code decides whether a project-thread message notification needs re-processing, it used to key on the message's id and timestamp alone. It now also computes and stores a hash of the message's text, so if a message with the same id and timestamp arrives but its text has changed (an edit or resend), it's no longer mistaken for one already seen. The same text-hash comparison was added to a companion path that handles shared state for other comments.

**Why**

This prevents edited or resent project-thread messages from being silently ignored just because their id and timestamp didn't change.

- Area: Projects
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### SSE transport reconnect: fixed stale-variable bugs in header refresh and retry logging

Fixed a bug where refreshed auth headers weren't actually applied on SSE reconnect, and retry logs showed the wrong status

**What**

When Claude Code's SSE (Server-Sent Events, a streaming connection type) transport reconnects, it refreshes authentication headers, but a bug meant the freshly computed headers weren't actually applied to the request — an undefined or stale variable was used instead. This is now fixed so the real refreshed headers are assigned. A related bug in POST-retry logging and telemetry, where the logged response status or error came from a mismatched variable left over from a previous iteration, is also fixed to report the actual current status.

**Why**

Before this fix, a reconnecting SSE connection could silently keep using stale credentials, and retry logs could report misleading status information, both of which made connection problems harder to diagnose.

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

### Staged file-list credential fetch hardened against reuse and cancellation

Staged file-list credential handling now blocks reuse and cancellation of the fetch

**What**

The internal worker code that fetches the list of staged files and parses the credentials for it was hardened. The fetch can now be cancelled with an `AbortSignal` (a standard way to stop an in-progress operation), and the credential-parsing step is wrapped by a single-use guard: if it is somehow triggered a second time, it fails immediately with the error `read failed: credential expired` instead of proceeding.

**Why**

This closes off a case where stale or reused credentials could be parsed twice, which could otherwise lead to confusing failures or wasted work. It also lets this internal fetch be cancelled cleanly if it's no longer needed.

- Area: Sessions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### MCP OAuth step-up-pending state is now cleared when the underlying credential disappears

MCP OAuth now clears a pending step-up permission flag when its credential is gone

**What**

When Claude Code's MCP (Model Context Protocol) OAuth token-refresh logic detects that a token is missing, has no access token in storage, or expired without a refresh token, it now also clears any pending "step-up" flag, which marks a request to escalate permission scope. This clearing is skipped if redirect handling is enabled.

**Why**

This prevents a stale step-up-pending state from lingering after the credential it was tied to has already disappeared.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### MCP OAuth step-up scope tracking now conditioned on the outbound request actually carrying credentials

MCP OAuth step-up auth no longer triggers on requests that had no credentials to begin with

**What**

When connecting to an MCP (Model Context Protocol) server that requires extra permission ('step-up' authentication) after a 403 'insufficient_scope' response, Claude Code now checks first whether the original request even carried an `Authorization` header. If it didn't, the step-up flow no longer triggers. Separately, a 401 response now clears any step-up scope that was pending.

**Why**

This avoids incorrectly starting a step-up authentication flow for requests that were never authenticated in the first place, and prevents a stale pending permission request from lingering after a 401 unauthorized response.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### OAuth pendingStepUpScope reset now conditioned on handleRedirection

Clearing the pending OAuth step-up scope on token save now only happens when handleRedirection is set

**What**

When Claude Code saves or refreshes an MCP (Model Context Protocol) OAuth token, it can clear a stored `_pendingStepUpScope` value, which tracks a scope the user still needs to re-authorize. This clearing used to happen unconditionally on token save, or on any change to the access token, at two different call sites. Both now only clear it `if (this.handleRedirection)`.

**Why**

This avoids discarding a pending re-authorization request in situations that aren't actually handling a redirect, so a scope still waiting on the user's approval isn't silently forgotten.

- Area: Auth
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Artifact file admission now resolves the 'from' path for object-form file entries

Internal artifact file checks now read the source path from the new object-style file entries

**What**

The internal logic that checks artifact files for problems like path traversal or exceeding size limits now correctly reads the source path from the `from` field when a file entry is given as an object, rather than only handling a plain path string.

**Why**

This keeps the existing safety checks (against path traversal and oversized files) working correctly now that file entries can be specified as objects with a separate content type, as introduced alongside this change.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Artifact-type discovery prompt text lost an appended trailing addendum in one branch

A trailing addendum text that used to be appended to the quickstart artifact-type description was dropped in one code path

**Unclear.** What the dropped trailing string said or what practical difference its absence makes is not shown by the finding.

**What**

The functions that build the Artifact-type description text for "quickstart" mode lost a parameter, and along with it, a conditional trailing string that used to sometimes be appended to the end of the quickstart description.

**Why**

The finding doesn't say what the dropped text contained or what effect losing it has, only that this particular addendum is no longer appended in this branch.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Bug fix: bare-git-repo scrub used mismatched variable when falling back to a directory check

Bug fix: bare-git-repo path scrubbing now checks and acts on the same variable

**What**

In the logic that scrubs file paths for bare git repositories, a fallback directory check was comparing one variable but then acting on a different one, inconsistent with the surrounding code. This has been fixed so the check and the resulting action both use the same path variable.

**Why**

This fixes a mismatch that could have caused the wrong path to be checked or acted upon during path scrubbing.

- Area: Git Security
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Overflow clipping added for positioned/absolute-styled teleport components

Teleport UI components with absolutely-positioned elements now clip overflow to prevent visual spillover

**What**

A generic wrapper used to render teleport-related components now checks whether the view isn't fullscreen (or is a static frame) and whether the component tree being rendered contains elements styled with absolute or fixed positioning. When both are true, it sets `overflow: hidden` on the rendered output, clipping anything that would otherwise spill outside its bounds.

**Why**

This prevents absolutely-positioned elements in teleport-related screens from visually overflowing or overlapping other content when not shown fullscreen.

- Area: Git Teleport
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

## In Development

### Projects thread-reply "lead" markers, gated by a killswitch that defaults off

Claude Code Projects threads can now label replies as sent directly, relayed, or from the project timeline

**Unclear.** Whether this labeling is active for any given account is unknown, since nothing has been read yet about the `tengu_projects_thread_reply_lead_killswitch` gate that controls it.

**What**

A new block of prompt-construction logic builds explanatory 'lead' text that distinguishes project messages sent directly in a Claude Code Projects thread from ones relayed through a coordinator session, or written on the project's timeline. It's wired into message formatting through a new parameter that, when set, routes the message through this new branching logic.

**Why**

This is meant to make it clearer, when reading a Projects thread, where each message actually came from.

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

### Compaction can now keep a tail-announcement summary of key attachments across a compact boundary

Compaction can now carry forward a short summary of key attachments across the compaction boundary

**Unclear.** Whether the `tengu_calm_noodle` gate is active for any account hasn't been read, so nothing can be said about whether this behavior runs anywhere yet.

**What**

When a conversation is compacted (its history condensed to save space), Claude Code can now build a short 'kept tail' summary noting which key attachments, such as instructions, session context, coordinator context, context sections, and date attachments, were carried forward past the compaction point. This emits a `compact_kept_tail_announcements` telemetry event recording whether it was enabled, where it was placed, and which types were kept. If a related feature flag check fails, it bails out early and records `enabled:false`.

**Why**

This makes it possible to track, and eventually improve, how well important context survives compaction instead of silently being dropped or duplicated.

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

### Public (non-member) artifact reads now conditionally admitted

Public, non-member reads of artifact content are now gated and flagged separately from relay reads

**Unclear.** It is not known whether this gate is currently enabled for any account, since no reading has been taken under this release yet.

**What**

When someone without membership access (a "public" or tokenless reader) tries to read an artifact's content or files, Claude Code now checks a permission gate before allowing it. If the check fails, it returns a "tokenless" error; if it passes, the result is now marked with a `publicRead` flag, separate from the existing `relay` flag.

**Why**

This adds a controllable checkpoint for public, non-member artifact reads, so this kind of access can be turned on or off independently of other read paths.

- Flag `tengu_cobalt_plinth_sedge`: Off by default, switched on for this account (read for one account on one subscription tier against v2.1.274; 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
- Names: `tengu_cobalt_plinth_sedge`
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### New task-notification coalescing path in the queued-message engine, gated off by default (compiled)

New option lets a background task notification merge into the current turn instead of interrupting it

**Unclear.** Whether `tengu_swirling_meteor` is switched on for any account has not been read; nothing is known about its current state.

**What**

A new `coalesceTaskNotifications` option was added to the part of Claude Code that manages queued messages during a session. When enabled, a background task notification that is short enough can be merged into the turn that's already pending, instead of being dispatched as its own separate interruption.

**Why**

This is controlled by the `tengu_swirling_meteor` setting, which hasn't been read for this site's account yet, so it's not known whether it's active here.

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

### Automounter-lookup path refusal exists but nothing turns it on

New code can refuse macOS automounter-lookup paths, but nothing in this build turns it on

**What**

A new internal permission check can refuse to read a file path if it looks like a macOS "automounter" lookup path, such as the `/Network` browse root or an `auto_home` entry, with its own denial message and reason code. However, this check only runs when an optional setting called `refuseAutomounterShapes` is passed in, and the only place in the codebase that calls this check never passes that setting, so the new refusal never actually triggers.

**Why**

This is dormant code: the capability exists internally, but no path in this build exercises it, so it has no effect on current behavior yet.

- Area: Filesystem Security
- Names: `refuseAutomounterShapes`
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 3/5
- Present in the build but not switched on

### Cross-boundary policy identity change can be deferred instead of forcing reload

Identity changes mid-session can now defer a policy reload instead of immediately reloading as an account change

**What**

When the credential identity (principal) behind a session changes mid-session, Claude Code can now, in a new gated code path, keep using the currently loaded policy verdict while fetching the new principal's policy in the background, instead of immediately reloading everything as if the account had changed. It handles two cases differently: one where a policy check is already in flight (marking a `principalCheckOwed` flag) and one where things have settled, in which case it fetches the new policy while keeping the old verdict active in the meantime.

**Why**

This is a mechanism to avoid disruptive, immediate policy reloads triggered by mid-session identity changes. Its associated gate `tengu_steady_marshmallow` returned off for this site's account and off for the anonymous baseline, and no reading has been taken under this release yet; the related gate `tengu_policy_limits_principal_changed` hasn't been read at all, which is not the same as being off.

- Flag `tengu_steady_marshmallow`: Off in both readings (read for one account on one subscription tier against v2.1.274; 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: Policy
- Names: `tengu_steady_marshmallow`
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 3/5
- Present in the build but not switched on

### New pasted-content trust-boundary note gated behind tengu_virtual_pancake

New system-prompt note warns Claude that pasted content may carry instructions the user didn't write

**Unclear.** Gate `tengu_virtual_pancake` controls this, but nothing has been read about whether it's on for any account, including this site's.

**What**

Claude Code's system prompt (the instructions that shape how Claude behaves during a session) can now include an extra note about pasted content. It explains that text wrapped in pasted-content tags may contain instructions the user themselves didn't write, and that Claude should only follow such instructions where the user's own message actually asks for that. It also tells Claude never to mention the wrapping tag's random id to the user.

**Why**

This is a safeguard against pasted text (for example, copied from a webpage or document) smuggling in instructions that look like they come from the user but don't. Whether this note is currently active depends on server-side rollout, which isn't visible here.

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

### MCP connect-timeout retry and legacy SSE fallback gates referenced

MCP connection code references two settings controlling connect-timeout retries and legacy SSE fallback

**What**

MCP (Model Context Protocol) connection handling now references two settings: `tengu_mcp_connect_timeout_retry`, which controls whether a connection timeout is treated as something worth retrying, and `tengu_mcp_legacy_sse_fallback`, which controls whether Claude Code falls back to the older HTTP+SSE (Server-Sent Events) connection style when a server rejects its initial connection request.

**Why**

These give Claude Code more resilient fallback behavior when an MCP server times out or doesn't support the newer connection method, though no reading of either setting's current value is available yet for this account.

- Flag `tengu_mcp_connect_timeout_retry`: Not enough to say (read for one account on one subscription tier against v2.1.274; 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_mcp_legacy_sse_fallback`: Not enough to say (read for one account on one subscription tier against v2.1.274; this account: no value returned, anonymous baseline: no value returned, compiled default: on) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.
- Area: MCP
- Names: `tengu_mcp_connect_timeout_retry`, `tengu_mcp_legacy_sse_fallback`
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 3/5
- Present in the build but not switched on

### New stdio MCP protocol-negotiation gate added

A new gate lets stdio MCP connections also try the newer protocol-negotiation handshake

**What**

MCP servers connected via stdio (standard input/output, a local process-based connection type) can now use the same automatic protocol-version negotiation that other connection types have, including their own probe timeout setting, instead of always using the older legacy handshake.

**Why**

This extends newer protocol-negotiation support to stdio-based MCP servers, though it is controlled by a gate that determines whether it's actually turned on for a given account.

- Flag `tengu_mcp_protocol_negotiation_stdio`: Off in both readings (read for one account on one subscription tier against v2.1.274; 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: MCP
- Names: `tengu_mcp_protocol_negotiation_stdio`
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 3/5
- Present in the build but not switched on

### Large new block of prompt logic for project-thread replies sent directly "in this thread"

Claude Code now distinguishes messages sent directly in the current thread from ones relayed through a coordinator or thread-fetch tool

**What**

Claude Code builds prompt text explaining to the agent how a project member's message reached it. Previously this covered two cases: a message relayed through a coordinator session, or one returned from a thread-fetch tool. A large new block of logic adds a third case: a message the person sent directly in the current thread, which is now explicitly labeled as "sent here, not relayed".

**Why**

This lets the agent tell apart messages that arrived directly in the ongoing conversation from ones that were relayed or fetched from elsewhere, which can matter for how it responds.

Gate state

No sentence about `tengu_projects_thread_reply_lead_killswitch` since nothing has been read about it yet.

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

### Elevated device-bind tier request with retry-on-rejection

Session device-binding can now request an elevated security tier, retrying without it if the server rejects the request

**What**

When creating a device-bound session, Claude Code can now ask the server for an 'elevated' security tier as part of an 'ask' proof-header flow. If the server rejects that elevated request with a 4xx error, the client logs the reason and retries the same bound-session creation without asking for elevation. A new telemetry event, `cloud_elevated_create`, records whether the elevation request was honored, unsupported, or refused, distinguishing reasons like an untrusted device or an unavailable device check.

**Why**

This lets Claude Code opportunistically request a stronger security tier for a device-bound session while still falling back gracefully and completing the session setup if the server can't or won't grant it.

Gate state

No sentence about `tengu_breezy_fairy` on/off for this release; the finding notes it read off for this site's account and off for the anonymous baseline, with no reading taken under this release yet.

- Flag `tengu_breezy_fairy`: Off in both readings (read for one account on one subscription tier against v2.1.274; 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: Device Security
- Names: `cloud_elevated_create`
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 3/5
- Present in the build but not switched on

### Artifacts tool result text now distinguishes fully-public artifacts from org-internal ones

Artifacts tool now warns more strongly when a fully public artifact was made outside your organization

**What**

When the Artifacts tool (used to create and view pages on claude.ai) reads or lists files, it now checks whether a result is marked as fully publicly readable. When an artifact is both public and was created outside the user's own organization, Claude now gets a stronger warning that the artifact could have been written by anyone on the internet. This is separate from the existing warnings about artifacts with outside writers or co-written artifacts.

**Why**

This gives Claude clearer signal about the trustworthiness of content it's reading from artifacts, so it can treat fully public, externally-authored content with appropriate caution.

- Flag `tengu_cobalt_plinth_sedge`: Off by default, switched on for this account (read for one account on one subscription tier against v2.1.274; 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
- Names: `tengu_cobalt_plinth_sedge`
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 3/5
- Present in the build but not switched on

### Artifact-watch status text now distinguishes 'hears comments' capability, gated by an unresolved condition

Artifact-watch status message can now mention 'hearing comments' as a capability, under an unresolved condition

**Unclear.** The finding does not say what the other two conditions checked by the new helper represent or when exactly comment-watching becomes possible.

**What**

The status text shown when watching an artifact (a generated file or piece of content) for changes can now include an extra clause. Instead of only saying the session 'does not keep track of new versions of this artifact,' it can say it 'does not keep track of new versions of this artifact or hear comments on it.' A new internal check decides which wording to show, based on whether something is in a 'live' state along with two other unnamed conditions.

**Why**

This lets Claude Code more precisely describe what a watch session can and cannot detect, distinguishing tracking new versions from hearing comments left on an artifact.

- Area: Artifacts
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 3/5
- Present in the build but not switched on

### Artifact-roster refresh denial backoff is stored but never consulted

A new backoff check for denied artifact-list refreshes is recorded but never actually applied

**What**

When a request to refresh the list of artifacts is denied with a 401 or 403, Claude Code now records the denial (status, time, and token expiry). A new check exists that could use this record to hold off retrying for a period of time, but nothing in the current build actually calls that check.

**Why**

This is groundwork with no visible effect yet: the denial is logged and cleared on account switch, but retries after a denial aren't currently held back by it.

- Area: Artifacts
- Tier: Nothing to try yet
- Useful: 1/5
- Signal: 3/5
- Present in the build but not switched on

### Git tag/GPG signing config keys defined but apparently unused

New git config entries for tag and commit signing (like tag.gpgSign, gpg.format) added, purpose unclear

**Unclear.** Whether these new keys and forced values are actually applied anywhere, or just defined, is not shown by the evidence.

**What**

A new regular expression matching git signing-related configuration keys, such as `tag.gpgsign`, `user.signingkey`, `gpg.format`, and `gpg.program`, was added, along with a paired list of key/forced-value combinations like `tag.gpgSign` set to `false` and `gpg.ssh.defaultKeyCommand` set to empty.

**Why**

This extends the earlier work that let Claude Code trust and automatically configure git signing settings for commits, now recognizing more signing-related keys such as tag signing settings, though the finding doesn't show these new entries actually being applied yet.

- Area: Git Security
- Tier: Nothing to try yet
- Useful: 1/5
- Signal: 3/5
- Present in the build but not switched on

### New gate tengu_tidy_fern controls an alternate user-message construction path

New gate tengu_tidy_fern can add an extra value into how user messages are built

**Unclear.** Nothing has been read about the tengu_tidy_fern gate, and what the extra computed value actually does isn't stated.

**What**

A new internal flag, `tengu_tidy_fern`, controls whether an extra value is computed and passed along when Claude Code builds a user message for tool use. Previously this value was always left empty; now, when the flag is on, it is computed via a new function and included instead.

**Why**

The finding doesn't say what this extra value is used for, so it's unclear what practical difference this makes for a user.

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

### Gated: eager unresolved-tool-use detection path (tengu_eager_pillow)

A gated code path changes how Claude Code detects unresolved tool uses

**Unclear.** Whether tengu_eager_pillow is enabled is unread and not established by this finding.

**What**

The function that finds unresolved tool uses (`findUnresolvedToolUse`) now has a new code path controlled by a feature flag. When enabled, it uses a new lookup function combined with the existing check for the last assistant turn, instead of the previous lookup function it used before.

**Why**

This appears to be a behind-the-scenes change to how Claude Code identifies tool calls that haven't been resolved yet, likely aimed at improving accuracy or performance of that detection.

The `tengu_eager_pillow` gate controlling this path has no recorded reading, so nothing can be said here about whether it's on or off.

- Flag `tengu_eager_pillow`: Not enough to say (read for one account on one subscription tier against v2.1.274; 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: Tool Use
- Names: `tengu_eager_pillow`
- Tier: Nothing to try yet
- Useful: 1/5
- Signal: 2/5
- Present in the build but not switched on

### New gate for coalescing background task notifications

New gate 'tengu_swirling_meteor' controls grouping of background task notifications

**What**

A new flag, `tengu_swirling_meteor`, controls whether notifications that a background agent's task has stopped get coalesced (grouped together) while a session's live loop is running.

**Why**

If enabled, this would mean fewer, grouped notifications about finished background tasks instead of one for each, reducing notification noise during a session.

- Flag `tengu_swirling_meteor`: Not enough to say (read for one account on one subscription tier against v2.1.274; 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: Background Tasks
- Names: `tengu_swirling_meteor`
- Tier: Nothing to try yet
- Useful: 1/5
- Signal: 2/5
- Present in the build but not switched on

### Live-subscribe ('artifact watch') feature flag remains off by compiled default

Explanation text for a disabled 'live-subscribe' artifact-watch feature was reworded

**What**

The feature that lets a session track republishes of a watched artifact is controlled by a flag called `tengu_slate_lantern`. When that flag resolves to false, the reason given is `flag_off`; this release only changed the wording of the explanation shown in that case, not the underlying logic.

**Why**

This is a text-only change to how the disabled state is explained. The flag itself has been read as on for this site's account and on for the general anonymous baseline in past checks, but no reading has been taken under this specific release.

- Flag `tengu_slate_lantern`: Off by default, switched on for this account (read for one account on one subscription tier against v2.1.274; 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
- Names: `tengu_slate_lantern`
- Tier: Nothing to try yet
- Useful: 1/5
- Signal: 2/5
- Present in the build but not switched on

### Roster-cache freshness check (`q7r`) similarly appears unused

A new roster-cache freshness check exists in the code but appears to have no caller

**Unclear.** Whether q7r is genuinely unused or simply not reachable from the parts of the bundle that were inspected is unclear.

**What**

A new internal function, `q7r`, checks whether the cached list of artifacts (the "roster") is still fresh, using a 4-hour window based on its last-fetched time. No code in the bundle appears to call it yet.

**Why**

Since nothing currently calls this function, it has no visible effect on Claude Code's behavior yet.

- Area: Artifacts
- Tier: Nothing to try yet
- Useful: 1/5
- Signal: 2/5
- Present in the build but not switched on

## Internal Changes

### Stage-file (remote session upload/output) can be invoked without CLAUDE_CODE_REMOTE_SESSION_ID via a 'vouched' path

Remote-session file staging can now skip the session-ID requirement via a new 'vouched' path

**What**

The function that stages files for upload or output in a remote session now accepts a second, optional parameter. When it's set, file staging can proceed without the usual `CLAUDE_CODE_REMOTE_SESSION_ID` requirement, and the mount is marked as "vouched" instead of tied to an actual remote session ID. This path is refused for synced, filestore-backed documents, with the message "synced documents are not staged here."

**Why**

This adds a way to stage files in remote-session contexts without a real session ID present, while still excluding documents that are synced through the filestore, which need to go through their normal path instead.

- Area: Sessions
- Names: `CLAUDE_CODE_REMOTE_SESSION_ID`
- Tier: Under the hood
- Useful: 2/5
- Signal: 3/5

### Fast/'penguin' mode org-status logic reworked for SDK contexts

Fast mode's org-status checking logic was reworked to handle SDK-based sessions separately

**Unclear.** Whether tengu_penguins_off is enabled is unread and not established by this finding.

**What**

The internal logic that manages fast mode's organization-status checking has been reworked. New helper functions split the handling by whether a session is running through the SDK (Claude Code's programmatic interface) versus a normal interactive session, an existing function gained a `sessionOnly` parameter for checking per-session opt-in, and a new pair of functions automatically triggers a background check of the organization's fast-mode status whenever settings show `fastMode` turned on but the org's status is still pending or assumed disabled.

**Why**

This makes fast mode's availability check more reliable for SDK-driven sessions and reduces cases where fast mode appears unavailable just because the org status hasn't been fetched yet.

The `tengu_penguins_off` gate involved in this logic has no recorded reading, so nothing can be said here about whether it's on or off.

- Flag `tengu_penguins_off`: Not enough to say (read for one account on one subscription tier against v2.1.274; 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: Models
- Tier: Under the hood
- Useful: 2/5
- Signal: 3/5

### Command.run answers now carry structured 'context' alongside text

Command-run answers can now carry structured 'context' data, not just text

**What**

When a hook modifies the answer produced by running a command, it can now override a `context` field in addition to the answer's `text`. The internal mechanism for settling and re-telling these answers can drop the text or the context independently of one another.

**Why**

This lets hooks attach structured information to a command's result, separate from its plain text output, and gives finer control over which part of a hook's answer is kept or discarded.

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

### New per-person ask-class consent tracking

Claude Code now tracks tool-permission consent separately for each collaborator in a session

**What**

Session state now includes several new tracking maps for permission-classifier decisions ('ask class', the system that decides whether a tool use needs to ask for permission) broken down per person or collaborator, rather than only tracking consent for the whole session:

- `askClassPersonConsent` — tracks each person's consent decisions

- `askClassPersonAsked` — tracks whether a person has already been asked

- `askClassNoClassifier` — tracks cases with no classifier available

- `askClassTakenByPerson` — tracks which person made a given decision

- `notedUnreadRefusals` — reuses a cached deny message for a given tool use

**Why**

This lets Claude Code manage tool-permission consent individually for each collaborator in a shared session, rather than treating consent as a single session-wide setting.

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

### Status-report 'brief' shape added to teammate/status serialization

Status reports gain a new 'brief' format with points, a question, and reply options

**Unclear.** The finding doesn't say which feature or UI actually generates or displays a 'brief'-shaped status report.

**What**

The internal function that formats status reports for teammates/subagents now understands a new input shape called `brief`, in addition to the existing `recap` shape and its default handling. A brief includes points, a question, a summary, a "next why" explanation, and options, and gets turned into fields like `status_category`, `needs_action`, `description`, `points`, `summary`, `next_why`, and `reply_options`.

**Why**

This adds a more structured way for a status update to pose a question with selectable reply options, rather than just a free-form recap, though the finding doesn't say where in the product this new shape is actually produced or shown.

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

### New team-memory / mount-dir error taxonomy

Team memory and mounted-directory features now report many more specific error codes

**What**

Claude Code's shared team memory and mounted-directory storage can now fail in a much wider variety of clearly named ways, including:

- `team_memory_too_many_entries`, `team_memory_entry_too_large`

- `team_memory_group_acl_denied`, `team_memory_group_acl_unconfigured`, `team_memory_feature_unavailable`

- `mount_dir_foreign_partition`, `mount_dir_unmanifested_nonempty`, `mount_dir_unreadable`

- `store_full`, `content_too_large`, `content_secret`, `content_screened`

- `index_too_large`, `invalid_path`, `store_archived`

**Why**

A larger, more specific set of error codes means Claude Code can explain more precisely what went wrong when a team memory write or mounted-directory access fails, instead of a generic failure.

- Area: Team Memory
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New artifact 'provisioned' schema for storage backing

Artifacts now carry an optional 'provisioned' field describing their storage backing

**What**

Artifact publish and session data can now include an optional `provisioned` object, holding fields for `store`, `project_id`, and optionally `file_id` and `node_id`. These describe where and how an artifact's underlying content is stored.

**Why**

This adds metadata that lets Claude Code track exactly where an artifact's data lives, which is groundwork for handling artifacts backed by different storage systems.

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

### New engine facade capability: refreshAgents

A new refreshAgents method lets Claude Code re-read custom agent (subagent) definitions on demand

**What**

The internal engine/session interface gained a `refreshAgents` method, alongside the existing `refreshCommands`, which triggers Claude Code to re-read custom agent definitions.

**Why**

This lets custom agents (subagents with their own instructions and tools) be picked up again after changes, the same way custom commands can already be refreshed, without needing an unrelated action to trigger it.

- Area: SDK
- Names: `refreshAgents`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Strict tool-result pairing mode gated by client launch option, not a simple flag

Strict tool-result pairing mode is now controlled by the client's launch options, not an experiment gate

**What**

The setting that decides whether Claude Code throws an error (instead of silently repairing) when tool calls and their results don't line up correctly has moved to a different check. It's now read from `host.launchOptions.strictToolResultPairing()`, a value the client application provides at launch, rather than from an internal experiment flag.

**Why**

This puts control of strict pairing behavior in the hands of whatever application is embedding Claude Code, rather than in a centrally managed experiment.

- Area: Tool Use
- Names: `strictToolResultPairing`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### read_file/batch file read now take byteBudget and admitPublicRead options; new asset-existence HEAD check

Artifact file-read functions gain options for public reads, byte limits, and a new file-existence check

**What**

The functions that read a single artifact file or a batch of artifact files now accept extra options: whether to admit a public (non-member) read, and for batch reads, a byte budget limiting how much data is fetched at once. A new helper also does a quick existence check (an HTTP HEAD request, which asks whether a file exists without downloading it) for a specific artifact version's asset bundle.

**Why**

These options let artifact file reads be tuned per request, controlling both who can read public artifacts and how much data a batch read pulls back, and let Claude Code confirm an asset exists before trying to fetch it.

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

### New per-session live-version tracking for watched artifacts

New per-session tracking of artifact versions heard about elsewhere, with a flag to avoid repeat notices

**What**

A new set of internal helpers maintains a map of "heard versions" for artifacts, tracking whether a version known locally has fallen behind one heard about from elsewhere, and marking each with a "told" flag so the same notice isn't repeated.

**Why**

This is the underlying mechanism for Claude Code to keep quiet, per-session track of artifact versions published elsewhere without repeatedly re-notifying about the same update.

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

### Local slash-command execution can now append extra 'meta' text blocks

Local slash commands can now append extra hidden 'meta' text blocks to their output messages

**What**

The internal function that assembles the messages produced by running a local slash command can now accept extra text blocks marked `isMeta: true`. When present, these are appended to the message list, and the result carries a `metaTexts` field noting they were added.

**Why**

This gives local slash commands a way to attach additional metadata-style content to their output alongside the regular command result.

- Area: Slash Commands
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Slash-command / local-command output can be patched in place after the fact

Slash-command output can now be edited in place after it's already been produced

**What**

A new internal function can update the output of an already-completed slash command or local command (such as its stdout or stderr text) with new content, and can also replace related context entries. This only happens if the current turn hasn't already moved on, such as by querying further, advancing to the next input, or finishing.

**Why**

This allows command output to be corrected or supplemented after the fact, as long as the turn is still in a state where that update can safely apply.

- Area: Slash Commands
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### hostSessionId now reported, reading CLAUDE_CODE_HOST_SESSION_ID

Session registration now reports a hostSessionId read from the CLAUDE_CODE_HOST_SESSION_ID environment variable

**What**

Claude Code now reads a `CLAUDE_CODE_HOST_SESSION_ID` environment variable, subject to two other conditions, and includes its value as `hostSessionId` in the payload sent when registering a session. One other place that reads this value is itself controlled by a separate flag.

**Why**

This lets Claude Code identify and report the host session a given session belongs to, which is useful in setups where sessions run under a managing host process.

- Flag `tengu_tidy_fern`: Not enough to say (read for one account on one subscription tier against v2.1.274; 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: Session Management
- Names: `CLAUDE_CODE_HOST_SESSION_ID`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Session metadata gains hostSessionId and outsideOrgReader fields

Session metadata and permission info now include new hostSessionId and outsideOrgReader fields

**Unclear.** What hostSessionId and outsideOrgReader are used for is not stated.

**What**

Session data now carries two small additions:

- `hostSessionId` is included in the session snapshot output.

- `outsideOrgReader` is included in the role/permission information built for a session.

**Why**

The finding doesn't say what these fields are used for, but their presence means session snapshots and permission checks now carry more information than before.

- Area: Session Management
- Names: `hostSessionId`, `outsideOrgReader`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Artifact page-data reads gained a manifest/store-usage/content-store surface (manifestPaths, storeDocuments, contentStore)

Artifact file reads can now include manifest paths, store usage documents, and a content store reference

**Unclear.** The finding shows these fields were added to the read result but not how or where Claude Code uses them afterward.

**What**

When Claude Code reads an artifact's page data, the result can now include three new pieces of information that did not exist before:

- `manifestPaths`, a list derived from the artifact's files

- `storeDocuments`, derived from database usage data

- `contentStore`, a value checked against a new validation pattern

**Why**

This gives Claude Code more detail about an artifact's underlying storage and file manifest when reading it, though the finding does not say what these fields are used for downstream.

- Area: Artifacts
- Names: `manifestPaths`, `storeDocuments`, `contentStore`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New expandable/collapsible message rendering components for inbound & task-notification text

New components render expandable/collapsible inbound and task-notification messages

**Unclear.** The finding describes the new component structure but not what the expand/collapse behavior looks like or does for a user.

**What**

New rendering functions were added that support `isExpanded`, `messageId`, `origin`, `verbose`, and `taskDelivery` properties for showing inbound and task-notification text. An existing renderer for inbound messages was refactored to delegate to one of these new components, reusing the same expandable/collapsible properties.

**Why**

This is an internal change to how messages are rendered.

- Area: Terminal UI
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### New MCP tool metadata field describing the serving MCP server

MCP tools now carry structured metadata identifying which server and source they came from, for security purposes

**What**

Tools provided by MCP (Model Context Protocol) servers now carry structured metadata describing the server that's serving them: the server's configuration key name, and a `source` value drawn from a fixed set of options (`sdk`, `plugin`, `user`, `project`, `local`, `dynamic`, `managed`, `enterprise`, `claudeai`, `agent`) describing where that server's definition came from. The tool-wrapper builder now threads this `source` value through into the tool's metadata.

**Why**

The metadata explicitly instructs consumers to trust the `source` field, not the tool's name or its `mcp__` prefix, for security purposes. This closes a gap where a tool's name or prefix alone could be spoofed or misleading about where it actually came from.

- Area: MCP
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### New memory-entry schema for listing individual memories

New schema defines the shape of a single memory record for listing memories

**What**

A new schema describes an individual memory record used when listing memories: its name (a path relative to the auto-memory folder, or `MEMORY.md` for the index file), its absolute path, an optional description and type from its frontmatter (type being one of user, feedback, project, or reference), and a modified timestamp in milliseconds.

**Why**

This formalizes the data structure behind memory listings, working together with the new `memories` array mentioned elsewhere, so that tools working with memory files have a consistent, typed record to work from.

- Area: Memory
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### MCP server 'source' attribution (sdk / plugin / config scope) added to schemas

MCP server status now reports where each server definition came from

**What**

MCP (Model Context Protocol) server status information now includes an optional `source` field, showing whether a given server was registered in-process via the SDK, came from a plugin, or came from a config scope such as user, project, local, dynamic, managed, enterprise, claudeai, or agent. This is computed internally from the server's metadata and exposed on `mcp_servers` status entries.

**Why**

This lets you (or tools reading this status) tell where an MCP server definition actually originated, rather than relying on its name alone, which is useful when the same server name could be defined in more than one place.

- Area: MCP
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Plugin UI pressable elements gain pressableLinks

Plugin UI clickable elements now also report their link destinations

**What**

When Claude Code extracts clickable ("pressable") elements from a plugin's rendered UI, it now also captures a `pressableLinks` array listing the link destinations (hrefs) attached to that element, alongside the existing plugin, handle, and element identifiers.

**Why**

This lets Claude Code (or code inspecting a plugin's UI) know not just that an element is clickable but where its links actually point.

- Area: Plugins
- Names: `pressableLinks`
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### New api_error_code / api_error_params surfaced on error messages

Error messages can now carry structured api_error_code and api_error_params fields, not just api_error

**What**

Error message objects used for chat and API error display now carry two new fields, `api_error_params` and `api_error_code`, in addition to the existing `api_error` field. This flows through the schema, the code that normalizes errors, and the shape used to display messages in the interface.

**Why**

Structured error codes and parameters let the interface show more specific, consistent error information instead of relying only on a generic error blob.

- Area: API Errors
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### New git-repo verification and auto-stash helpers for teleport/agents

New checks verify a checkout's .git points to the right repo and can auto-stash changes before teleport operations

**What**

Two new internal helpers support git teleport and agent operations:

- one that verifies a checkout's `.git` entry actually points back to the resolved repository, throwing "Could not verify this checkout's git repository" if it doesn't

- one that stages untracked files and runs `git stash push --message` before certain operations

**Why**

The verification check guards against operating on a checkout whose `.git` link is broken or mismatched, while the auto-stash helper protects uncommitted work by setting it aside safely before a risky operation runs.

- Area: Git Teleport
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Transcript message components gain `isExpanded`/`origin`/`messageId` props (collapsible messages)

Transcript messages internally gain expanded/collapsed and origin tracking, hinting at collapsible messages

**Unclear.** Whether this already produces user-visible collapsible messages or is only internal groundwork is not shown by the finding.

**What**

Several components that render messages in the conversation transcript — task messages, messages from other users in a shared channel, messages from other sessions, and inbound-labeled messages — now receive new `isExpanded`, `messageId`, and `origin` properties that they didn't take before. A shared `isExpanded` value is computed once per render and passed down consistently to all of them.

**Why**

This looks like groundwork for letting messages in the transcript be individually expanded or collapsed, though the finding doesn't show the collapsing UI itself yet.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Agent-evicted resume/mailbox handling reworked

Agent-evicted teammate event handling reworked to match tasks differently

**Unclear.** unused placeholder, replaced below

**What

- Area: Subagents
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### New sdk-MCP "unconnected server" tracker joined into turn lifecycle

Claude Code now tracks SDK MCP servers that are configured but not yet connected before starting a turn

**Unclear.** The exact effect of joining on pending servers (e.g. whether it blocks or times out) is not specified in the finding.

**What**

Claude Code now keeps a tracker of SDK-based MCP (Model Context Protocol, the standard used to connect external tools and data sources) servers that have been configured but have not finished connecting yet. This tracker's `join` step is now invoked as part of a turn's setup process, apparently to wait for those pending servers before the turn proceeds.

**Why**

This likely prevents a turn from starting before its configured SDK MCP servers are actually ready, reducing the chance of tool calls failing because a server hasn't connected yet.

- Area: MCP
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Rewrite-detector generalized to catch control characters in any prop, not just origin

The check for hooks secretly rewriting UI text now covers more fields and blocks hidden control characters

**What**

Claude Code has an internal check that catches a hook or plugin silently rewriting the text a UI element displays. Previously this check only looked at one field, a message's `origin`. It now checks a wider set of fields (`origin`, `isExpanded`, `task`, `from`), and separately flags any of these values as suspicious if it contains a control character (a hidden escape sequence the terminal would act on) or is unexpectedly long.

**Why**

This closes gaps where a hook could have altered what a user sees in ways the old, narrower check wouldn't catch, making it harder for a hook to disguise a rewrite as ordinary printable text.

- Area: Permissions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Memory backend list/read/create/update/delete now share a single 'store not provisioned' status handler

Memory-storage error handling for 'store not provisioned' and conflicts was consolidated and renamed internally

**What**

The internal client that talks to the memory-storage backend (used for listing, reading, creating, updating, and deleting memory data) now routes all of these operations through one shared helper that turns HTTP error codes, like 404, into a consistent typed error before any operation-specific handling runs. This replaces duplicated handling that previously existed separately for each operation. The internal error types for "store not provisioned" and "conflict" were also renamed.

**Why**

This is an internal cleanup that makes error handling for memory storage more consistent across list, read, create, update, and delete operations, reducing the chance that one operation handles a missing store or a conflict differently from another.

- Area: Memory
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### HTTP fetch helper for CCR now recognizes 404 alongside 403 as a possibly-non-fatal status

Skill/answer fetch requests now treat HTTP 404 like 403 as potentially non-fatal

**What**

A shared network helper used for fetching things like skills or answers from a remote config service previously only had special handling for an HTTP 403 (forbidden) response. It now also checks for a 404 (not found) response using a new check, before falling back to treating the response as an unrecognized failure.

**Why**

This means a 404 response in these fetches can now be handled the same deliberate way a 403 already was, rather than always falling through to a generic error path.

- Area: Internals
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Bundled/builtin plugin loading gets structured failure tracking and a phase-tagged telemetry event

Loading bundled/builtin plugins now tracks structured failures by phase and reports telemetry

**What**

Claude Code ships with some plugins built in. Loading them now goes through a new helper that requires, shape-checks, and registers each builtin plugin, and records failures with the plugin's name and the specific phase it failed at (requiring the code, checking its shape, registering it, or checking availability). These failures are also reported via telemetry. A related helper checks a plugin's `isAvailable()` status as a gate before proceeding.

**Why**

This makes it easier to diagnose why a specific builtin plugin failed to load, since failures are now tagged with the exact stage they occurred at instead of being lumped together.

- Area: Plugins
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Managed-settings policy refusal now sends telemetry/export via a dedicated flow

Failures to read managed policy settings now trigger a dedicated telemetry export

**What**

When managed settings (organization-controlled policy configuration) can't be read or are invalid, or when a policy refusal state exists, Claude Code now sends a dedicated telemetry export through new internal functions, force-flushing the telemetry exporter with a timeout to make sure the report goes out.

**Why**

This gives better visibility into cases where an organization's managed policy is unreadable or invalid and is causing Claude Code to fail closed (block changes rather than risk acting on an unverifiable policy), by ensuring that event gets reported rather than silently swallowed.

- Area: Managed Settings
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### First-party design auth now double-checked against request URL

First-party design auth classification now also checks the request URL, not just the token

**What**

The internal check that classifies a request as using "first_party_design_auth" now also requires a URL-based check to pass, in addition to the existing authentication lookup it already performed.

**Why**

This tightens how Claude Code decides a request qualifies as first-party design authentication, requiring the request's URL to also match expectations rather than relying on the auth lookup alone.

- Area: Auth
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Bridge attestation treats SERVER_AUTHORED/SERVER_REPLAYED as UNSPECIFIED

Remote-control bridge now treats SERVER_AUTHORED/SERVER_REPLAYED attestation as UNSPECIFIED

**What**

The remote-control bridge (the channel that lets an external device or host control a Claude Code session) checks a device attestation status to decide whether to accept incoming events. Two new attestation values, `SERVER_AUTHORED` and `SERVER_REPLAYED`, have been added to the underlying attestation-source list alongside the existing `UNCHECKED`, `VERIFIED_KEYLESS_DEVICE`, and `SERVICE_VOUCHED` values. When filtering bridge events, both new values are now normalized to `UNSPECIFIED` before the acceptance checks run.

**Why**

This means events attested as server-authored or server-replayed are handled the same as events with no specific attestation, rather than being given special treatment, which keeps the acceptance logic consistent as new attestation sources are introduced.

- Area: Remote Control
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### mcp_server field added to tool permission event schemas

Tool permission events now record which MCP server a tool belongs to

**What**

The event schemas used for tool-use permission requests, denials, and asks (which record things like `tool_name`, `tool_input`, `tool_use_id`, and `permission_suggestions`) now include an optional `mcp_server` field. A new helper function fills this field in by looking up the tool in the MCP (Model Context Protocol) tool registry when a permission decision is made.

**Why**

This lets permission-related records show which MCP server a tool came from, which is useful for tracking or auditing permission decisions involving tools provided by MCP servers rather than built-in tools.

- Area: Permissions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact frame watch-token calls gain a version query param and a publicOutsideOrg case

Artifact frame token requests add a version marker and a new publicOutsideOrg error case

**What**

The request Claude Code sends to renew an artifact frame's watch-token now includes a version marker (`?vn=`) in the URL. Separately, when parsing frame info from a response, a case with no `assetToken` present now returns a distinct `publicOutsideOrg` error, instead of falling through to the normal token-parsing path.

**Why**

Distinguishing the 'public outside org' case gives a clearer, more specific error when an artifact frame's token can't be found because it's public and outside the organization, rather than treating it as a generic parsing failure.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Escaping team-memory mount-dir check refactored into scope-aware `jfn`

Team memory's mount-directory escape check was refactored to dispatch by scope, now including the new account scope

**What**

The check that guards against a team-memory mount directory escaping its expected location has been refactored into a helper that dispatches based on scope: `user` and `team` scopes use the existing check, and the new `account` scope gets its own dedicated check. This replaces an inline scope check with the same underlying logic.

**Why**

This is an internal restructuring that extends the existing escape-safety check to cover the new account memory scope.

- Area: Team Memory
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Diff-size finder-subagent budget hint can now use a caller-supplied diff line counter

Sizing hints for diff-review subagents can now reuse a caller-supplied line count instead of always recomputing it

**What**

When Claude Code estimates how many helper subagents to use for reviewing a diff, it computes a budget hint based on how many lines changed. This logic can now accept a pre-supplied diff line count from the caller instead of always recalculating it itself, and adjusts its "about N lines" guidance text and subagent count accordingly.

**Why**

This avoids redundant recomputation when a line count is already available, and keeps the guidance text accurate to whichever count is actually used.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### MCP catalog lookup source changed

MCP catalog lookups now read from a served catalog cache instead of a host-keyed source

**Unclear.** What effect this source change has on behavior visible to the user is not specified.

**What**

The internal function that looks up the MCP (Model Context Protocol) catalog now returns its data from a `servedCatalogByKey` source instead of the previous host-based lookup.

**Why**

This changes where Claude Code's MCP catalog data comes from internally; the finding does not specify what practical difference this makes for users.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Git diff review pane now tracks explicit fullscreen state and a cwd override

Git diff review pane tracks its working directory and fullscreen state more precisely, and cancels stale background work on session changes

**What**

The git diff review pane (the view that shows pending changes for review) now tracks more state internally:

- a `cwd` field, so process runs use an explicit working directory when one is set

- an `isEmpty` flag, letting it skip re-checking git status when a session is already known to have no repository

- an `epoch` counter, which cancels in-progress work to resolve a diff's base when a session is cleared or resumed

Separately, whether the pane is shown fullscreen is now derived from the actual render viewport instead of being assumed, and the pane now only auto-opens when it is explicitly confirmed to be fullscreen.

**Why**

These changes make the review pane more accurate about its own state, avoiding wasted work on repo-less sessions, stale background lookups after switching sessions, and auto-opening under the wrong screen layout.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Query engine events now dispatched through a frame notifier instead of applied inline

Engine events during a query are now deferred to a frame boundary instead of applied immediately

**Unclear.** What user-visible difference this timing change produces is not stated.

**What**

In the main query-turn handler, incoming engine events used to be applied straight away. They are now routed through a frame notifier that defers applying them until a frame boundary is reached.

**Why**

Deferring event application this way changes the timing of when state and UI updates take effect during a turn, though the finding doesn't specify the visible effect.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Managed settings now reported to telemetry with redaction

Managed settings resolution is now reported to telemetry, with sensitive values redacted

**What**

A new `managed_settings_resolved` telemetry event reports metadata about how managed (organization-controlled policy) settings were resolved: the source, the resolution behavior, helper state, and details like entry key, path, and script hash.

If the `OTEL_LOG_MANAGED_SETTINGS` environment variable is set, the actual resolved settings content is included too, but values are redacted to `[REDACTED]` unless they match a known tool/permission-rule/value schema, are recognized tool names, or match an `mcp__` tool naming pattern.

**Why**

This gives organizations visibility into how their managed settings actually get resolved, while keeping sensitive configuration values out of telemetry by default.

- Area: Managed Settings
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact boot/frame requests gain a distinct "probe" kind and version param

Artifact frame-boot requests now carry a distinct "probe" kind and version parameter depending on why they were made

**Unclear.** The finding doesn't describe any visible effect of this beyond the internal request format.

**What**

The internal function that requests an artifact's boot frame now takes a `kind` parameter, which defaults to `"probe"`, and a `watchBoot` flag. A probe request now appends `&bk=probe` to its query string, while watch, sync, and peer requests instead append a `&vn=` version parameter.

**Why**

This lets Claude Code's backend tell apart different reasons an artifact frame is being requested.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Structured exit-reason telemetry added to early CLI startup failures

Early CLI startup failures now report a categorized reason via telemetry before exiting

**What**

Several places where Claude Code exits early during startup now report a categorized reason before exiting:

- a failed security dialog or forced refresh reports `force_refresh_failed`

- being rejected by the gateway reports `gateway_rejected`

- running a version below the minimum required reports `version_below_minimum`

- running `--dangerously-skip-permissions` as root reports `bypass_root`

A new subscription also reports `consent_rejected` when consent is rejected.

**Why**

This gives clearer, categorized telemetry for why Claude Code fails to start, making it easier to diagnose startup problems like an outdated version, a rejected gateway, or an unsafe root and `--dangerously-skip-permissions` combination.

- Area: Startup
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Tool-result elision generalized to a list of open/tail marker pairs

Tool-result collapsing in non-verbose mode now uses a general list of marker pairs instead of hardcoded prefixes

**What**

When Claude Code shows a tool's result in non-verbose mode, it collapses (elides) long or error-wrapped content so the terminal doesn't fill up. That detection used to rely on hardcoded prefix checks; it now first checks a general list of open/tail/end marker pairs, falling back to the old prefix-based check only if none match.

**Why**

This is an internal restructuring of how collapsed content is recognized, making it easier to add new collapsible content types without touching the fallback logic. It shouldn't change what a user sees.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact fetch gains explicit 'kind' and 'watchBoot' parameters

Artifact fetch helper gains explicit 'kind' and 'watchBoot' options

**Unclear.** What effect the new `kind` and `watchBoot` parameters have on user-visible behavior isn't stated.

**What**

The internal helper used to fetch an artifact as part of the publish/read flow now accepts two new parameters: `kind` (defaulting to `"probe"`) and a `watchBoot` flag, alongside the existing `relayOnly`, `agentPeer`, `syncLive`, and `speculative` options. These feed into the same underlying request as before.

**Why**

This gives the artifact system finer control over how and why a fetch is made, though the finding doesn't specify what behavior `kind` or `watchBoot` change from a user's perspective.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Bridge inbox message fetch now logs fetch attempts against the message queue

Bridge inbox message fetch now logs each fetch attempt against the message queue

**What**

The tool that fetches an inbound bridge message by its file ID now receives the current `session` and `messageQueue` when it's created, and records each fetch attempt, whether it succeeds or fails, via a new `noteFetchAttempt` call.

**Why**

This adds visibility into message-fetch attempts on the bridge, which should make it easier to diagnose problems with inbound messages not arriving or being missed.

- Area: Remote Control
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### MCP tool descriptions carry provenance ('source') into the render payload

MCP tool data sent to the UI now includes where each MCP client came from

**Unclear.** It's unclear whether or how this source information is currently surfaced to the user in the interface.

**What**

When Claude Code passes information about connected MCP clients (Model Context Protocol servers providing extra tools) into the data used to render the interface, each client entry now includes a `source` field alongside its `name` and `type`, computed by a new internal helper.

**Why**

This adds provenance information about MCP tools that the interface (or other consumers of this data) can use, though the finding doesn't specify what visibly changes for users yet.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Windows-path circuit breaker added to Artifact database permission checks

Artifact database permission checks gain a new suspicious-Windows-path safeguard

**Unclear.** The finding doesn't say what specifically makes a path 'suspicious' or what condition triggers the new classifierApprovable branch.

**What**

The permission check for an Artifact's shared database (covering `read_db` and `write_db` actions) now has a new branch that, under a new condition, flags the decision with a `circuitBreaker` labeled `suspiciousWindowsPath` — a category that already existed elsewhere. A separate new branch also marks another condition as `classifierApprovable`.

**Why**

This adds an extra safeguard specifically for database actions on Artifacts, flagging cases that look like a suspicious Windows-style file path so they get extra scrutiny, though the finding doesn't specify exactly what pattern triggers it.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New share-status refusal/message case: public_outside_org

Share-status tracking adds an 'outside org reader' flag alongside the same new refusal case

**What**

A related code path for checking an Artifact's share status now handles the same `public_outside_org` case, returning the same message used when resuming automatic replies is refused. Share-status records also now track a new `outsideOrgReader` flag, which gets cleared whenever account-boundary details change, alongside the existing `probeErrorCode` and `role` fields.

**Why**

This keeps the share-status data consistent with the new rule that accounts outside an Artifact's organization can't re-arm automatic replies on a public Artifact, giving that check a persistent flag to reference rather than recomputing the org relationship each time.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Worktree-registration vetting before deletion

New internal check vets a repository's worktree registrations with git before removal proceeds

**What**

A new internal function checks whether a repository's worktree registrations can be safely verified with git before an operation (such as removing a worktree) proceeds. It resolves pointer or symlinked `.git` directories, and distinguishes between two outcomes: 'unlisted' (the worktree is gone or not a real repository) and 'kept' (git couldn't be asked yet, so the entry is preserved).

**Why**

This reduces the risk of incorrectly discarding worktree registrations when git can't yet be consulted, by keeping them by default until they can be properly checked.

- Area: Git Worktrees
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Sandbox/session state gains refused-write and unusable-basis tracking

Internal session-recovery state now tracks refused writes and whether the comparison basis is unusable

**Unclear.** The finding does not say what user-visible behavior, if any, reads or reacts to these new fields.

**What**

The internal state object used for tracking write conflicts and session recovery now carries three new fields: `refusedWrites`, `basisUnusable`, and `basisUnusableReport`, alongside its existing conflict and failure tracking fields.

**Why**

This expands what the system tracks internally about failed or refused write attempts and cases where the comparison basis can't be used, likely supporting more precise recovery or reporting behavior.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Teleport client-directory-sync retraction now sends a trusted-device token

Retracting the Teleport client-directory-sync tag now sends a trusted-device token

**Unclear.** Nothing has been read yet about the `tengu_teleport_client_directory_sync_retracted` gate, so it's unclear whether or how it governs this behavior.

**What**

When Claude Code retracts (undoes) its Teleport client-directory-sync tag, the request now also includes a `trustedDeviceToken` value, in addition to the parameters it already sent.

**Why**

Including a trusted-device token on this call lets the server verify the request is coming from a recognized device when the sync tag is being retracted.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New shutdown-time telemetry for unsent/backlogged events

Claude Code now reports backlogged, unsent telemetry events when a session ends

**What**

Claude Code now tracks how many usage/telemetry events are still waiting to be sent when a session shuts down. A new internal check reports the number of unsent client events, the number of unsent internal events, how long the oldest queued event has been waiting, and whether sending is currently backing off. This information is attached to telemetry as `unsent_client_events_at_close`, `unsent_internal_events_at_close`, and `hold_preflush_inflight_age_ms` at the moments a connection closes or no listener is holding events.

**Why**

This gives visibility into whether Claude Code is losing or delaying telemetry data at shutdown, which helps diagnose gaps in usage reporting rather than leaving them silent.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New api_error_code field threaded through turn-completion telemetry

Turn-completion data now includes a specific API error code, not just a status

**What**

When a conversation turn ends because of an API error, the turn-result data (`SDKAssistantMessage` and related payloads) now includes a new `api_error_code` field alongside the existing `api_error_status`. This carries the more specific error code from the server's error details, when one is available.

**Why**

This gives more precise information about why a turn failed due to an API error, beyond just a general status, which is useful for diagnosing what actually went wrong.

- Area: API Errors
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New telemetry event for queued-message delivery timing

New telemetry event tracks how long queued messages wait before being delivered

**What**

Claude Code now records a `queued_message_delivered` telemetry event whenever queued commands or prompts are dispatched. It logs the delivery mode, how many commands and prompts were included, and how long the oldest item in the queue had been waiting.

**Why**

This gives insight into how queued messages and commands are actually delivered and how long they sit waiting, which helps identify delays in message handling.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New 'must be an integer within N (character cells)' settings validation rule

Settings validator adds a rule requiring some values to be whole numbers of "character cells"

**Unclear.** The finding doesn't say which specific settings keys this new rule applies to.

**What**

Claude Code's settings validation now includes a new rule for certain configuration keys, requiring their value to be a finite whole number within a set range, described in terms of "character cells". This is separate from the existing rule that validates color-string settings.

**Why**

This lets Claude Code catch invalid values earlier for settings that must be sized in character cells, giving a clearer error instead of accepting a malformed value.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### MCP server identity now threaded through permission requests

Permission prompts now carry which MCP server is asking, including its name and source

**What

An MCP server is an external tool provider Claude Code can connect to. Permission requests (the prompts asking whether Claude Code may use a tool) can now include an optional `mcp_server` field with `name` and `source`, which is validated and stripped out with a warning if malformed. This information is also passed through to the permission dialog shown to the user, and to the tools that check request formatting.

**Why**

When a permission request comes from an MCP-provided tool, the person approving it can now see which MCP server is making the request, rather than seeing only the tool name with no indication of which external server it came from.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### post_turn_summary telemetry/schema gains richer structured fields

Turn-summary telemetry now carries a description, points, summary, and suggested replies

**What**

The internal `post_turn_summary` event, which records data about a completed turn (one back-and-forth exchange with Claude), now includes several new fields on top of what it already tracked: `description`, `points`, `summary`, `next_why`, and `reply_options`.

**Why**

This gives whatever consumes this telemetry a richer picture of what happened at the end of a turn and what might reasonably follow, rather than just a status code and a short detail string.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New server-authored/server-replayed event origin values

Events can now be labeled as server-authored or server-replayed

**Unclear.** The finding doesn't say where these display categories are shown or how they affect behavior.

**What**

The function that maps an event's origin to a display category now recognizes two new origin values: `server_authored` and `server_replayed`, which map to the display categories `SERVER_AUTHORED` and `SERVER_REPLAYED` respectively.

**Why**

This lets Claude Code distinguish events that the server itself created or replayed from events originating elsewhere, wherever that origin category is displayed or used.

- Area: Remote Control
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New telemetry categories: cloud_elevated_create and compact_kept_tail_announcements

Two new telemetry categories track elevated cloud session creation and kept compaction announcements

**What**

The list of recognized telemetry event categories gained two new entries:

- `cloud_elevated_create`, tracked when an elevated cloud session is created

- `compact_kept_tail_announcements`, related to announcements kept at the tail end of a conversation compaction (the process that shortens a long conversation history)

**Why**

This lets Claude Code's telemetry track these specific events separately rather than lumping them into an unrelated or generic category.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Sandboxed dynamic-render-hook runtime template hardens against global tampering

Sandboxed render-hook runtime now locks down global objects before running untrusted code

**What**

When Claude Code runs a render hook (custom code that draws part of the interface) in its sandboxed JavaScript runtime, that runtime now captures references to `Object.freeze`, `defineProperty`, `defineProperties`, `keys`, `Array.isArray`, `Map`, `JSON.stringify`, `Error`, and `TypeError` into local constants up front, instead of referencing the global versions directly each time.

**Why**

This guards against a render hook tampering with these global objects or methods to interfere with how the sandbox itself works, making the sandbox more resilient against misbehaving or malicious render-hook code.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### MCP server source now reported to clients

MCP server status sent to hosts and the SDK now includes where each server's configuration came from

**What**

Status information about MCP (Model Context Protocol) servers, sent both in the MCP servers listing and in the initial status payload, now includes a `source` field describing where that server's configuration came from.

**Why**

This lets a host application or the SDK show or reason about where an MCP server's settings originated, rather than only seeing the resulting configuration.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact reads track skipped/refused files with size limits

Artifact validation now checks a list of skipped/refused files against count and length limits too

**What**

When Claude Code validates artifact type files, it now also checks a `skipped` files list, files that were skipped or refused, against a maximum count and per-entry length limits on the path and reason text, in addition to the existing checks on regular file paths.

**Why**

This stops an artifact from listing an unbounded or oversized set of skipped files, keeping validation consistent for both processed and skipped files.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New helper for locating an unresolved tool_use's full message-row group

New helper functions can locate the full message group behind an unresolved tool call

**What**

A new set of internal helpers can reconstruct which rows in a conversation transcript belong to the assistant message that produced a tool call whose result was never resolved, so that message can be restored.

**Why**

This supports repairing conversations where a tool call is left dangling, by making it possible to find and restore the full context it came from.

- Area: Tool Use
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact live-subscribe republish handling no longer directly composes a re-read prompt

Live artifact republish updates no longer inject a re-read prompt message, just log it passively

**What**

When a live artifact Claude Code is watching gets republished elsewhere, the handler used to build a message telling Claude the artifact appears to have been republished and should be re-read before editing, and queue it as a task notification. It now instead just records that the new version was heard and logs telemetry, without composing or sending that message.

**Why**

This is consistent with the shift to passive version tracking: rather than actively interrupting with a re-read prompt each time, the update is recorded quietly and surfaced differently.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New telemetry field `arm_source` on refusal and API events

Telemetry for refusals and API success events now records which experiment arm produced the response

**Unclear.** What arm_source is used for downstream isn't stated, and no reading of the tengu_api_success gate itself has been taken under this release.

**What**

Several telemetry events, including the one recorded for invalid-content-policy refusals and `tengu_api_success`, now include a new `arm_source` field.

**Why**

This lets Claude Code's internal telemetry distinguish which configuration or experiment variant a given response came from, though the finding doesn't say how this is used.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### tengu_api_success gains tender_quilt_header flag

tengu_api_success telemetry gains a tender_quilt_header flag for low-priority background requests

**Unclear.** No reading of the tengu_api_success gate itself has been taken under this release.

**What**

When a low-priority or background request condition is present, the `tengu_api_success` telemetry event now records a `tender_quilt_header` flag set to true, alongside the new `arm_source` field.

**Why**

This lets Claude Code's telemetry distinguish API success events that came from this background/header condition from other requests.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Dynamic MCP server types 'sse-ide'/'ws-ide' now get special-cased during server-set updates

MCP servers of type 'sse-ide' or 'ws-ide' are now handled specially when server lists update

**Unclear.** The finding does not say what user-visible effect this routing change has beyond how the code sorts these server types.

**What**

When Claude Code processes an update to its list of configured MCP servers (external tool providers connected via the Model Context Protocol), servers whose connection type is `sse-ide` or `ws-ide` are now grouped together with servers that are already registered, rather than being sorted through the normal allow/block logic.

**Why**

This changes how these particular IDE-connection server types are treated when the server list is refreshed, keeping them from being dropped or re-evaluated the same way ordinary servers are.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New telemetry before resuming a subagent

Resuming a subagent now logs diagnostic details about how it's being resumed

**What**

When Claude Code resumes a subagent (a helper agent handling part of a task), it now records a telemetry event with details about that resume: whether sidecar metadata was found, where the originating prompt came from, whether a task record exists, whether this continues an interrupted turn, whether the resumer is itself a subagent, and whether a newer storage system (storageV5) is active.

**Why**

This gives more visibility into how and why subagent resumes happen, which can help diagnose problems with resuming interrupted or nested agent work.

- Area: Subagents
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Worktree state now reports whether submodules were verified

Git worktree status reports now include whether submodules were verified

**What**

The snapshot of a git worktree's state (a working copy of a repository checked out separately) that gets sent over the remote bridge now includes a `submodules_unverified` field, alongside existing fields like the head commit, unpushed commit count, and whether the tree is dirty.

**Why**

This lets tools consuming worktree state know whether the status of any git submodules within it has actually been checked, rather than assuming it always has been.

- Area: Git Worktrees
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact comment-reply and asset-copy calls now record consent/telemetry via new helper calls

Artifact comment reads and asset copies now log more detailed consent/telemetry records

**What**

When Claude Code reads comments on an artifact, it now separately records which specific comment IDs were shown to you, in addition to the existing record of the read happening. When copying an asset between artifacts (the `copy_from` action), it now records consent-tracking telemetry for the copy source before performing the copy, in addition to the deny/ask permission-rule checks already in place.

**Why**

This adds more precise tracking of what was shown and copied, supporting the permission and consent checks that already govern artifact reads and asset copies.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Newly-created artifacts tracked per account/conversation epoch as 'own created'

Claude Code now tracks which artifacts you created, per account and conversation, as 'own created'

**Unclear.** The finding doesn't say what consumes this new `ownCreatedSlugs` tracking or how it changes visible behavior.

**What**

When an artifact is created, Claude Code now records its slug (identifier) into a new session-state map called `ownCreatedSlugs`, tagged with the current environment. This only happens when the acting agent isn't the top-level agent-context-skip case, and when the account/conversation matches the one that made the create call. This tracking is separate from the existing `roomStoppedByUser` tracking.

**Why**

This is internal bookkeeping that lets Claude Code know which artifacts were created by the current session itself, likely to support other logic that behaves differently for artifacts you created versus ones you didn't.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact create call now threads an explicit requestId

Artifact creation calls now can carry an explicit requestId

**What**

The function that creates a new artifact now accepts an additional parameter and, when it's set, forwards it as `requestId` in the request sent to create the artifact.

**Why**

This is internal plumbing that lets an artifact-creation request be tagged with a specific request identifier; it has no direct visible effect on how artifacts are created.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Remote-bridge teardown telemetry reworked with archive-credential and worker-epoch fields

Remote session-bridge teardown telemetry reworked with archive-credential and worker-epoch details

**Unclear.** Nothing has been read yet about the `tengu_bridge_repl_teardown` gate, so whether this behavior is active for any account is unknown.

**What**

The teardown process for the remote session bridge (`bridge_repl_v2_teardown`) was refactored: telemetry about pending flushes and archive status is now built through two new helper functions and merged into the reported event. When a worker's bearer token is available, the bridge host interface now also exposes a `getWorkerEpoch` accessor alongside the existing `getWorkerBearerToken`.

**Why**

This is internal telemetry and plumbing for how a remote session bridge shuts down; it should not change what you see, though it may improve the diagnostic detail captured when a teardown happens.

- Area: Sessions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Plugin install/materialize helper gains a `preview` option

Plugin install helper gains a preview option, and marketplace installs reuse an already-resolved registry lookup

**Unclear.** What the new preview option actually does when enabled is not stated in the finding.

**What**

The internal helper that materializes (installs and links) plugins now accepts a new `preview` option, off by default, alongside its existing `linkFarm`/`linkFarmProducer` options. Separately, when installing a plugin from a marketplace entry, the code now reuses an already-resolved registry lookup to find the marketplace directory instead of performing a second, separate lookup.

**Why**

These are internal groundwork changes; the `preview` option's effect isn't described, and the marketplace-lookup change is a small efficiency cleanup rather than a behavior change.

- Area: Plugins
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Slash-command-dispatched user messages now carry an explicit permissionMode field

Messages created from slash commands now explicitly carry the current permission mode

**What**

The internal function that builds user-message objects when Claude Code dispatches a slash command now takes a `permissionMode` parameter and stamps it directly onto every message it creates.

**Why**

This ensures messages generated by slash commands carry an explicit record of the permission mode active at the time, keeping that state consistent with how it's already tracked elsewhere in the settings change-log system.

- Area: Slash Commands
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Prompt submissions are now tracked with a per-submission UUID for the duration of processing

Prompt submissions now get a unique ID tracked through processing

**What**

When a prompt is submitted, Claude Code now opens a short-lived tracked record for that submission, containing the agent ID, mode, value, and a unique ID (UUID). This same UUID is then passed along to the code that processes the submission.

**Why**

Giving each submission its own tracked ID makes it possible to correlate a specific submission with its processing, which is useful for tracing what happened to a given prompt.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### liveTranscript flag for spawned agent prompts is now conditional instead of always true

Subagent prompts now enable live transcript conditionally instead of always

**Unclear.** What condition `ps(r)` checks to decide whether liveTranscript is enabled is not stated.

**What**

When a subagent (a separate Claude instance spun up to handle part of a task) is started, the `liveTranscript` setting passed along is now computed by a function instead of always being turned on. The related `parentPromptId` lookup was also changed to read from the current message container rather than a different one.

**Why**

This means live transcript streaming for a subagent's prompt is no longer unconditional; it now depends on the computed condition, though the finding does not specify what that condition checks.

- Area: Subagents
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact publish/version actions now thread a requestId for idempotency

Artifact publish actions now pass a requestId through to the backend for idempotency

**What**

The artifact publish "version" action, along with its three underlying implementations (workshop files-only publish, live-doc publish, and the general publish path), now pass a `requestId` taken from the incoming request through to the backend publish call.

**Why**

Threading a request ID through publish calls supports idempotency, meaning a repeated or retried publish request can be recognized as the same request rather than causing a duplicate action.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Bridge inbound messages now register with a new sessionInboxPointers tracker

Bridge inbound messages now also register with a new sessionInboxPointers tracker

**Unclear.** What sessionInboxPointers is used for downstream is not stated.

**What**

When a remote/bridge control message, or a user message originating remotely, is queued, Claude Code now also records it with a `sessionInboxPointers` tracker (noting its origin, wake behavior, and unique ID), in addition to the existing lifecycle notification. This only happens when a related internal object is present.

**Why**

This adds an additional record of queued inbound messages from remote/bridge sources, which the finding does not further explain the purpose of.

- Area: Remote Control
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New per-worker-epoch tracking added to headless bridge mount setup

Headless bridge sessions now track a worker epoch when setting up the mount

**Unclear.** What the worker epoch value is used for once tracked is not stated.

**What**

When Claude Code bridges into headless or print mode, the setup call for the mount now also passes along a `getWorkerEpoch` accessor, alongside the existing storage, credentials, and session settings that were already passed.

**Why**

The finding does not explain what consumes this value, but it means the headless mount setup now carries additional worker lifecycle information that wasn't tracked before.

- Area: Sessions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact create-from-type now threads a request id and extra param into page creation

Artifact creation now passes a request ID through, and auto-opening after first write has an extra gate

**Unclear.** What the extra parameter and the new auto-open gate condition specifically check is not stated in the finding.

**What**

When the Artifacts tool creates a new artifact from a type, the call that builds the artifact page now also passes along a request ID and an additional parameter that weren't included before. Separately, the path that automatically opens an artifact after its first write is now gated by an additional check before it will open.

**Why**

Threading a request ID through artifact creation likely helps associate the creation with the request that triggered it. The added gate on auto-opening means the artifact won't necessarily pop open automatically in every case it used to.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifacts tool gains restoreTransientForRemap hook

Artifacts tool gains a restoreTransientForRemap hook shared with other tool-result mappers

**What**

The Artifacts tool, which renders an HTML file as a page on claude.ai, now includes a `restoreTransientForRemap` method. This is a hook already used elsewhere in Claude Code for restoring temporary state when a tool result's ID gets remapped.

**Why**

This brings the Artifacts tool in line with other tool-result handlers so its temporary state is preserved correctly across ID remaps, rather than being a user-facing change on its own.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New command-lifecycle tap on session inbox pointers

Session setup adds a new hook that taps command lifecycle events on session inbox pointers

**Unclear.** What tapCommandLifecycle actually does with command lifecycle events is not stated in the finding.

**What**

When a session is set up, Claude Code now optionally calls a new hook that taps into the command lifecycle for that session's inbox pointers, right after the session's outbound communication is wired up.

**Why**

The finding doesn't state what consumes this tap, so its practical effect for the reader isn't clear from the change alone.

- Area: Remote Control
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Auto-mode transcript builder gains a 'summary' turn frame

Auto-mode's transcript reconstruction now handles 'summary' turn frames, not just 'invisible' ones

**What**

The internal function that rebuilds conversation history for auto-mode's project-ownership classification now handles a new case: a 'summary' frame. When it encounters one, it folds the summarized text into a synthetic user-turn entry via a helper function. Previously, only 'invisible' frames were handled specially at this point.

**Why**

This lets the auto-mode classification process take summarized turns into account when reconstructing history, rather than only recognizing invisible ones.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact create result now reports a 'provisioned' store reference

Creating an artifact now returns a 'provisioned' field identifying where it was stored

**What**

When an artifact (a generated file or piece of content) is created, the result now includes a new `provisioned` field. It is parsed from the server's response and can contain a store identifier, a project ID, and optionally a file ID or node ID. Whether this field is present is now also recorded in telemetry.

**Why**

This gives Claude Code a structured reference to where an artifact actually landed after creation, which can be used to track or verify storage behind the scenes.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Git subprocess calls widely switched to a new env-builder `ss()`/`Ji()` in place of `ko()`

Git subprocess calls widely switched to a new environment-builder in place of the old one

**What**

Many internal functions that invoke `git` (for status, diff-cost estimation, worktree creation and removal, rev-parse, and config listing) were changed to build their process environment using a new helper instead of the previous one, and several of these now pass along a value scoped to a specific repository.

**Why**

This is an internal refactor to how git subprocesses get their environment variables; it doesn't change what these git operations do, but centralizes and scopes how their environment is constructed.

- Area: Git
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Git config include-filtering (`-c` overrides) reworked into direct call with envPins/pin args

Git config override-filtering logic reworked to take explicit args and pins instead of returning a result object

**What**

The internal function that builds `-c key=value` override arguments from `git config --includes -z --list` output was restructured. Previously it was a self-contained routine that returned a success/failure result; now it's a lower-level helper that takes explicit arguments, environment pins, and a repository pin directly, and is used by the git environment-building code.

**Why**

This is an internal refactor to how git config overrides are constructed and threaded through to git calls, changing how the logic is organized rather than what it accomplishes.

- Area: Git
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### New broad cache-invalidation helper (Bd) clears output styles, workflows, skills, agents

One new function clears cached output styles, workflows, skills and agents together

**What**

A new internal helper function clears several caches at once: the cached lists of output styles, workflows, skill directories, markdown files, and agent definitions. This runs alongside an existing reset function that already handled other cached data.

**Why**

Grouping these resets into one call makes sure that when Claude Code needs to refresh its view of custom configuration, none of these related caches are left stale by accident.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Ink root double-mount guard

Claude Code now errors loudly instead of silently overwriting a stuck terminal UI root

**What**

Claude Code's terminal interface is built with a library called Ink, which mounts a "root" to take over the terminal and put it in raw input mode. Previously, if something tried to mount a second root on a stream while a prior root was still holding the terminal in raw mode, the tracking silently overwrote the old root. Now this situation throws an explicit error telling the caller to unmount the previous root first.

**Why**

This surfaces a bug condition immediately instead of letting it fail silently, which should make it easier to catch and fix cases where the terminal UI is being mounted incorrectly.

- Area: Terminal UI
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Repo-detection caches now get invalidated by path (HUe)

Repo-detection caches are now cleared by path when a directory changes

**What**

Claude Code keeps several internal caches about repository identity, such as which root directory a path belongs to, its canonical root, its remote slug, and its git directory. A new helper walks these caches and evicts any entries whose key path matches or contains a given path.

**Why**

This prevents stale repository-identity information from lingering after a directory is moved or a repository changes, which could otherwise cause Claude Code to misidentify which repository or root a path belongs to.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### MCP tool call plumbing refactored (no clear behavior change found)

MCP tool-call code reorganized internally with no known behavior change

**Unclear.** Whether this refactor has any subtle behavioral effect beyond code reorganization is not established by the evidence.

**What**

The code that handles calling a tool through MCP (Model Context Protocol, the standard Claude Code uses to talk to external tool servers) was restructured. A callback used when a tool call is waiting on user input was pulled out into its own named function and reused in two places, and several internal helper names were renamed.

**Why**

This is an internal cleanup with no behavior change identified; it doesn't change what you see or how tools work.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### New no-op state initializer `j4o` feeding a context provider

A new always-null state value was added feeding an internal context provider

**Unclear.** It is unclear what user-facing feature or purpose this new state and context provider serves; the finding only shows a null-returning initializer being wired into a context.

**What

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Permission/tool-scoping setup takes an explicit getAllBaseTools callback

Tool permission setup now takes the base tool list as an explicit parameter

**What

The internal function that sets up which tools are allowed or disallowed (including `--tools` narrowing) now receives the full list of built-in tools as an explicit `getAllBaseTools` parameter, instead of fetching it directly from a fixed global source in multiple places.

**Why

This is an internal code organization change; it makes the tool-scoping logic easier to test and reuse without changing how `--tools` behaves for you.

- Area: Permissions
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### MCP tool-call awaiting-user-input handling consolidated

MCP tool-call user-input-waiting logic consolidated into one shared function

**What

The callback that manages a background-eligibility timer while an MCP tool call is waiting on user input was previously defined separately for each call site; it's now a single standalone function shared across the whole call path.

**Why

This is an internal cleanup that reduces duplicated code; it doesn't change how tool calls behave while awaiting your input.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Artifact tool input-validation error paths reordered/renamed

Artifact tool's input-validation checks reordered and error codes renamed

**What

The `artifact_bash` tool's input-validation logic now runs a combined check earlier than before, reuses existing helper functions, and replaces some error codes for local-only and eval-stub validation checks with named constants instead of raw values.

**Why

This is an internal code-quality change to how validation errors are structured; it doesn't change what triggers a validation error, just how it's represented internally.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Startup: fastMode/advisor settings sync extracted into shared helper

Headless startup's fastMode and advisor settings sync moved into shared helper functions

**What

When Claude Code starts up in headless mode (`--print`, used for non-interactive/programmatic use), the code that syncs `fastMode` and advisor-related settings has been moved out of inline logic into two dedicated functions, one of which adds a new settings subscription.

**Why

This is an internal restructuring of startup code; it doesn't change what settings are available or how fast mode behaves.

- Area: Startup
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Background/workflow agent(schema) execution loop — renames only

Background agent structured-output execution loop internally renamed with no logic change

**What

The code implementing the structured-output execution loop for background/workflow agents (handling retries, stalled/error states, and token/tool-call accounting) had its internal variable names changed, with no identifiable change in logic.

**Why

This is an internal cleanup with no expected effect on behavior.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### MCP client reconnect logic — renames only

The MCP client's reconnect handler was renamed internally with no logic change

**What**

The code that handles reconnecting an MCP (Model Context Protocol) client after a dropped connection was reshuffled: internal variable names changed, but the reconnection backoff timing, retry limits, and notification logic all stayed the same.

**Why**

This is internal cleanup with no effect on behavior; nothing changes for people using Claude Code.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Plugin agent loader refactored to take a single options object and drop try/catch wrapper

The plugin agent loader now takes a single options object instead of separate arguments, and lost its own error-catching wrapper

**Unclear.** The finding suggests error handling for load failures likely moved to the calling code but doesn't confirm where it now lives.

**What**

The internal function that builds an agent definition from a plugin's agent markdown file now takes a single destructured options object instead of a list of separate positional arguments. It also no longer has its own try/catch block that caught load failures, logged an error, and returned null.

**Why**

This is an internal refactor to how plugin agents are loaded.

- Area: Plugins
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Absolute-positioned element overdraw tracking in terminal renderer

Terminal renderer now tracks and repaints stale absolutely-positioned elements that overlap new content

**What**

Claude Code's terminal rendering engine gained new internal logic to track absolutely-positioned elements (parts of the interface pinned to a specific spot rather than flowing with the rest of the layout). New helper functions check whether such an element's rectangle stays within its parent's bounds, and detect when a leftover rectangle from a previous frame overlaps a newly drawn element. A new `repaintAfterStaleAbsolutePaint` method uses this to trigger a repaint when that happens.

**Why**

This is a rendering correctness fix: it should prevent stale visual artifacts from absolutely-positioned elements lingering on screen and overlapping new content after the layout changes.

- Area: Terminal UI
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Browser-selection prompt-builder simplified to a name lookup

Internal browser-selection prompt builder simplified to just naming the tool, with instruction text moved elsewhere

**Unclear.** The finding does not say what replaced the removed text-building logic beyond suspecting it moved into related new helpers, so the net effect on the final prompt text isn't confirmed.

**What**

An internal function used to build the mandatory browser-selection instructions was simplified. It previously constructed the full multi-paragraph instruction text itself; now it just returns a short phrase naming the tool to use (like 'the X tool') or a fallback mentioning the ask-user tool. The actual instruction text is now built elsewhere.

**Why**

This is an internal restructuring of how browser-selection prompts are assembled; it doesn't change what instructions Claude ultimately receives, just how the code produces them.

- Area: Chrome Control
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Critical memory usage banner text unchanged but reformatted with memoized hook

The 'Critical memory usage' banner code was reorganized with memoization, keeping the same wording

**What**

The 'Critical memory usage' banner, which suggests restarting and resuming with `--continue` and, in some cases, running `/compact` to free up context, is now rendered by a memoized component. It still only appears when memory usage is at the 'critical' tier, not the 'high' tier. The banner's text itself is unchanged.

**Why**

This is an internal rendering change; the guidance shown to users when memory usage is critical stays the same.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### registerWorker request now sends a User-Agent header

Worker registration requests to the backend now include a User-Agent header

**What**

The request that registers a worker with the backend now sends a `User-Agent` header, built by a helper function, in addition to the existing `Authorization`, `Content-Type`, and `anthropic-version` headers.

**Why**

This gives the backend more information about the client making the registration request, which can help with diagnostics or compatibility handling on the server side.

- Area: Internals
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Diff/gitdir baseline computation made lazy and cached

Repository-diff computation now happens lazily and is cached instead of running eagerly upfront

**What**

The internal helper that computes repository diffs no longer eagerly computes the git baseline it needs as soon as it runs. Instead, it computes and caches that baseline only when `fetchDiff` is actually called. A related function, `headKeyOf`, now explicitly passes a `null` baseline rather than a computed one.

**Why**

This avoids doing potentially unnecessary work computing a git baseline when it isn't needed, improving efficiency for code paths that don't end up calling `fetchDiff`.

- Area: Git
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### CreateSession request can now attach extra headers per-call

Session-creation requests can now carry extra custom headers

**What**

The internal function Claude Code uses to create a session can now accept an extra set of HTTP headers for a given call, which get merged on top of the default headers. Previously it always sent the same fixed set of headers.

**Why**

This is an internal plumbing change that allows specific session-creation calls to add headers as needed, rather than being locked to one fixed set.

- Area: SDK
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### 'core.excludesfile' resolution simplified to a pure function

Global gitignore file lookup no longer runs the git command itself, just processes the result

**What**

Claude Code figures out where your global gitignore file lives (the `core.excludesfile` git setting) so it can respect files you've told git to ignore everywhere. Previously, the function that determined this path ran the `git config --global --get core.excludesfile` command itself. Now that function just takes the already-looked-up value as plain text and processes it, without running git.

**Why**

Separating the git lookup from the processing logic is an internal cleanup; it should not change what path Claude Code ends up using, but makes that piece of code simpler to run and test on its own.

- Area: Git
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Artifacts login-required message consolidated into a shared constant

The 'Artifacts need a claude.ai login' message is now defined once as a shared constant

**What**

The message "Artifacts need a claude.ai login", shown as part of a model-precedence error, is now built from a single shared constant instead of being written directly inside that one function.

**Why**

This is an internal cleanup that keeps the wording consistent if the message is needed in more than one place; it doesn't change what the user sees.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Screen-diff renderer gains overlap detection (blitsOver)

Terminal screen-diff renderer can now detect when a region overlaps a previous 'blit' operation

**What**

The part of Claude Code that tracks what's been drawn to the terminal screen (to figure out what needs redrawing) gained a `blitsOver(rect)` method, which checks whether any previously recorded "blit" (block image/content transfer) operation overlaps a given rectangular region.

**Why**

This is used to decide whether a region left over from a previous frame that wasn't refreshed actually needs to be cleared, which helps the terminal renderer avoid unnecessary or incorrect redraw work.

- Area: Terminal UI
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Session credential rejection classifier factored into a shared helper (step_up vs credential_rejected)

Two duplicated auth-failure decision blocks were merged into one shared helper deciding step_up vs credential_rejected

**What**

The logic that decides whether an authentication failure should ask the user to re-authorize a specific scope (`step_up`) or should instead be treated as a flat `credential_rejected` failure used to be written out twice, in two separate places. Both now call a single shared function, taking the error code, whether the error looks like an unauthorized (401) response, whether it looks like an OAuth-shaped auth error, whether headers are available, and the pending step-up scope, as named inputs.

**Why**

Consolidating the two copies into one function makes both call sites behave consistently and means future fixes to this decision only need to be made once.

- Area: Auth
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### git env helper renamed/changed from ko() to Ji(e) across many git operations

Internal git environment-building helper was swapped out across many git operations

**What**

Dozens of internal git command wrappers, covering things like deleting branches, locking worktrees, listing revisions, and reading config, switched from an older environment-building helper to a new one that is also passed the working directory explicitly.

**Why**

This is an internal refactor. Passing the working directory explicitly to the environment builder makes git operations less dependent on ambient process state, which can make behavior more consistent across different working directories.

- Area: Git
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Git teleport/branch helpers now pin cwd and env to the checkout root

Git teleport and checkout helpers now pin their working directory and environment to the checkout root

**What**

Internal git helper functions used for teleport and checkout operations (setting upstream, checking out, and reading the current branch) now resolve a stable checkout root directory and pass it, along with an explicit environment, to every git subprocess they run, instead of relying on whatever the process's current directory and environment happened to be.

**Why**

This makes these git operations more reliable by removing dependence on ambient process state, reducing the chance that a git command runs against the wrong directory.

- Area: Git
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Refusal-message helper renamed/consolidated (Po -> xo)

Content-policy refusal responses now use the same result-wrapping helper as other API errors

**What**

The code that builds a refusal message for content-policy violations now wraps its result using the same helper function used elsewhere for API error responses, rather than a separate one.

**Why**

This aligns refusal responses with the same internal shape as other API errors, which is an internal consistency change rather than something that changes what a user sees.

- Area: API Errors
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Artifact database tool description strings reordered/refactored

Artifact database tool descriptions had their wording reordered

**Unclear.** Which release's prompt capture actually shows this reordering is not established, since no capture has been taken under this release yet.

**What**

The descriptions shown for the artifact tool's `read_db` and `write_db` actions (used for auto-classification and permission prompts) had parts of their sentences reordered, such as where the note about being "requested after an unattended auto-reply notification" and the shared-with clause appear.

**Why**

This is a wording change to how these descriptions read; it isn't tied to a specific version since no capture of the new text has been taken under this release yet.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Request telemetry gains rawRequestBodyId and a requestBodyId threaded into assistant-response logging

Assistant-response logging now threads a requestBodyId through the telemetry that records completions

**What**

The internal function that logs completion telemetry now takes and passes along a `rawRequestBodyId` value (previously stored under a differently named slot), and forwards a `requestBodyId` into the code path that saves assistant responses.

**Why**

This is internal bookkeeping for how Claude Code correlates a logged response with the request that produced it. It has no direct effect on how you use the tool.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Design-connector MCP detection consolidated into a shared helper

Design-connector MCP detection logic was consolidated into shared helper functions

**What**

Two nearly identical internal functions that decide whether a design-tool MCP (Model Context Protocol) server should get special design-connector treatment used to each inline their own URL-scheme/path check and auth-header check. Both now call the same shared helper functions instead.

**Why**

This is an internal cleanup that removes duplicated logic; it should not change behavior for users but makes the design-connector detection easier to maintain consistently.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Skill index cache gets an explicit clear function

A new function can explicitly clear the cache of indexed Skills

**Unclear.** The finding does not say when or under what circumstances this new clear function is actually called.

**What**

A small new function was added that clears the cached skill index, the in-memory list Claude Code keeps of available Skills.

**Why**

Having an explicit way to clear this cache lets Claude Code force a fresh read of available Skills when needed, rather than relying on stale cached data.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Internal: session options gain a shared `toolCatalog` object

Internal: sessions now pass around a shared toolCatalog object instead of calling tool-lookup functions directly

**What**

When Claude Code builds the options for a session or subagent (in the main loop, in subagents, and when resuming a session), it now threads a `toolCatalog` object through those options alongside the existing `tools` field. This object bundles the functions that get all base tools, get specific tools, and assemble a tool pool, replacing several places that previously called those functions directly.

**Why**

This is an internal refactor with no direct user-facing behavior change; it makes tool lookup more consistent across the different places sessions get constructed.

- Area: Session Management
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Marketplace git-clone path refactored; LFS warning now surfaced after clone completes

Marketplace git-clone code was restructured so LFS warnings are reported after the clone finishes, via a shared clone helper

**What**

The logic for adding or refreshing a plugin marketplace (both when refreshing multiple sources and when installing from a single source) was reorganized around a shared clone helper. Its result is now passed to a separate step that logs and reports any git LFS (Large File Storage) warnings, instead of passing a `skipLfs` option inline during the clone call itself.

**Why**

This is a restructuring of when and how LFS warnings surface during marketplace operations, separating the cloning step from the warning-reporting step.

- Area: Plugin Marketplace
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Interrupted-response continuation reminder wording unchanged, only internal renames

Interrupted-response continuation reminder is unchanged, only internal code renamed

**What**

The `[reply-on-resume]` mechanism, which prefixes a prior interrupted response with an `<interrupted-output>` reminder when Claude Code continues after being cut off, still shows the same text to users. Only internal variable and helper names changed.

**Why**

This is a behind-the-scenes rename with no visible effect for users.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Transfer-copy upload code renamed only (no behavior change)

Transfer-copy upload verification code renamed internally with no behavior change

**What**

The code that handles clipboard/transfer-copy uploads, reading a transfer copy, verifying its integrity, writing it to disk with a hashed filename, and returning counts, had its internal variable names changed. The underlying logic is the same.

**Why**

This is an internal rename with no effect on behavior.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### rewind_conversation internals refactored into shared helper functions

rewind_conversation's internals were split out into shared helper functions, with no behavior change noted

**What**

The handler for the `rewind_conversation` remote request - which rewinds a conversation to an earlier point - has been restructured. The logic for persisting the rewind, checking whether the session state has drifted, mirroring and logging failures, and stopping any in-flight agents past the cut point now lives in separate helper functions instead of being written inline. Stopping in-flight agents is now driven by a cut index rather than the previous predicate-based walk through agent ancestry.

**Why**

This is an internal code reorganization rather than a change in what `rewind_conversation` does for the user.

- Area: Sessions
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Plugin skill loading now passed the plugin name

Plugin skill loading now also receives the plugin's own name

**Unclear.** What using the plugin name in the skills loader actually changes for the reader is not stated.

**What**

When Claude Code lists what a plugin provides - its commands, agents, skills, hooks, and MCP servers - the function that loads the plugin's skills now also receives the plugin's name, in addition to the skill file path(s) it already received.

**Why**

Passing the plugin name alongside its skill paths likely lets the skill loader associate skills with the plugin they came from, though the finding doesn't specify what this enables in practice.

- Area: Plugins
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Session/turn wiring in the REPL hook (v8e) renumbered, no behavior change found

REPL session/turn wiring code was renumbered internally with no behavior change found

**What**

A large block of internal caching slots used by the React compiler in the REPL's session hook was renumbered, and some local variable names were swapped around. The same underlying session, turn, and notification objects - including idle-notification thresholds - are still wired up the same way.

**Why**

This is an internal code reshuffle with no found effect on behavior.

- Area: Terminal UI
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

## Removed

### Artifact publish validation: removed a restriction on auto_open:"after_first_write"

The inert check blocking auto_open:"after_first_write" with certain tool settings has been removed entirely

**What**

The validation check that rejected artifact publishes setting `auto_open: "after_first_write"` together with a specific tool-availability condition has been removed from the artifact publish input validator, along with its error message.

**Why**

This check could never actually fire in practice, so removing it has no visible effect on what `auto_open: "after_first_write"` publishes are allowed to do.

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