# Claude Code v2.1.268

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

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

This build carries 26 dormant additions, most left unswitched. A new allowed_domains parameter lets the model tell a sandboxed Bash, PowerShell, or Monitor command which network hosts it needs, gated behind a flag that isn't confirmed live yet. The sandbox config also gains schemas for routing traffic through a MITM proxy and masking credentials in environment variables, including JWT decoding, alongside experimental in-process TLS termination and upstream parent-proxy support. Other pieces sitting dark include a 'governed git' push-URL relay for self-hosted and cloud sessions, a bounded self-expiring watch mode for the Monitor tool, a disk-space watchdog off by default, and a new bridge dialog that would warn when a tool tries to read outside its allow-list.

Of the 157 shipped entries, Remote Control can now fork a running conversation into a brand-new session, and plugins gain two actions, prompt.fill and prompt.suggest, to fill in or suggest text in the prompt box directly. A new 'Prompt suggestions' setting predicts and pre-fills your likely next prompt after a turn. Org admins get a gatewayInternalNetworks managed setting restricting /login to gateway hosts inside declared private network ranges, and managed plugins can now pin specific plugins to run first or last among hooks via prependPlugins/appendPlugins. The workflow-keyword trigger setting also reveals its internal codename, now labeled 'Ultracode keyword trigger' in settings.

Among 60 fixes, settings.json now validates environment variables, dropping invalid names, values, or NUL bytes with a warning instead of silently using them. Resuming a background teammate now requires folder trust before restoring its custom agent definition, and per-command network allowlists are now enforced against actual sandbox confinement, refusing commands that would otherwise run unconfined. Stale model-access denials are no longer cached forever, with the server re-probed so they can self-heal, and Bash permission checks gain a fallback path-based deny check for when full command parsing fails.

## 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 "fork_conversation" control request forks a session's history into a new SDK-hosted session

A new fork_conversation control request lets a host app branch a session's history into a brand-new session

**Unclear.** Whether this feature is active for a given user is unread, since the gate `tengu_cozy_pixel` has no recorded reading.

**What**

Claude Code now supports a `fork_conversation` request that a host application or SDK client can send to branch off the current session. It copies the conversation history (optionally cut off at a chosen message) into a brand-new session hosted via the SDK backend, seeded with that prior history.

**Why**

This lets tools built on Claude Code create a new, independent session starting from an existing conversation's history, for example to explore a different direction without altering the original session.

- Flag `tengu_cozy_pixel`: Not enough to say (read for one account on one subscription tier against v2.1.268; this account: no value returned, anonymous baseline: no value returned, compiled default: off)
- Area: Sessions
- Names: `fork_conversation`
- Tier: Use it now
- Useful: 5/5
- Signal: 4/5

### New plugin API actions: prompt.fill and prompt.suggest

Plugins can now fill in or suggest text directly in the prompt input box via two new prompt.fill and prompt.suggest actions

**What**

Claude Code's plugin system (which lets extensions add extra capabilities) gained two new actions plugins can trigger: `prompt.fill` and `prompt.suggest`. These let a plugin write text directly into the prompt input box (the composer) or propose text to the user, alongside the existing actions like submitting a prompt, calling a tool, or spawning a subagent (a secondary Claude instance handling part of a task). The same two names were also added as hook events (points where a plugin's own code can run in response to something happening), so plugin authors can write handlers that respond when text is filled or suggested. A new `composer` object with `write`/`propose` methods was also added to the plugin host so plugins can trigger this directly. Both actions have their own budget-tracking objects and are logged with character counts and whether the fill or suggestion was actually applied.

**Why**

This gives plugins a way to actively populate or propose prompt text for the user, rather than only reacting to what the user types, opening up new kinds of assistive or automated plugin behavior.

- Area: Plugins
- Names: `prompt.fill`, `prompt.suggest`
- Tier: Use it now
- Useful: 5/5
- Signal: 4/5

### Remote Control gains a fork_conversation tool

Remote Control can now fork a conversation into a brand-new session

**Unclear.** Whether `fork_conversation` is active for this site's account is unread from the `tengu_cozy_pixel` gate, so it's unclear if it's currently reachable.

**What**

Remote Control (controlling a Claude Code session from another device) gains a `fork_conversation` tool. It can branch a conversation off from a specific message or from the whole transcript, saving a size-limited snapshot of it to a file, then attach that snapshot to a newly created session so the fork can pick up, discard, or double-check it when that session starts. If forking can't proceed, it now reports specific reasons such as a turn already running, commands still queued, a prompt still pending, the target message not found, or history being suppressed.

The remote-control slash command can also now be disabled with an explicit, distinct reason shown to the user, rather than just being hidden with no explanation.

**Why**

This lets you branch off an existing Remote Control conversation into a separate session without starting over, and gives clearer feedback both when a fork can't be created and when the remote-control command itself is unavailable.

- Flag `tengu_cozy_pixel`: Not enough to say (read for one account on one subscription tier against v2.1.268; this account: no value returned, anonymous baseline: no value returned, compiled default: off)
- Area: Remote Control
- Names: `fork_conversation`
- Tier: Use it now
- Useful: 5/5
- Signal: 4/5

### Bash/PowerShell/Monitor tools can declare per-command network allowlists (`allowed_domains`)

Bash, PowerShell, and Monitor tools can now declare extra allowed network domains for sandboxed commands

**Unclear.** Whether this field is active for a given user depends on an unread setting (tengu_flickering_rain), so it's unclear if it's currently enabled anywhere.

**What**

Sandboxed command tools (Bash, PowerShell, and Monitor) gain a new `allowed_domains` field, which lets Claude Code's automatic mode specify extra network hosts that a sandboxed command is allowed to reach. The values are checked against anti-spoofing rules that reject things like loopback addresses, IPv4-mapped addresses, and mismatched canonical forms, and the field is rejected outright if the command isn't actually going to run inside a sandbox.

**Why**

This lets a sandboxed command reach network hosts it specifically needs, without opening up broader network access or being tricked by disguised addresses.

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

### Monitor tool gains a bounded, self-expiring watch mode (behind tengu_breezy_crescent)

Monitor tool watches can now be capped with an auto-expiring timeout instead of running forever

**Unclear.** Whether this bounded behavior is active for a given user depends on the tengu_breezy_crescent setting, which is currently off for this site's account and the anonymous baseline, and has not yet been read under this release.

**What**

The Monitor tool, used to watch a running background task or command, is changing from a model where a monitor could run indefinitely (until stopped or the session ended) to one where every monitor gets a maximum `timeout_ms`, with a default and a cap. When a watch expires, Claude Code kills it and sends a one-time notice reporting the elapsed time and how many events were delivered (or none), telling the model to re-arm a new watch rather than expecting the old one to keep polling.

**Why**

This prevents a monitor from running unbounded and instead nudges the model to periodically re-establish its watch, which should avoid stuck or forgotten long-running watches.

- Flag `tengu_breezy_crescent`: Not enough to say (read for one account on one subscription tier against v2.1.268; this account: no value returned, anonymous baseline: off, compiled default: off)
- Area: Monitor Tool
- Names: `timeout_ms`
- Tier: Nothing to try yet
- Useful: 5/5
- Signal: 4/5
- Present in the build but not switched on

### New `allowed_domains` parameter for sandboxed Bash commands, gated dark by tengu_flickering_rain

A new allowed_domains parameter lets the model tell a sandboxed Bash command which network hosts it needs, feature-flagged and not yet confirmed live

**Unclear.** Whether tengu_flickering_rain is switched on for any given user is not known from this evidence.

**What**

The Bash tool gains a new `allowed_domains` parameter, letting the model list the network hosts (plain domains, wildcards, or IP addresses, each with an optional port) that a sandboxed shell command needs to reach. In auto mode, this list is reviewed together with the command by the auto-mode classifier and applied just for that one command's run; in any other mode, the parameter is ignored. The whole feature only turns on when several internal conditions are all true, including a check on the `tengu_flickering_rain` setting, sandboxing being enabled, and some other internal checks.

**Why**

This is meant to let sandboxed commands (commands run in a restricted environment with limited network access) reach specific hosts they legitimately need, without opening up broader network access.

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

### New env var CLAUDE_CODE_QUESTION_OPTIONAL_DESCRIPTIONS, gated to specific entrypoints

New CLAUDE_CODE_QUESTION_OPTIONAL_DESCRIPTIONS env var makes AskUserQuestion option descriptions optional, but only for certain entrypoints

**What**

A new environment variable, `CLAUDE_CODE_QUESTION_OPTIONAL_DESCRIPTIONS`, makes the descriptions attached to answer options in `AskUserQuestion` (the tool Claude uses to ask the user multiple-choice questions) optional instead of required. It only takes effect when Claude Code's `CLAUDE_CODE_ENTRYPOINT` is one of a fixed set: `sdk-ts`, `sdk-py`, `sdk-cli`, `local-agent`, `claude-desktop`, or `claude-desktop-3p`, or when the session is remote.

**Why**

This lets SDK-based integrations and the desktop app skip writing option descriptions for `AskUserQuestion` where they aren't needed, without changing the requirement for other entrypoints.

- Area: AskUserQuestion
- Names: `CLAUDE_CODE_QUESTION_OPTIONAL_DESCRIPTIONS`
- Tier: Use it now
- Useful: 4/5
- Signal: 4/5

### New 'governed git' push-URL wiring for self-hosted/cloud sessions

New 'governed git' system routes pushes through a session-scoped relay for self-hosted and cloud sessions

**What**

A new subsystem rewrites a governed git repository's push URL so pushes go through a "git mount" relay using a credential helper scoped to the current session, rather than pushing directly. It keeps this in sync with a `git_mount_push_base_url` value read live from the `/remote` endpoint, and can withdraw or restore this rewriting as the session's token changes.

**Why**

This lets self-hosted and cloud sessions push to git repositories through a controlled, session-scoped relay instead of using credentials directly, and keeps that routing up to date as the session's authorization changes.

- Area: Self-Hosted Git
- Names: `/remote`
- Tier: You'll notice
- Useful: 4/5
- Signal: 4/5

### Disk-space watchdog added (gated, off by default)

A new gated background watchdog can warn or take action when disk space runs low

**Unclear.** Whether this watchdog and its warnings are active for any given user depends on gates (`tengu_ccr_disk_watchdog`, `tengu_disk_low`, `tengu_disk_drain`) that have not been read, so nothing is known about their current state.

**What**

Claude Code has a new background watchdog that periodically checks how much disk space is used on the drive holding the current working directory. It can emit warning and 'drain' telemetry and log messages when usage crosses 85% or 95%, uses hysteresis (so it doesn't flip back and forth right at the threshold), and uses a lock file shared across processes so multiple Claude Code instances don't duplicate the check.

**Why**

Running low on disk space can cause hard-to-diagnose failures; a watchdog like this is meant to surface the problem before it does.

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

### Experimental in-process TLS termination and upstream parent-proxy support added to sandbox network config

Sandbox can now terminate HTTPS itself and route traffic through an upstream proxy, both experimental

**What**

Two new experimental sandbox network settings:

- `network.tlsTerminate` lets the sandbox terminate HTTPS connections itself, making request and response bodies visible to request filtering and credential injection; an `excludeDomains` option opts specific hosts (such as ones using certificate pinning) out of this.

- `network.parentProxy` lets the sandbox's proxy route outbound traffic through an upstream HTTP proxy, falling back to the `HTTP_PROXY`, `HTTPS_PROXY`, and `NO_PROXY` environment variables if not explicitly set.

Credential masking now requires `tlsTerminate` to be turned on, unless you explicitly opt out with `allowPlaintextInject` (off by default).

**Why**

Terminating TLS in-process lets the sandbox actually inspect and mask credentials inside encrypted traffic instead of only seeing opaque bytes, but both features are marked experimental, so behavior may still change.

- Area: Sandbox Network
- Names: `network.tlsTerminate`
- Tier: Nothing to try yet
- Useful: 4/5
- Signal: 4/5
- Present in the build but not switched on

### Sandbox schema additions: MITM proxy domain routing and env-var credential masking with JWT decode

Sandbox config gains schemas for routing traffic through a MITM proxy and masking credentials in environment variables, including JWT handling

**What**

Two new configuration schemas appear in the sandbox (the restricted environment Claude Code can run commands in). One configures a man-in-the-middle (MITM) proxy, a proxy that can inspect and route traffic, specifying a `socketPath` and which `domains` should be routed through it.

The other wraps environment variables that carry credentials, with several options:

- `mode` and `extract`, using a regex to mask only part of a variable's value

- `onExtractNoMatch`, set to `warn`, `deny`, or `error` for when the regex doesn't match

- `decode: "jwt"`, which replaces a JWT (a signed token format) with a structurally valid fake token while sandboxed, swapping the real one back in when traffic leaves the sandbox

- `maskClaims`, to mask only specific named fields inside a JWT

- `injectHosts`, to limit which hosts actually receive the real credential

**Why**

These give sandboxed commands a way to see plausible-looking credentials and tokens without exposing the real values, while still letting real credentials reach an approved proxy or a narrow set of trusted hosts.

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

### New local-pairing protocol for the Chrome extension bridge

Claude Code adds an encrypted local-pairing handshake for connecting to the Claude-in-Chrome extension

**What**

Claude Code now includes a new subsystem for establishing a secure, end-to-end encrypted connection to the Claude-in-Chrome browser extension, called "local pairing." It uses ECDH key exchange (a way for two parties to agree on a shared secret) over the P-256 curve, HKDF key derivation, and AES-GCM encryption to build a sealed communication channel, alongside the existing plain local socket bridge.

The system includes:

- JWT-based attestation checked against an issuer and JWKS endpoint (`/api/oauth/local_pairing/attest` and `/api/oauth/local_pairing/jwks.json`)

- pairing offer/accept/done handshake messages

- sealed request/response message framing

- liveness probing to detect a dropped connection

- pairing-state callbacks (`onPairingState`) reporting states like `pairing`, `established`, `refused`, and `closed`

**Why**

This strengthens the connection between Claude Code and the Claude-in-Chrome extension by encrypting and authenticating the pairing handshake, rather than relying on a plain local socket.

- Area: Chrome & Browser
- Tier: Under the hood
- Useful: 4/5
- Signal: 4/5

### New 'Prompt suggestions' feature (predicted next-prompt)

New 'Prompt suggestions' setting can predict and pre-fill your next prompt after a turn

**What**

A new setting, `promptSuggestionEnabled`, controls a feature called 'Prompt suggestions.' When enabled, Claude Code can generate a predicted next prompt after a turn finishes and show it as a grayed-out suggestion in the input box, or pre-fill it as a draft you can edit or send.

**Why**

This can save time by suggesting what you might type next, though the setting also lets you hide these suggestions if you'd rather not see them.

- Area: Prompt Input
- Names: `promptSuggestionEnabled`
- Tier: Use it now
- Useful: 5/5
- Signal: 3/5

### Sandbox system-prompt text rewritten to describe allowed_domains / auto-mode network review

Sandbox instructions shown to the model were rewritten to explain listing needed hosts and reacting to blocked-host violations

**Unclear.** Whether this rewritten guidance is actually shown to any given user depends on the same unread tengu_flickering_rain setting.

**What**

The sandbox instructions built into the system prompt (under a '`command sandbox`' heading) were substantially rewritten for when the new network-list capability is active. The model is now told to list every host a command needs, that the sandbox is applied per command at the operating-system level, and to check a `<sandbox_violations>` block for any denied hosts. If a host was denied, the instructions say to re-run the command with that host added to `allowed_domains` when in auto mode. Separately, the wording used when sandboxing is fully disabled by policy was softened from a blanket prohibition to language that tells the model to ask the user instead.

**Why**

This gives the model concrete steps to follow when a sandboxed command is blocked from reaching a network host, instead of leaving it to guess how to retry.

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

### Model family allowlist extended with placeholder future models

Model list now recognizes placeholder future Claude models like claude-opus-4-6 and claude-sonnet-4-6

**Unclear.** The finding does not say whether these models are actually available or when they might be.

**What**

The internal list of known first-party Claude model families was extended to include `claude-opus-4-6`, `claude-opus-4-7`, and `claude-sonnet-4-6`, alongside the existing 4.x and 4.5 entries. A helper was also added to check whether a model string contains "application-inference-profile".

**Why**

This is preparatory groundwork so Claude Code recognizes these model names if and when they become available, rather than treating them as unknown; it does not mean these models are usable now.

- Area: Model Catalog
- Names: `claude-opus-4-6`, `claude-opus-4-7`, `claude-sonnet-4-6`
- Tier: Under the hood
- Useful: 3/5
- Signal: 4/5

### New virtual plugin "surface" bundling/runtime scheme

A new "surface" virtual-module system lets plugin desktop UI code import from special surface:/// and claude: URIs

**Unclear.** What plugin authors can now build with this that they couldn't before is not detailed.

**What**

Claude Code now has a new module-loading scheme for plugin desktop UI components. Plugin source code can import from virtual addresses like `surface:///...`, `surface-unlinked:///computed#...`, and virtual modules named `claude:hooks-types` and `claude:surface-runtime`. Import statements in plugin source are rewritten to these virtual forms before the plugin code runs inside its sandboxed virtual machine.

**Why**

This is infrastructure for building plugin UI components, giving plugin code a controlled set of virtual modules to import from rather than reaching into the real filesystem or module system, which fits with running plugin code in a sandbox.

- Area: Plugins
- Names: `surface:///`, `claude:hooks-types`, `claude:surface-runtime`
- Tier: Under the hood
- Useful: 3/5
- Signal: 4/5

### --trust-workspace gains a stricter mode referencing cli#44151, still on by default

--trust-workspace help text now documents a stricter mode that drops repo-committed permission grants

**What**

The help text for the `--trust-workspace` flag now documents a second, stricter enforcement mode. Setting `--trust-workspace` (or its environment variable) to `false` now triggers this stricter gate: permission grants committed to the repository's own settings (via `permissions.allow`) are dropped, with a warning like "Ignoring N permissions.allow" printed to the terminal. Instead, such grants have to live in the host machine's own `settings.json`, not the repo's.

**Why**

This stops a checked-out repository from being able to grant itself extra tool permissions just by having them committed to its settings files. Anyone relying on repo-committed `permissions.allow` entries needs to move those grants to their local `settings.json` if they set `--trust-workspace` to false.

- Area: Trust
- Names: `permissions.allow`
- Tier: Use it now
- Useful: 4/5
- Signal: 3/5

### CLAUDE_CHROME_PAIRED_DEVICE_ID environment override for Claude in Chrome pairing

A new CLAUDE_CHROME_PAIRED_DEVICE_ID env var pins which paired browser device Claude in Chrome connects to

**What**

Claude in Chrome (the browser extension bridge that lets Claude Code control a Chrome browser) can now be pointed at a specific paired device using a new `CLAUDE_CHROME_PAIRED_DEVICE_ID` environment variable. When set, this value is checked against the expected device-id format; if it doesn't match, Claude Code ignores it and logs a warning instead of using it.

**Why**

This lets you pin bridge setup to one specific browser-extension device rather than letting Claude Code pick automatically, which matters if you have more than one paired device and want predictable connections. The format validation means a mistyped or malformed id fails safely with a warning rather than causing a confusing connection error.

- Area: Chrome & Browser
- Names: `CLAUDE_CHROME_PAIRED_DEVICE_ID`
- Tier: Use it now
- Useful: 4/5
- Signal: 3/5

### Draft can now be filled/suggested programmatically (prompt-suggestion completion)

The input box can now have text filled in or suggested for you programmatically

**Unclear.** What feature triggers fillDraft or suggestDraft, and what a 'generated' suggestion looks like to the user, is not stated.

**What**

The controller behind Claude Code's input box (the "draft" you type into before sending) gained two new capabilities: `fillDraft`, which writes text directly into the box, and `suggestDraft`, which proposes text as a suggestion. The suggestion path marks the draft's state as 'generated', attaching the suggested text and a generation request ID, and only takes effect when the input box is currently empty and no dialog is open.

**Why**

This is the mechanism that would let Claude Code offer or fill in a suggested prompt for the user to accept, rather than requiring the user to type it themselves.

- Area: Prompt Input
- Names: `fillDraft`, `suggestDraft`
- Tier: Use it now
- Useful: 4/5
- Signal: 3/5

### Internal codename 'Ultracode' revealed for the workflow-keyword trigger setting

The setting that lets the word 'ultracode' start a workflow is now labeled 'Ultracode keyword trigger' in settings

**What**

The settings panel now shows a row called "Ultracode keyword trigger" (setting id `workflowKeywordTriggerEnabled`, on by default). It controls whether typing the word `ultracode` in a prompt automatically starts a [workflow](/docs/en/workflows) — Claude Code's mode for running a multi-step task across several coordinated agents. Related messages tell you when this happened: "Dynamic workflow requested for this turn" when the keyword triggered a workflow, and "Ultracode keyword ignored for this prompt" when it didn't.

Turning the setting off lets you type the word `ultracode` in a prompt without it starting a workflow.

**Why**

This gives a name to a setting that already existed, and a way to type the trigger word for other reasons without it kicking off a workflow you didn't intend to run.

- Area: Workflows
- Names: `workflowKeywordTriggerEnabled`, `ultracode`
- Tier: Use it now
- Useful: 4/5
- Signal: 3/5

### Managed plugin hook "seating" can now be driven by a managed `prependPlugins` list, not just org tier

Managed prependPlugins settings can now force the hooks-modules plugin to load first, not just org tier

**What**

Claude Code decides whether the internal hooks-modules plugin should be seated as the outermost plugin, which affects hook execution order. Previously this was decided only by whether the organization was on a Team or Enterprise plan. Now it also checks a managed `prependPlugins` setting: if that setting explicitly lists the hooks-modules plugin, it gets seated at the position specified, reported as "seated by managed prependPlugins at position N"; if the setting exists but doesn't list it, that's reported as "not seated: managed prependPlugins does not list it."

**Why**

This gives administrators a way to control hook plugin ordering directly through managed settings, rather than that ordering being tied only to the organization's plan tier.

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

### Managed plugins can pin hook ordering with prependPlugins/appendPlugins

Org admins can now pin specific plugins to run first or last among hooks

**What**

Organizations managing Claude Code settings can now use two new keys, `prependPlugins` and `appendPlugins`, to list plugins (in `plugin@marketplace` form) whose hooks should run first (outermost) or last (innermost) in the chain of hook execution, when multiple plugins define hooks. This replaces the previous internal `secDefault` setting, which only ever placed one bundled plugin, sec-default, outermost.

**Why**

This gives organizations general control over hook execution order across any plugins, instead of a fixed, single-purpose mechanism that only applied to one built-in plugin.

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

### Managed settings can restrict a Cloud gateway sign-in to your org's public IP block

Managed settings can now restrict Cloud gateway sign-in to CIDR blocks matching the org's own public IP

**What**

A new admin-only managed-settings key, `gatewayInternalNetworks`, lets an organization list up to 4 non-overlapping public IP ranges (CIDR blocks, from /8 to /32) that its Cloud gateway resides in. With this set, `/login` will only accept a gateway inside one of those listed ranges when the signing-in machine's own address on that direct connection also falls inside the same range; otherwise sign-in is refused. This is wired into the login flow and `forceLoginGatewayUrl`, with dedicated error messages for the various failure cases.

**Why**

This lets an organization lock down Cloud gateway sign-ins so they only succeed from within its own network, preventing sign-in through a gateway URL from outside the organization's expected IP ranges.

- Area: Gateway
- Names: `gatewayInternalNetworks`, `/login`, `forceLoginGatewayUrl`
- Tier: Use it now
- Useful: 4/5
- Signal: 3/5

### New 'claude rm' subcommand flags for background sessions

claude rm gains --discard-unpushed and --force-remove-worktree flags for cleaning up background session worktrees

**What**

The `claude rm` command, used to remove background sessions, has two new flags:

- `--discard-unpushed <commit>@<worktree-id>` — discards unpushed or uncommitted changes on a worktree that is still at the given commit

- `--force-remove-worktree <worktree-id>` — force-deletes a worktree directory when the `WorktreeRemove` hook or git itself couldn't remove it

**Why**

These give a way to clean up leftover worktrees and unpushed changes from background sessions that couldn't be removed automatically, instead of leaving them stuck.

- Area: Sessions
- Names: `claude rm`
- Tier: Use it now
- Useful: 4/5
- Signal: 3/5

### New --remove-session-state flag for self-hosted runner

Self-hosted runner can now delete a session's leftover files when the session ends

**What**

The `claude self-hosted-runner` command line tool gets a new `--remove-session-state` flag (also settable via the `SELF_HOSTED_RUNNER_REMOVE_SESSION_STATE` environment variable). When enabled, ending a session now removes that session's stored state under its `_sessions/` folder, including its Claude config directory (transcript copy, shell snapshots, session environment, file history, debug log), staged uploads, per-session git configuration, and the session's working directory.

- Accepts `true`/`false`/`1`/`0`, and defaults to `true` if you pass the flag with no value.

- Off by default, so existing behavior is unchanged unless you turn it on.

- Cleanup is best-effort: files are safely renamed then deleted, and at startup the runner logs whether these per-session files will be removed or kept.

- The runner logs how many of the targeted paths were actually removed versus already absent, and this also affects whether the debug log tail is sent to server-side session diagnostics or kept on disk.

**Why**

This lets self-hosted runner operators avoid accumulating leftover session files (transcripts, uploads, git config, working directories) on disk after each session, which matters for storage management and for not retaining session data longer than needed.

- Area: Self-Hosted Runner
- Names: `SELF_HOSTED_RUNNER_REMOVE_SESSION_STATE`
- Tier: Use it now
- Useful: 4/5
- Signal: 3/5

### New AWS SigV4 masked-credential signing policy, default deny

New sandbox setting controls whether AWS-signed requests the proxy can't re-sign are denied or passed through

**What**

When the sandbox's credential-masking proxy substitutes fake AWS credentials, some request shapes can't be re-signed with the real ones afterward. A new `sigv4` policy setting now governs what happens in three such cases:

- `streaming` (chunked uploads using `aws-chunked` encoding)

- `presigned` (URLs with an embedded signature)

- `sigv4a` (asymmetric AWS signatures)

All three default to "deny", meaning the request fails closed with a 403 error, unless explicitly set to "passthrough".

**Why**

This closes a gap where masked AWS credentials could otherwise be silently forwarded in a request the proxy has no way to properly re-sign; the safe default is to block rather than send a request that might leak or fail unexpectedly.

- Area: Sandbox Credentials
- Names: `sigv4`
- Tier: Use it now
- Useful: 4/5
- Signal: 3/5

### New CLAUDE_CODE_RESUME_REASON env var for interrupted turns

New CLAUDE_CODE_RESUME_REASON env var labels why an interrupted turn was resumed

**What**

A new environment variable, `CLAUDE_CODE_RESUME_REASON`, can now be set to a short lowercase tag (letters and underscores only, up to 64 characters) that becomes the recorded reason for resuming a turn that was interrupted. If the value doesn't match that pattern, Claude Code falls back to the default reason, `interrupted_turn`. A new `interruptedTurnUserMessageUuid` field also now records which prior user message an interruption corresponds to.

**Why**

This gives tooling built around Claude Code a way to tag and later trace why a particular turn was resumed after an interruption, and to tie that resumption back to the specific user message it interrupted.

- Area: Sessions
- Names: `CLAUDE_CODE_RESUME_REASON`
- Tier: Use it now
- Useful: 4/5
- Signal: 3/5

### New managed-settings key gatewayInternalNetworks restricts /login to declared network CIDRs

New gatewayInternalNetworks managed setting restricts /login to gateway hosts inside declared private network ranges

**What**

A new managed-settings field, `gatewayInternalNetworks`, lets administrators declare the private network ranges (CIDR blocks) that a gateway login host is expected to resolve within. Claude Code validates this list, rejecting public, documentation, reserved, or overlapping ranges and capping how many can be listed.

When this setting is present, `/login` now checks that both the DNS resolution of the gateway host and the actual TLS connection to it land inside the declared network range. If either the machine's resolution or the gateway's answer falls outside that range, sign-in is refused with a specific error.

**Why**

This lets administrators ensure that gateway sign-in only succeeds when the connection genuinely stays within their organization's private network, guarding against a gateway host that resolves or connects somewhere unexpected.

- Area: Gateway
- Names: `gatewayInternalNetworks`
- Tier: Use it now
- Useful: 4/5
- Signal: 3/5

### New resume_reason field on streaming assistant-message frames

Streaming assistant messages can now carry a resume_reason explaining an automatic re-run after an interruption

**What**

Streaming partial-message frames can now include a `resume_reason` field that explains why the current turn is an automatic re-run of one that got interrupted. The possible reasons are `host_draining`, `checkpoint_restore`, `container_recreated`, or a fallback `interrupted_turn`. This is tied to two environment variables, `CLAUDE_CODE_RESUME_INTERRUPTED_TURN` and `CLAUDE_CODE_RESUME_REASON`.

**Why**

This lets whatever is consuming the stream distinguish a turn that's continuing normally from one that's being automatically resumed after the underlying worker process was restarted, restored from a checkpoint, or recreated, rather than the interruption looking like an unexplained restart.

- Area: Streaming
- Names: `resume_reason`, `CLAUDE_CODE_RESUME_INTERRUPTED_TURN`, `CLAUDE_CODE_RESUME_REASON`
- Tier: Use it now
- Useful: 4/5
- Signal: 3/5

### New scale parameter for browser screenshot/zoom, extension-version gated

Browser screenshot and zoom actions gain a scale option to shrink image size and token cost

**What**

The screenshot and zoom actions in the Claude in Chrome browser tool now accept a `scale` parameter. Setting it to 0.5 returns a quarter-size image, which reduces the number of tokens the image consumes.

**Why**

Smaller images cost fewer tokens, so this gives more control over that tradeoff, but it depends on the Claude in Chrome browser extension version installed: only versions that support `scale` will actually return a reduced image, while older extensions will keep returning the full-size image regardless of the setting.

- Area: Chrome & Browser
- Names: `scale`
- Tier: Use it now
- Useful: 4/5
- Signal: 3/5

### Plugin CLI commands (disable, disable-all, update) gain --json output

Plugin disable, disable-all, and update commands gain --json output alongside other plugin commands

**What**

The `claude plugin disable`, `disable-all`, and `update` commands now support a `--json` option. With it set, they print a single structured result line (fields like command, outcome, plugin, pluginId, scope, message, and for updates, updateOutcome/oldVersion/newVersion) instead of the usual checkmark-prefixed human-readable message.

This is part of a broader rollout across plugin commands:

- `install`, `enable`, `disable`, and `uninstall` now support `--json` for structured output, with `uninstall --json` refusing to combine with `--prune`.

- Several plugin subcommands, including `prune` and install-related commands, gained the same `--json` option, all preserving existing exit codes.

**Why**

This lets scripts and other tools drive plugin management and reliably parse the result, rather than scraping human-facing text, while behaving the same as before for interactive use.

- Area: Plugins
- Names: `--json`, `claude plugin disable`, `claude plugin disable-all`, `claude plugin update`
- Tier: Use it now
- Useful: 4/5
- Signal: 3/5

### Sandbox-runtime credential masking gains JWT decoding, claim-level masking, and duplicate-value scrubbing

Sandbox credential masking adds JWT decoding, per-claim masking, and scrubbing of duplicate secret values

**What**

The sandbox's credential-masking configuration (under `credentials.files` and `credentials.envVars`) gains new options:

- `decode: 'jwt'` locates and verifies JWT-shaped values (a common token format) before masking them

- `maskClaims` masks only specific named fields inside a decoded token instead of blanking the whole value

- `maskDuplicates` also scrubs any verbatim repeats of a captured secret found elsewhere, not just the original regex match

Behavior when a configured pattern fails to match is now controlled by `onExtractNoMatch`, which can warn, deny, or error, and defaults to warn.

**Why**

These options give finer control over how sensitive tokens are found and redacted in sandboxed environments, including tokens that repeat elsewhere in output and tokens embedded inside JWTs.

- Area: Sandbox Credentials
- Names: `credentials.files`, `credentials.envVars`
- Tier: Use it now
- Useful: 4/5
- Signal: 3/5

### reload_plugins SDK request gains a hold_on_cache_impact option to avoid silent cache invalidation

reload_plugins can now hold off reloading if it would invalidate the prompt cache, via a new hold_on_cache_impact option

**What**

The `reload_plugins` request (used by the `/reload-plugins` command and by the SDK) now accepts an optional `hold_on_cache_impact` flag. When set, if reloading plugins would change the session's tool list in a way that invalidates the prompt cache (the cached record of the conversation-so-far that lets Claude skip reprocessing it), the reload is skipped instead of applied. The response then reports `held: true` along with a `cache_impact` breakdown of what would have changed: `mcp_servers_added`, `mcp_servers_removed`, or `lsp_tool_change`. The session keeps its current plugins in that case.

This mirrors a check the interactive `/reload-plugins` command already makes before it asks for `--force`. In the Agent SDK, the equivalent `reloadPlugins()` call now accepts a `holdOnCacheImpact` flag that gets sent as this same option.

**Why**

This lets SDK integrations and other callers opt into the same cache-safety check the interactive command already had, avoiding a silent, expensive cache invalidation when plugins change.

- Area: Plugins
- Names: `hold_on_cache_impact`, `reload_plugins`, `/reload-plugins`
- Tier: Use it now
- Useful: 4/5
- Signal: 3/5

### Hooks can now interrupt a running permission-prompt tool call

Hooks can now cancel a tool call while its permission prompt is still waiting for you to respond

**What**

A hook is custom code that runs automatically at certain points in Claude Code, such as before a tool is used. Previously, once a tool call reached its permission prompt (the dialog asking you to approve or deny a tool), a hook could not stop it mid-flight. Now, while that permission prompt is waiting, Claude Code races the tool call against the hook's own decision. If the hook finishes first with an outcome, the tool call is aborted and the hook's decision, including any interrupt, is used instead, with a log message noting which tool and hook caused the interrupt.

**Why**

This lets hooks reliably cancel a tool call that's sitting at a permission prompt, rather than only being able to act before or after that point.

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

### Security-default hooks module opt-out changed from a boolean to a prependPlugins allowlist

Org opt-out for the built-in security-default hooks now uses a prependPlugins allowlist instead of a simple on/off setting

**What**

The built-in `sec-default` hooks module, which seats classic hooks and policy protections ahead of any plugin a user installs, used to be turned off with a simple `secDefault: false` setting in managed settings. Now, whether it is active depends on the organization's managed `prependPlugins` list: it stays active unless the organization explicitly lists `sec-default@builtin` there, and that same list is what an organization now uses to opt back in or out.

**Why**

This gives organizations more explicit control over the order in which security-related hooks and plugins are seated, replacing a single boolean with an allowlist that can name `sec-default@builtin` directly.

- Area: Plugins
- Names: `prependPlugins`, `sec-default@builtin`
- Tier: Use it now
- Useful: 3/5
- Signal: 3/5

### New bridge dialog for tools that would read outside the allow-list ('block outside reads')

A new confirmation dialog appears when a tool tries to read a file outside the allowed list

**Unclear.** Whether this dialog is active for any given account depends on the tengu_compressed_river gate, which is unread for this account, so nothing can be said about whether it is switched on.

**What**

When a tool tries to read a file path that falls outside your allowed-reads list, Claude Code can now show a dedicated dialog offering to allow it, block it, or ask again later, instead of just denying it outright. The permission system now carries a flag, `offersBlockOutsideReads`, that decides whether this new dialog appears, and denying through it records that the read was blocked for being outside the allow-list.

**Why**

This gives you a clearer, more specific choice when a tool asks to read something outside the paths you've allowed, rather than a generic denial.

- Flag `tengu_compressed_river`: Not enough to say (read for one account on one subscription tier against v2.1.268; this account: no value returned, anonymous baseline: no value returned, compiled default: on)
- Area: Permissions
- Names: `offersBlockOutsideReads`
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### New server-controlled telemetry hold: dropUnwatchedStreamEvents / servedPolicyHolds

Telemetry can now silently drop unwatched stream events under a new server-controlled policy hold, instead of buffering them

**What**

Claude Code's client-controlled reporting (CCR) system, which manages how usage telemetry is buffered and sent, now has a second way to "hold" events besides the existing no-subscriber hold. A new policy-driven path checks server-supplied settings (`flushPolicy.maxEvents` above 1, plus `eventHoldEnabled`) and, when a setting called `dropUnwatchedStreamEvents` is turned on, causes `stream_event` telemetry to be dropped immediately and counted rather than buffered for later delivery. It defaults to off. A new warning log, `cli_ccr_event_hold_undelivered_at_close`, fires if a policy-held batch still has undelivered events when the session ends.

**Why**

This gives the server more control over telemetry volume, letting it choose to discard certain stream events outright instead of accumulating them in memory when nothing is actively consuming them. The new warning helps catch cases where events meant to be held for later delivery never actually got delivered before the session closed.

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

### Telemetry uploads can now be held back under a server-served flush policy

Telemetry uploads can now be delayed by a server-configured flush policy instead of sending right away

**What**

Claude Code can now hold back some internal telemetry (usage/diagnostic data it sends) instead of uploading it immediately, under a new "served policy" mode configured remotely. That policy can set limits like maximum age, maximum size, or maximum event count before a flush is forced, list certain event types that must always flush right away, and force a flush when the assistant finishes responding or when sampling ends.

A new check decides, row by row, whether a given transcript entry (like a plain assistant or user turn) is allowed to wait. Entries that carry tool results, or that are meta/virtual/compact-summary rows, are always sent immediately regardless of the policy.

**Why**

This lets telemetry be batched more efficiently under server control instead of always uploading immediately, while making sure important events (tool results, summaries) are never delayed.

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

### `claude rm` gains a `--force-remove-worktree` flag and rich refusal messages

`claude rm` gets a `--force-remove-worktree` flag and much more detailed refusal messages

**What**

The `claude rm` command, which removes a background session and its worktree (the checked-out copy of your code used for that session), now accepts a `--force-remove-worktree <worktree-id>` flag alongside the existing `--discard-unpushed <commit>@<worktree-id>` flag. Use `--force-remove-worktree` to force-delete a worktree directory that git or the `WorktreeRemove` hook couldn't remove on its own.

Claude Code also now generates much more specific messages explaining exactly why a removal was refused, covering cases such as: dirty working state, unpushed commits (including when they're shared), the worktree being in use or locked, an occupied path, an unreadable or changed shared record, an unverified worktree, and various sub-reasons when the removal itself fails (tracked changes, not registered, nested repositories, and more). Both new flags are fully parsed and are printed back to you in the retry command suggested after a refusal.

**Why**

This makes it much clearer why `claude rm` refused to delete a session's worktree, and gives you a direct way to force through a removal that's stuck because a directory couldn't be cleaned up automatically.

- Area: Sessions
- Names: `claude rm`
- Tier: Use it now
- Useful: 4/5
- Signal: 2/5

### New optional `icon` parameter for artifacts, distinct from the emoji `favicon`

Artifacts can now be given a plain icon label, separate from the emoji favicon

**What**

When publishing an artifact (a shareable page or output Claude creates), you can now set an `icon` field, a short generic word like "chart" or "calendar" that signals the type of page it is. This is separate from the existing emoji-based favicon, persists across redeploys the same way the favicon does, but is explicitly ignored for artifacts that were created from an Artifact type.

**Why**

This gives artifact pages a simple, consistent way to signal their page type beyond a single emoji, useful for categorizing or displaying different kinds of published pages.

- Area: Artifacts
- Names: `icon`
- Tier: Use it now
- Useful: 4/5
- Signal: 2/5

### Browser file_upload tool gains a direct base64 upload path

Browser file_upload tool can now accept file contents directly instead of only file paths

**What**

The browser automation `file_upload` tool now accepts an optional `files` array containing base64-encoded file data, a name, and a MIME type, in addition to its existing `paths` option. The `files` field is described as meant to be populated by the client itself after it reads the files under its own file-read permissions, not set directly by the model. A reference (`ref`) and tab ID (`tabId`) are still required, but `paths` is no longer required on its own.

**Why**

This gives the browser tool a way to upload file contents directly when the client has already read them, rather than always relying on a file path that must be resolved separately.

- Area: Chrome & Browser
- Names: `file_upload`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### Fleet view: worktree deletion can now be force-removed with a follow-up confirmation

Fleet view can now force-delete a worktree directory git no longer recognizes, with a confirmation step

**What**

When deleting a job in the fleet view (Claude Code's view of multiple parallel sessions), there's now a second confirm-and-retry option alongside the existing 'discard unpushed changes' offer: force-removing a worktree directory that git no longer recognizes. After it runs, Claude Code reports whether the associated branch was preserved.

**Why**

This gives you a way to clean up a worktree that git has lost track of, rather than being stuck with a directory that can't be deleted through the normal path, while confirming first and telling you what happened to the branch.

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

### Fork seed size cap and stale-mtime housekeeping

Fork snapshot files get a hard size cap and a background-wait timer becomes configurable

**What**

The snapshot files written when forking a conversation (see the new `fork_conversation` tool) now have a fixed maximum size, and writing one that exceeds it now fails with a dedicated error instead of succeeding silently. A separate internal helper keeps a snapshot file's modification time fresh, and a new environment variable, `CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS`, controls a related ceiling on how long a background wait can run.

**Why**

The size cap prevents oversized conversation forks from being written unbounded, and the new environment variable gives more control over background-wait timing in headless or scripted use.

- Area: Sessions
- Names: `CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### Gateway can push admin-configured modelPricing overrides down to managed-policy clients

Claude Code's gateway can now push admin-set model pricing overrides down to managed clients

**What**

The self-hosted Claude Code Gateway can now build a `modelPricing` object per deployment, a price multiplier plus per-model overrides, from an admin pricing configuration, and push it into each managed policy's CLI settings, but only for policies that don't already define their own `modelPricing`. The gateway logs how many policies received the pushed pricing.

**Why**

This lets an organization set contracted pricing centrally in the gateway and have it apply automatically to managed clients, rather than requiring every client policy to set `modelPricing` itself, so usage reports reflect your organization's contracted rates instead of list price.

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

### Hook-injected transcript entries can now be placed at head or tail, not just prepended

Hooks can now insert transcript entries at the tail as well as the head

**What**

When a hook (custom code that runs at certain points in Claude Code) injects new entries into the transcript, those entries could previously only be prepended to the start. Now the hook can specify a `placement` of either "head" (the old prepend behavior) or the new "tail," which appends the entries at the end instead and can extend the tracked length of restored transcript.

**Why**

This gives hook authors control over whether their injected content appears before or after existing transcript entries, useful for hooks that want to append rather than prepend information.

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

### New 'required' plugin installation preference can force a plugin to stay enabled

Plugins can now be marked 'required' so they stay enabled regardless of user or admin settings

**Unclear.** Which specific marketplace this applies to is not stated.

**What**

Plugins can now carry an `installationPreference` value of "required," coming from the plugin's manifest or marketplace metadata. When a plugin is marked required and belongs to a specific marketplace, Claude Code now forces it to be treated as enabled, overriding both a user's attempt to disable it and an organization's managed-settings disable rule. This applies when checking for load-failure errors, when computing whether a plugin is enabled, and when checking if managed settings have disabled a plugin.

**Why**

This lets a marketplace mark certain plugins as mandatory so they can't be turned off by users or by admin configuration, useful for plugins an organization considers essential.

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

### New "browser" tool_kind added to the permission-request schema for SDK hosts

Permission requests gain a "browser" tool_kind so SDK hosts can route browser tools to a dedicated UI

**What**

The tool-use permission request format used by SDK-based hosts gained an optional `tool_kind` field, currently supporting the value `"browser"`. This lets hosts like Claude in Chrome, Cowork, Claude Desktop, or Remote Devices recognize browser-related tools and show a specialized permission prompt for them, without having to guess based on the tool's name.

**Why**

This gives SDK hosts a reliable way to detect browser tools and present a purpose-built permission UI, instead of relying on fragile name matching.

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

### New managed-settings key gatewayInternalNetworks joins highest-source-wins auth pins

New managed setting gatewayInternalNetworks joins the group taken only from the top-priority settings source

**Unclear.** The finding does not say what `gatewayInternalNetworks` actually controls on the login screen beyond being passed into its props.

**What**

A new managed-settings key, `gatewayInternalNetworks`, has been added to the group of settings that Claude Code takes only from the highest-priority settings source, joining `forceLoginOrgUUID`, `forceLoginMethod`, and `forceLoginGatewayUrl` (which [pin logins to an organization, restrict login method, and set the gateway login URL](/docs/en/authentication#restrict-login-to-your-organization)). It is now also passed into the props used by the OAuth/gateway login screen.

**Why**

Treating `gatewayInternalNetworks` the same way as the other login-restriction settings means a lower-priority settings source (like a user's local config) can't override it, keeping this control firmly under organizational management.

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

### New num_turns-adjacent 'seq' field documented for stream-json results

Stream-json results from claude -p now document a 'seq' delivery-order field

**What**

Results returned in stream-json format (used with `claude -p`) now have a documented `seq` field, a delivery sequence number counting how many results the run has numbered before this one, starting at 0. It counts in the order results are written, not the order they were produced, and it still increments even if a particular write fails, so a gap in the sequence means a result was lost. This field is absent from the in-process engine surface and from error results built locally by cloud-relay clients.

**Why**

This gives consumers of stream-json output a way to detect whether any results were dropped in transit, by watching for gaps in the sequence numbers.

- Area: Stream JSON
- Names: `seq`, `claude -p`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### New session-config field: questionOptionDescriptionsOptional

New session-config field lets question options skip descriptions

**Unclear.** What uses this field or what behavior it actually toggles is not stated.

**What**

The session configuration accessor gained a new field, `questionOptionDescriptionsOptional`, with its own getter (`questionOptionDescriptionsOptional()`) and setter (`replaceQuestionOptionDescriptionsOptional()`). It arrives alongside two other new fields in this same area, `extendedQuestionsEnabled` and `disableFileMentions`.

**Why**

The finding doesn't say what consumes this field, but its name suggests it controls whether descriptions are required or optional for question options in a session.

- Area: AskUserQuestion
- Names: `questionOptionDescriptionsOptional`, `extendedQuestionsEnabled`, `disableFileMentions`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### New stream-json result_index field, live for -p/headless output

Streamed JSON output now includes a result_index showing delivery order

**What**

When running Claude Code in headless or `-p` (print) mode with streamed JSON output, both successful and error result objects can now include a `result_index` field. This field is actually populated, counting up for each result delivered during a run.

**Why**

This gives tools consuming streamed JSON output a reliable way to know the order in which results were delivered.

- Area: Stream JSON
- Names: `result_index`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### OTEL trace exporter can cap batch size

OTEL trace export can now cap how many spans are sent per batch

**What**

When setting up OpenTelemetry (OTEL) trace export, Claude Code can now optionally pass a maximum export batch size to each batch span processor, limiting how many spans are sent together in one export.

**Why**

This gives control over batch export sizing for telemetry, which can help manage the size and frequency of trace export requests.

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

### Plugin enable/disable results now carry a machine-readable failureCode

Plugin enable/disable failures now return a machine-readable failureCode alongside the human-readable error message

**What**

When enabling or disabling a plugin fails (through `/plugin` or the command line), Claude Code now returns a specific `failureCode` in addition to the existing text message. Codes include:

- `not_installed_at_scope`

- `settings_write_failed`

- `already_in_goal_state`

- `required_by_dependents`

- `dependency_missing`

- `dependency_disabled`

- `dependency_policy_blocked`

- `plugin_policy_blocked`

- `ambiguous_marketplace`

- `managed_name_locked`

- `required_by_organization`

The same pattern extends to plugin install failures (with codes like `builtin`, `directory_loaded`, `marketplace_policy_blocked`, `not_found`, `settings_write_failed`, `dependency_resolution_failed`, `plugin_policy_blocked`, `dependency_policy_blocked`, `dependency_version_conflict`) and to plugin uninstall/disable-all failures (`builtin`, `directory_loaded`, `not_installed`, `enabled_at_project_scope`, `not_installed_at_scope`, `partial_failure`).

**Why**

A structured failure code lets tools and scripts that call into `/plugin` react programmatically to specific failure reasons instead of parsing free-text error messages.

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

### S3 tool gains explicit deny-by-default policy fields for AWS streaming auth schemes

S3 tool now has separate deny-by-default policy switches for streaming, presigned, and SigV4A auth requests

**What**

The S3 tool's schema now includes three separate policy fields: `streaming`, `presigned`, and `sigv4a`. Each controls whether the tool is allowed to re-sign a particular kind of AWS request:

- `streaming` — aws-chunked streaming uploads

- `presigned` — presigned URLs

- `sigv4a` — SigV4A asymmetric-signed requests

All three default to "deny".

**Why**

By defaulting each of these authentication schemes to denied, the S3 tool won't silently re-sign sensitive or unusual AWS request types unless explicitly permitted, reducing the risk of unintended credential use.

- Area: S3 Tool
- Names: `streaming`, `presigned`, `sigv4a`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### SDK turn result schema gains resume_reason and result_index fields

SDK turn results can now report a resume_reason and a result_index

**What**

When using the Claude Code SDK (the programmatic, headless interface some tools build on), the schema for a turn's result now carries two new optional fields:

- `resume_reason`: a text explanation for why a turn was automatically re-run after the background worker running it restarted. This ties into the `CLAUDE_CODE_RESUME_INTERRUPTED_TURN` and `CLAUDE_CODE_RESUME_REASON` environment variables.

- `result_index`: a number identifying the result's position.

Both fields appear in the streamed result messages as well as the final result message.

**Why**

This gives SDK integrations visibility into when a turn's result came from an automatic restart-recovery rerun rather than a normal completion, and lets them order or dedupe results using `result_index`.

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

### SDK/print-mode result event gains a local_command field

The SDK/print-mode final result event can now include a local_command field

**Unclear.** What triggers the condition for including local_command, and what value it carries, is not specified in the evidence.

**What**

When a query run through the SDK or in print mode finishes, the final 'success' result event can now optionally include a `local_command` field, built from an internal helper, alongside the fields it already carried.

**Why**

This gives callers of the SDK or print-mode output more information about what happened at the end of a query in cases where a local command is involved.

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

### Skills sync can skip a full sync round on startup if recently synced

Claude Code can skip a full skills sync on startup if one finished recently

**What**

On startup, Claude Code checks whether skills (packaged instructions for specific tasks) were already synced within a configurable time window, set by `CLAUDE_CODE_SYNC_REUSE_WITHIN_MS`. If so, and nothing has blocked the sync, it skips the full sync round and logs `skills_sync_round_reused` instead. This does not apply when running in cloud/XD mode.

**Why**

Avoiding a redundant sync on every startup should make launching Claude Code faster when skills were already synced a moment ago.

- Area: Skills
- Names: `CLAUDE_CODE_SYNC_REUSE_WITHIN_MS`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### WebFetch requests now enforce a deadline/timeout

WebFetch requests now enforce a timeout and fail with a clear deadline error if exceeded

**What**

WebFetch requests now have a deadline enforced on them. The deadline comes from the `CLAUDE_CODE_WEBFETCH_DEADLINE_MS` environment variable if it's set, otherwise from a remote configuration value, capped at a maximum. If a fetch doesn't complete within that time, it's aborted and fails with a "Fetch did not complete within the deadline" error.

**Why**

This prevents a WebFetch call from hanging indefinitely, giving a clear, specific error when a fetch takes too long instead of leaving it to stall.

- Area: WebFetch
- Names: `CLAUDE_CODE_WEBFETCH_DEADLINE_MS`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### CLAUDE_CODE_QUESTION_EXTENDED gains an alias/companion env var

A new env var CLAUDE_CODE_QUESTION_OPTIONAL_DESCRIPTIONS also turns on extended AskUserQuestion mode

**What**

The extended mode for the `AskUserQuestion` tool (a preview feature that lets Claude ask you multiple-choice style questions) can now be turned on by either of two environment variables: the existing `CLAUDE_CODE_QUESTION_EXTENDED`, or a new `CLAUDE_CODE_QUESTION_OPTIONAL_DESCRIPTIONS`. Setting either one enables the same behavior.

**Why**

This gives another name to set if you're enabling extended questions through configuration that already uses the word "descriptions," without changing what the feature does.

- Area: AskUserQuestion
- Names: `CLAUDE_CODE_QUESTION_OPTIONAL_DESCRIPTIONS`, `CLAUDE_CODE_QUESTION_EXTENDED`
- Tier: Use it now
- Useful: 2/5
- Signal: 2/5

### Todo/task tool availability no longer conditioned on a remote feature flag

Todo/task tool availability no longer falls back to a remote feature flag; it's decided locally

**What**

The check that decides whether the todo/task tracking tools are available dropped a remote feature-flag lookup and an associated fallback branch it previously relied on. Now availability is decided purely by local conditions: it's enabled if certain internal checks pass, if the model's capability string is missing or matches specific known patterns, or if the environment variable `CLAUDE_CODE_ENABLE_TODO_TOOLS` is explicitly set to true, with no separate remote feature-flag fallback anymore.

**Why**

This makes todo/task tool availability depend only on local, inspectable conditions (the model in use and the `CLAUDE_CODE_ENABLE_TODO_TOOLS` environment variable) rather than a remote flag fetched from Anthropic's servers.

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

## New Features

### REPL bridge (Remote Control) connection status now shown in the header

The CLI header now shows the connection status of the Remote Control bridge, when your terminal is wide enough

**What**

The header now shows a small status indicator for the REPL bridge, the connection Claude Code uses for Remote Control. It reflects whether the bridge is connected, reconnecting, in an error state, or has a session active. It only appears when the terminal window is at least 60 columns wide, and it does not show when Remote Control is running in outbound-only mode.

**Why**

This gives an at-a-glance signal of whether Remote Control is actually connected, instead of leaving that state invisible until something goes wrong.

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

## Improvements

### Stale model-access denials are now automatically re-probed and can self-heal

Claude Code now re-checks previously denied models with the server instead of caching the denial forever

**What**

Claude Code keeps a record of models the server has denied access to (`confirmedEntitlementDenies`). Now, before reporting one of those denials again, it re-checks with the server first. If your account or organization has changed, or the denial no longer applies, Claude Code updates its cache and removes the model from the deny list, so it becomes available again through `/model` or at startup without needing to restart Claude Code.

**Why**

Previously a denied model could stay marked as unavailable even after the underlying reason was resolved, requiring a restart to notice the change. Now access to a model can recover on its own as soon as the server confirms it.

- Area: Model Access
- Names: `/model`
- Tier: You'll notice
- Useful: 3/5
- Signal: 3/5

### New Cowork artifact permission-card tracking and stricter file-read denials

Cowork sessions now show permission cards for artifact actions and block reading files outside connected folders since no one is there to approve

**What**

New machinery renders human-readable permission cards for actions on artifacts, such as uploading, copying, or editing, derived from the reasoning behind a tool's decision. Alongside this, two new checks deny requests to read a local file from outside a Cowork session's connected folders, through a link, or when the file simply can't be read.

**Why**

In a Cowork session there's no human present to approve an unusual file-access request, so these reads are now refused outright rather than left waiting on an approval that can never come.

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

### Gateway device-code login can verify the connection stays inside a declared internal network

Gateway sign-in can now show that both ends of the connection stay inside a trusted internal network

**What**

When you sign in through the gateway using the device-code login flow (the screen that asks you to enter a code shown on another device), Claude Code can now check the connection against a list of declared internal networks before it contacts the identity provider. If the gateway's address matches one of those networks, the trust prompt you see now spells out the path the connection took, for example "Connecting from to , both inside declared ".

**Why**

This gives you more concrete evidence when deciding whether to trust a gateway login prompt, instead of just a bare request to approve the connection.

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

### read_db can now skip approval entirely for a recognized trusted source

read_db can now skip the approval prompt entirely for recognized trusted sources

**Unclear.** The finding doesn't say what qualifies a source as pre-trusted or how that determination is made.

**What**

The `read_db` permission check can now allow a request through with no approval prompt at all when a new internal check recognizes the artifact as coming from a pre-trusted, known source. In that case it shows the message "Reading the database of ... needs no approval."

**Why**

This reduces prompt friction for database reads from sources Claude Code already recognizes as trustworthy, while presumably still prompting for anything it doesn't recognize.

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

### Claude Code Projects system prompt extended to shared/multi-member projects

Claude Code Projects now describes shared, multi-member projects to the agent, not just single-owner ones

**What**

Claude Code Projects let a Claude Code agent follow a shared timeline of messages. The built-in instructions describing how those timeline messages reach the agent now also cover projects with multiple members, rather than assuming a single project owner. When relaying a timeline message, the generated marker now states whether the message's author was the project owner or a regular member, including that person's account id.

**Why**

This lets the agent correctly attribute messages in shared projects with several people posting to the same timeline, rather than treating every message as if it came from a lone owner.

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

### CLAUDE_CODE_REMOTE auto-trusts built-in Slack/Teams bot MCP endpoints

Under CLAUDE_CODE_REMOTE, built-in Slack/Teams bot MCP servers now bypass the allowedMcpServers allowlist

**What**

When Claude Code runs under `CLAUDE_CODE_REMOTE`, connections to known built-in Slack and Teams bot endpoints (internally: `slackbot`, `slackbot_read`, `ccr-slack-thread`, `teamsbot`) are now automatically marked as trusted, injected connections. These marked connections skip the `allowedMcpServers` allowlist check entirely, where `allowedMcpServers` is the setting that normally restricts which MCP servers (external tool providers Claude Code can connect to) users are permitted to add.

**Why**

This means the Slack and Teams bot integrations used for Claude-Code-Remote sessions keep working even on accounts whose `allowedMcpServers` policy would otherwise block them, since they're treated as part of the built-in remote session infrastructure rather than a user-added server.

- Area: MCP
- Names: `CLAUDE_CODE_REMOTE`, `allowedMcpServers`
- Tier: You'll notice
- Useful: 3/5
- Signal: 3/5

### Per-command network allowlists now enforced against actual sandbox confinement

Commands approved with domain restrictions are now refused outright if they would run unconfined by a sandbox

**What**

When a shell command is approved with an `allowed_domains` network restriction, Claude Code now checks whether it would actually run inside a sandbox that can enforce that restriction. If it would run outside a confining sandbox, the command is refused with a message explaining it wasn't run and needs to be re-run, rather than silently executing without the network restriction in place. When a command does run sandboxed, its network allow/deny lists are now registered with the sandbox manager for the life of the process and removed when it exits or errors.

**Why**

This closes a gap where a command approved under the assumption that its network access was restricted could otherwise run with unrestricted network access if the sandbox wasn't actually confining it.

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

### Default safe git-push allowlist now covers configured remotes, not just "origin"

Auto-approved git push rules now cover your configured push remote, not just "origin"

**What**

The default list of `git push` commands Claude Code will run without asking permission is now built by checking your actual git remotes: it keeps `origin` if present, and adds `remote.pushDefault` if it names a single valid remote. It then expands this into allow-list entries for `git push <remote> *` and `git push -u <remote> *`, plus a certified form, for every default allow-list used across the app.

**Why**

Repositories that push to a remote other than `origin` (such as `upstream` or a fork remote) will no longer trigger unnecessary permission prompts for ordinary pushes to their normal configured remote.

- Area: Git Permissions
- Names: `remote.pushDefault`
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### Artifact publish gains an icon field and generalized upstream-rejected-field retry

Artifact publishing now supports an icon field and retries automatically when the server rejects an unknown field

**What**

Publishing an artifact (a shareable output produced by the Artifact tool) now accepts an `icon` field alongside the existing `favicon`, `label`, and other fields. If the publish server rejects the request because it doesn't recognize the `icon` or `deadline` field, Claude Code now automatically strips just that field and retries, instead of failing the whole publish. This retry logic used to only handle a rejected `deadline` field; it's now generalized to handle either field.

Separately, the success response after deploying an artifact now also reports which paths were "reseeded," alongside the existing list of paths that went live.

**Why**

This makes artifact publishing more resilient to server-side changes: if the publish endpoint doesn't yet support a field the client sends, the request still goes through instead of erroring out.

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

### New "verification_required" API error surfaced to users with a dedicated message

A new 'verification_required' server error now shows its own specific message instead of a generic one

**Unclear.** Whether this appears to users depends on server-side gates (`tengu_ranch_rc_shown`, `tengu_ranch_rc_link_shown`) that have not been read for this release.

**What**

When the Claude API returns a specific type of 403 error indicating verification is required, Claude Code now recognizes it and shows the server-provided message directly, rather than treating it as a generic failure.

**Why**

Users who hit this condition now see a message that actually explains what's wrong instead of an unhelpful generic error.

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

### Plugins required by organization policy can no longer be disabled

Plugins marked required by organization policy can no longer be disabled from Claude Code

**What**

If an organization's marketplace or installation policy marks a plugin as required, Claude Code now blocks attempts to disable it (or its synced counterpart), showing the message: "Plugin "..." is required by your organization and can't be disabled here. Contact your admin to change it." with `failureCode: "required_by_organization"`. A related check also blocks disabling a plugin that other required plugins depend on, unless `bypassDependentsBlock` is passed.

**Why**

This stops users from accidentally turning off plugins their organization has mandated, keeping enforcement consistent with admin policy.

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

### Gateway warns once when a client connects from a non-private IP with no allowlist configured

Self-hosted gateway now warns once if a client connects from a public IP with no allowlist set

**What**

The self-hosted Claude Code gateway now checks incoming client connections against an expanded list of private IP address ranges, adding the `169.254.0.0/16` and `fe80::/10` link-local ranges. If `access_control.allow_cidrs` (the setting that restricts which addresses may connect) is not configured, and a request comes from an address outside the private ranges, the gateway prints a one-time warning that it may be reachable from the public internet.

**Why**

Because the gateway can push settings that run commands on developer machines, an unnoticed public exposure would be a serious risk; this warning flags the situation so an administrator can lock it down with `allow_cidrs`.

- Area: Gateway
- Names: `access_control.allow_cidrs`
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### Settings env vars now validated: invalid names/values/NUL bytes are dropped with a warning

Invalid environment variable names or values in settings.json are now dropped with a warning instead of silently used

**What**

Environment variables defined in an `env` block inside `settings.json` now go through a validation step before Claude Code applies them. Entries are stripped out, with a one-time warning logged per settings scope, if:

- the key isn't a valid environment-variable name

- the value isn't a string, number, or boolean

- the value contains a NUL character

**Why**

This catches malformed or invalid `env` entries in settings files early, rather than letting them silently fail or produce confusing behavior later.

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

### New deny path for read_db writes outside working folders with no live approver

Database reads that would write outside the working folder are now denied when no one can approve them

**What**

The artifacts database's `read_db` permission check now includes a hard denial: if a `read_db` call would save documents outside the session's working folders, and there's no person present in that session to approve the request, it is now blocked outright with a dedicated explanation rather than left pending or silently allowed.

**Why**

This closes a gap where a database read that writes files outside the expected working area had no way to get approved in an unattended session, so it's now refused instead of proceeding without consent.

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

### Permission prompts can now display the network allow-list of hosts

Permission prompts can now show the list of network-allowed hosts for a pending command

**What**

The permission-request panel, the dialog Claude Code shows before running a command or tool that needs approval, can now display a list of hosts that are allowed for network access, drawn from `networkAllowHosts`. This appears alongside the existing sandbox and tool-type information. Behind this, the code that builds the permission dialog's details gained a `networkAllowListHonoured` field; when true, the dialog includes the `networkAllowHosts` list derived from the tool's own allow list.

**Why**

This gives users visibility into exactly which network hosts a pending command or tool would be allowed to reach, rather than leaving network access unstated in the approval prompt.

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

### Resuming an in-process teammate now checks folder trust before restoring its custom agent definition

Resuming a background teammate now requires folder trust before restoring its custom agent setup

**What**

When resuming an in-process teammate (a background agent running as part of a multi-agent team), Claude Code now checks whether the folder that its custom agent definition came from is trusted. If it isn't, the custom definition is no longer restored: the teammate falls back to only the team-essential tools and no custom instructions, and an error is logged (`agent_type_untrusted`) explaining that the user needs to run Claude Code in that folder and accept the trust dialog.

**Why**

This prevents a custom agent definition from an untrusted folder from being silently restored with its full instructions and tools when a teammate is resumed.

- Area: Trust & Teams
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### Permission-ask dialogs can now render a structured 'card' (safety-check explanation)

Permission prompts can now show a structured 'card' explaining a safety-check block, sourced from the tool itself

**What**

When Claude Code asks for permission to use a tool, the dialog can now include an optional structured "card" - a question, lines of detail, and values - that explains the reason behind a decision. This appears specifically when the reason is a safety check (or another explanatory type), there's no specific rule that already matched, and no denial-limit fallback applies. The content of the card comes from the tool's own `permissionCard` callback, meaning individual tools can supply their own explanation.

**Why**

This gives users a clearer, more specific explanation when a tool use is blocked or flagged for a safety reason, instead of just a generic permission prompt, making it easier to understand why Claude Code is asking or refusing.

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

### Per-command sandbox network allowlist can now be looked up and shown separately from the global allowlist

Sandbox commands can now get extra network access from a per-command rule, shown separately in the UI

**What**

Claude Code's sandbox (the restricted environment commands run in) can now grant network access to a specific command through a new per-command allowlist, checked after the existing global allowlist and configuration rules fail. When this applies, a new line in the UI reads "Also lets this command reach, beyond the sandbox allowlist: ...", listing the extra hosts (truncated after 160 characters, with a "+N more" count for long lists).

**Why**

This lets a single command reach specific extra network domains it needs, without having to widen the sandbox's overall network allowlist for everything else.

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

### Command permission prompt now shows the allowed network hosts

Permission prompt for running a command now displays which network hosts it's allowed to reach

**What**

When Claude Code asks for permission to run a bash command, the permission dialog now also shows the network hosts that the command is allowed to access, alongside the description of the command itself.

**Why**

This gives you visibility into what network access a command would have before you approve it, rather than only seeing the command text.

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

### New billing state: organization verification required

New billing block state: "organization verification required" can now stop a session with its own message and error code

**What**

Claude Code now recognizes a new reason a session can be blocked: `verification_required`, alongside the existing auth, billing, and context-limit reasons. It shows the label "organization verification required" and carries the error code `cleared_verification_required`, with matching handling added to the logic that classifies why an operation was blocked, the code that handles API errors, and the screen shown when a session is blocked.

**Why**

If your organization needs to complete some verification step, Claude Code can now show a specific, accurate message for that situation instead of a generic or mismatched error.

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

### Teleport-to-cloud now precomputes a GitHub access check before handoff

Teleporting a session to the cloud now checks GitHub access ahead of time and can fail earlier

**Unclear.** Whether this precheck runs for any given account depends on the tengu_teleport_github_access_precheck gate, which is unread for this account, so nothing can be said about whether it is switched on.

**What**

Before moving a session to the cloud ('teleport'), Claude Code now looks up the project's git remote, and if it points to GitHub, kicks off a check in the background to confirm access to that repository. If that check finds GitHub isn't connected, or the repository can't be found, the teleport is stopped immediately with a specific message instead of failing later once it reaches the server.

**Why**

Catching a missing GitHub connection or an inaccessible repository up front means you find out sooner, rather than after the teleport has already started and failed on the server side.

- Flag `tengu_teleport_github_access_precheck`: Not enough to say (read for one account on one subscription tier against v2.1.268; this account: no value returned, anonymous baseline: no value returned, compiled default: on)
- Area: Teleport
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### Cloud session bootstrap (teleportToRemote) gets branch-divergence-aware source selection and a 'not connected to GitHub' error path

Starting a cloud session now handles diverged branches and unlinked GitHub accounts with clearer errors

**What**

When starting a remote/cloud session (teleporting work to a remote environment), Claude Code now checks whether the branch you asked for is actually reachable on the detected remote. If your local branch 'shares no history' with the remote as last fetched, it can fall back to starting from a different commit or branch instead of failing outright.

Separately, the preflight checks before starting a cloud session now distinguish the case where your GitHub account isn't linked to Claude Code at all. In that case you get a dedicated error message telling you to connect your GitHub account, instead of the generic message that previously implied the GitHub app just wasn't installed.

**Why**

This produces clearer, more accurate errors when starting a cloud session fails: distinguishing 'your local branch has diverged too far from the remote' from 'your GitHub account isn't connected' should make it easier to know what to actually fix.

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

### Governed-git push URLs restricted to github.com

Governed-git push URLs are now only generated for GitHub repositories

**What**

When Claude Code sets up a governed git mount (a controlled way for the sandbox or runner to push to a repository), it now only computes a special push URL for repositories hosted on github.com. For repositories on other hosts, it logs a notice and leaves that source's existing push path unchanged. A new `directUpstreams` check also flags repositories whose owner/repo combination isn't on an allowed list of direct upstreams.

**Why**

This limits the governed push mechanism to GitHub specifically, avoiding unintended behavior for other git hosting providers, and adds a guardrail restricting which repositories can be pushed to directly.

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

### Org-required plugins can no longer be disabled/uninstalled, with new structured failure codes

Plugins your organization requires can no longer be disabled or uninstalled, and failures now report a specific reason code

**What**

Uninstalling a plugin or disabling all plugins now first checks which plugins are marked as required by the organization (based on the marketplace's `installationPreference` setting) and refuses to touch those. When disabling all plugins, the resulting message now includes a count of how many required plugins were skipped, with a note to contact your admin to change it.

Uninstall and disable failures also now carry a specific `failureCode`, such as `builtin`, `not_installed`, `enabled_at_project_scope`, or `partial_failure`, instead of just a plain message.

**Why**

This stops users from accidentally disabling or removing plugins their organization has mandated, and the structured failure codes make it easier to tell exactly why a given plugin operation failed rather than just seeing a generic error.

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

### Permission-rule path prefixes now resolve symlinks to a canonical "physical twin" form

Permission rules on symlinked paths now also apply to the real, resolved path they point to

**What**

When a permission rule is written against a file path that turns out to be a symlink, Claude Code now also resolves that path to its real, canonical location on disk, and adds an equivalent rule for that resolved "physical twin" path. This applies to deny rules during permission-rule compilation.

**Why**

Without this, a deny rule written against a symlinked path could be bypassed simply by accessing the same file through its real, resolved path instead of the symlink. Now both paths are covered by the same rule.

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

### New user-facing message for cloning a repo in the cloud without GitHub connected

New message explains how to connect GitHub when a cloud session needs to clone a repo

**What**

When a cloud or remote session needs to clone a repository but no GitHub account is linked to your Claude account, Claude Code now shows a dedicated message explaining this and pointing you to the fix: `/web-setup` if your local CLI already has a GitHub login, or the web `connect-github` page otherwise.

**Why**

This gives a clearer, more direct path to resolving a missing GitHub connection when a cloud operation like cloning a repository needs one, rather than a generic failure.

- Area: Cloud Sessions
- Names: `/web-setup`
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### Artifact auto-react now recognizes when the page itself owns comment threads

Artifact comment auto-reactions now back off when the artifact's own page manages its comment threads

**What**

When an artifact's page manages and displays its own comment threads (reported as `pageOwnsThreads`), the automatic comment-reaction logic now declines to act, logging it as a 'blocked' reason with a new telemetry event `page_owns_threads` (or `page_owns_threads_notice_suppressed` if the notice can't be shown), rather than treating it as an ordinary deactivation. In this situation the Artifact tool also refuses to post a reply or resolve a thread through the relay tool, since doing so would never actually show up on the page, and instead tells Claude to use whatever tool exists for posting to that page's own comment system.

**Why**

This avoids a confusing situation where Claude thinks it posted or resolved a comment through the relay tool, but the comment never appears because the artifact's page is managing its own comments independently.

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

### Gateway login now flags when it would go through a proxy for a declared-network host

Gateway login now blocks and warns when a declared-network host would route through an HTTP proxy

**What**

When `gatewayInternalNetworks` is configured and the gateway host Claude Code resolves falls inside one of those declared networks, login now checks whether the connection would go through an HTTP proxy. If it would, login refuses to proceed and tells the user to add the host to `NO_PROXY` (the environment variable that lists hosts to reach directly, bypassing any proxy).

**Why**

Routing a trusted internal gateway host through an external proxy could be a misconfiguration or a security risk, so this catches it at login time instead of letting the connection go through silently.

- Area: Gateway
- Names: `NO_PROXY`
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### MCP-over-HTTP tool exposure disables background tasks and unsandboxed commands

Listing tools from HTTP-based MCP servers now runs in a restricted context with background tasks and unsandboxed commands disabled

**What**

When Claude Code lists available tools from an MCP server that uses the 'http' transport, it now does so inside an isolated context that has background tasks and unsandboxed (unrestricted) command execution turned off. This restriction is skipped if those things are already disabled globally.

**Why**

This limits what an HTTP-based MCP server can trigger just by being asked to list its tools, reducing the risk that listing tools from a remote server could kick off background work or run commands outside the sandbox.

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

### Artifact tool: list_files/read_file now resolve and return a `type` object for type-locked files

Artifact file listing and reading now include the artifact's declared type when the file is type-locked

**What**

When the artifact tool's `list_files` and `read_file` actions handle a file that is "type-locked" (tied to a specific artifact type), Claude Code now looks up that type's metadata and includes it as a `type` field in the response, alongside the existing `from_type` flag. The `read` action also now records `type_named` in its internal telemetry when the artifact has a title.

**Why**

This gives Claude Code more context about what kind of artifact a file belongs to when listing or reading it, which can help produce more accurate handling of type-specific files.

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

### Self-hosted runner: governed git mount now requires a minimum git version, and gracefully degrades otherwise

Self-hosted runner now checks git's version before using governed git mount credentials, degrading gracefully if too old

**What**

When a self-hosted runner work item's repository is configured with `fetchViaMount`, Claude Code now checks the locally installed git version against a required minimum before routing git fetches through the mount's path-scoped credential. If git is too old, or the runner is running with `--capacity` greater than 1 (which shares git configuration across sessions), the mount-based routing is skipped and a warning is logged instead of the fetch silently failing.

**Why**

This avoids silent failures on older git installations or shared-capacity runner setups by falling back safely and telling you why the governed mount routing was skipped.

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

### Self-hosted runner sessions now reconcile governed-git config on every token refresh

Self-hosted runner sessions now re-sync governed-git config on every token refresh, warning if that fails

**What**

Self-hosted runner sessions now reconcile their governed-git configuration every time a session token is presented or refreshed: on initial token presentation, on background token refresh, and on scheduled inference-token refresh. If the session token can't be successfully re-presented to `/remote`, new telemetry events fire (`self_hosted_governed_push_url`/`represent_failed` and `self_hosted_governed_mount_read`/`represent_failed`) and a warning is logged that git traffic through the governed mount may be refused with a `git_token_mismatch` error until it succeeds.

**Why**

Keeping the governed-git configuration in sync with each fresh token reduces the chance that git operations through the governed mount fail unexpectedly due to a stale or mismatched token, and the new warning makes such failures easier to diagnose.

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

### Bash permission check gets a fallback deny check based on cd/read paths when full AST parsing fails

Bash permission checks get a fallback path-based deny check when full command parsing fails

**What**

When Claude Code can't fully parse the structure of a bash command to check permissions, it now runs a secondary check that scans the raw command text for `cd` directory changes and file reads, comparing any resulting paths against configured Read/Edit deny rules. This only runs when deny rules are actually configured. If this fallback check itself fails, the failure is logged as "semantics-path deny check failed" and Claude Code falls back to asking the user.

**Why**

This closes a gap where a command that couldn't be fully parsed might have bypassed deny rules entirely; now it gets a best-effort check instead of skipping straight to asking or allowing.

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

### Agent worktree deletion gains a force-remove path with nested-repo/tracked-change safety checks

Deleting an agent's worktree now checks for nested repos and tracked changes, with a new force-remove option

**What**

Removing a job's git worktree (the separate working copy an agent uses) is now more careful before deleting it:

- It detects nested git repositories inside the worktree.

- It detects tracked changes, not just uncommitted ones.

- It verifies the worktree is actually registered in git's own worktree list before removing it.

- It supports an explicit `forceRemoveWorktree` request to override these safety checks.

When removal is withheld, it now reports specific reasons: `tracked_changes`, `nested_repositories`, `nested_unverified`, or `not_registered`, along with a new `job_delete_force_remove` delete-kind and a `forceRemoveWithheld` field in the response.

**Why**

This prevents accidentally destroying work: nested repositories or tracked changes inside a worktree that's about to be deleted are now caught and reported instead of silently discarded, while still allowing a deliberate force-remove when you really want to delete anyway.

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

### write_db consent check also honors the new trusted-source signal

write_db's consent check now also recognizes the same trusted-source signal as read_db

**What**

The consent check for `write_db` now also treats an artifact as already consented-to if the same new trusted-source recognition used by `read_db` applies, in addition to the existing per-session consent flags it already checked.

**Why**

This keeps `write_db`'s approval behavior consistent with the new trusted-source shortcut added to `read_db`, so recognized trusted sources don't get treated differently between the two operations.

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

### Session teardown skips pushing outcome branches that are only reachable via the git mount

Session cleanup now skips pushing branches only reachable through the session's git mount

**What**

When a session ends and Claude Code tries to push outcome branches, it now checks whether each branch's source repository is only reachable through the session's git mount (the relay used for governed git pushes). If so, that branch's release-time push is now skipped, with a warning explaining that the repository is only reachable through the mount and the release push targets the plain upstream instead.

**Why**

This avoids a push either failing silently or going to the wrong destination when a repository can only be reached through the session's git mount rather than directly.

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

### Deploy retries generalized to drop any rejected field, not just 'deadline'

Deploy retry logic now strips any field the server rejects, not just a hardcoded 'deadline' field

**What**

The retry logic used when publishing or deploying used to handle one specific case: if the server rejected a 'deadline' field, it would strip that field and retry once. It now works generally, inspecting the server's response for whatever field name was rejected, removing it, and retrying, repeating this until nothing more is rejected. A parallel 'icon' flag was also added alongside 'deadline' in the internal retry-state tracking.

**Why**

This makes deploy retries more resilient to different kinds of field rejections from the server, instead of only handling the one case that had been hardcoded before.

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

### TUI renderer opt-out reason now submitted as feedback, not just hashed telemetry

Feedback typed when opting out of the new fullscreen terminal UI is now actually submitted, not just measured

**What**

When a user opts out of the new fullscreen (TUI) renderer and types a reason why, Claude Code now submits that reason as an actual feedback item, with a timeout and credentials attached, and records locally whether the submission succeeded. Only after that does it send a `tengu_tui_optout_reason` telemetry event, and that event now carries the reason's length (`reason_length`) and a `feedback_id` referencing the submitted feedback, rather than sending the reason text itself in telemetry.

**Why**

This means opt-out feedback actually reaches a feedback system where it can be reviewed, instead of only ever showing up as anonymized telemetry.

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

### New 'verification_required' error classification for API errors

API errors can now be classified specifically as 'verification_required'

**What**

Claude Code's classification of errors coming back from the Anthropic API now includes a distinct `verification_required` category. It is checked before the existing `repeated_529` check, and sits alongside other existing categories like `rate_limit`, `capacity_off_switch`, and `prompt_too_long`.

**Why**

Giving this kind of error its own category lets Claude Code (and its error handling and messaging) respond to a verification requirement differently than to rate limits or capacity issues, rather than lumping it in with other error types.

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

### Bridge session fetch now blocked for third-party providers

Bridge session fetches are now blocked outright for non-Anthropic providers

**What**

The internal `bridge_session_get` helper, used to fetch a session over the bridge, now checks upfront whether the active provider is Anthropic itself (first-party). If it isn't, the fetch is refused immediately, returning `session:null` and logging a new telemetry reason (`bridge_session_get_3p_provider`). Separately, this helper gained a `useV2` override option, so it no longer always derives whether to use the V2 path solely from `isCcrV2SessionCrudEnabled`.

**Why**

This stops session-fetch requests from going out to the bridge when a third-party provider is in use, rather than attempting a fetch that presumably wasn't meant to succeed in that setup.

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

### Sandbox network permission check: per-command allowlist and richer denial reasons

Sandbox network permission checks gain per-command allowlists and custom denial reasons

**What**

The check that decides whether a sandboxed command can reach the network now looks up a per-command list of allowed domains after checking global configuration rules but before falling back to denying the request outright. When a user is asked to approve or deny such a request, the denial can now carry a custom reason string instead of a plain yes/no.

**Why**

This makes network permission denials more informative, and lets individual commands be granted network access without changing sandbox-wide settings.

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

### New artifact wake-subscription failure reason: session_device_bound

New error explains why artifact wake subscriptions fail on desktop-bound cloud sessions

**What**

Artifact "wake subscriptions" (which let a session be woken up by activity on an artifact) now report a specific new failure reason, `session_device_bound`, when the cloud session is tied to the desktop that started it, such as through Cowork or `claude --cloud`. This happens because of a trusted-device check, and it's now fully wired up: parsed from the server's response, shown to the user with a specific message, and checked at another point in the code.

**Why**

Users running a desktop-bound cloud session will now get a clear explanation of why wake subscriptions don't work for them, and know that retrying won't help, while publishing and reading artifacts are unaffected.

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

### Managed pricing validation relaxed to accept a managed: block

Pricing settings now also take effect under a managed: block, not only under admin:

**What**

Claude Code checks organization configuration files for pricing information. Previously, custom pricing only had any effect if it was set inside an `admin:` block. Now it also takes effect if set inside a `managed:` block, as long as that block contains at least one policy. This is because both blocks are read for pricing: `admin:` feeds the built-in spend tracker, and `managed:` feeds the `modelPricing` values pushed out to client devices.

**Why**

Organizations that configure pricing under `managed:` instead of `admin:` will now have that pricing actually apply, instead of silently being ignored.

- Area: Managed Settings
- Names: `managed`, `admin`
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### Bash permission deny-rules extended to redirects, `env --chdir`, and argument caps

Bash permission checks now also cover shell redirects and env-based argument rewriting, asking instead of silently allowing when unsure

**What**

The checker that decides whether a shell command is allowed to run now looks beyond the command itself:

- it checks shell redirect targets (like `>`, `>>`, `<`) against Edit deny rules, so a command can't sneak a write to a blocked file through a redirect

- it detects risky uses of `env` and `env --chdir` that rewrite a command's arguments

- it caps how many individual arguments it will check, and once that cap is hit it now falls back to asking you explicitly (a new "denyRulesUnjudged" state) instead of silently letting the command through

**Why**

Previously a command with more arguments than the checker could fully verify might be allowed to run without a proper deny-rule check. Now, when Claude Code can't fully verify every argument or redirect target, it asks for confirmation rather than guessing it's safe.

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

### Blocked-content refusal reason can now surface a specific policy category

Blocked-content refusal messages can now name the specific policy category that triggered them

**What**

When Claude Code's fast safety classifier blocks some content, it now tries to pull a `<category>` tag out of the classifier's raw response. If that category matches one of a known set, the refusal message now shows a bracketed category name (like `[category name]`) instead of always showing the same generic fallback message.

**Why**

This gives a more specific explanation of why content was blocked, when the classifier's response identifies a known category, instead of a one-size-fits-all message.

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

### Tool-call telemetry now suppresses detailed input fields in some sessions

Tool-call telemetry now skips file paths, commands, and skill/subagent names in some sessions

**Unclear.** What determines which sessions have these fields suppressed is not stated.

**What**

When Claude Code records telemetry for a tool call, it normally attaches detail fields like `file_path`, `full_command`, `skill_name`, and `subagent_type`. This now only happens when an additional check passes; in sessions where that check comes back true, none of these detailed fields are attached to the telemetry payload.

**Why**

This means some sessions send less detailed tool-call telemetry than before, likely to avoid capturing sensitive details like file paths or command text in those cases.

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

### WorktreeRemove hook result reporting overhauled

WorktreeRemove hook now reports whether it actually ran, removed the worktree, or failed

**What**

The `WorktreeRemove` hook, which can run when a worktree is being removed at session exit, when a subagent finishes, or when you delete a background session, now returns a structured result instead of a simple yes/no: `not_configured`, `removed`, or `failed`, each with a summary. If the hook reports failure or gives no output but the worktree directory is confirmed gone anyway, Claude Code now treats the removal as successful rather than reporting a failure.

**Why**

This gives clearer feedback about what actually happened during worktree removal, and avoids reporting a false failure when the hook didn't report cleanly but the worktree was in fact removed.

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

### Short unrecognized model names are now tentatively allowed

Short, unrecognized model names now get a further chance instead of being rejected immediately

**What**

When Claude Code encounters a model name it doesn't recognize, it used to reject it right away if it didn't match a known shape. Now, if the unrecognized name is classified as an "other" shape and is short enough, it's allowed to fall through to further allowed/blocked checks instead of being rejected on the spot.

**Why**

This avoids immediately blocking short model names that don't match a known pattern, giving them a chance to pass other validation instead of being turned away outright.

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

### Directory-sync now verifies git config wasn't mutated mid-read before trusting it

Directory-sync now detects if git config changed while being read and refuses to trust it

**What**

When Claude Code's directory-sync feature decides whether it's safe to run git in a synced checkout, it now takes a fingerprint of each git config file (its device, inode, size, and change time, plus a hash for small files, following symlinks) both before and after reading it. If the fingerprint changed during the read, or a follow-up check shows the config changed since it was read, Claude Code now refuses to run git there rather than trusting a config that might have been altered mid-read.

**Why**

This guards against acting on a git configuration that was modified while it was being read, which could otherwise lead to running git with stale or tampered settings.

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

### Commands carrying allowed_domains now force an 'ask' via the auto-mode classifier

Commands with allowed_domains now always prompt for approval instead of being auto-allowed

**What**

When a tool call is restricted to a sandbox network list and carries `allowed_domains` under the relevant sandbox mode, Claude Code's permission check now forces the decision to "ask" rather than letting an allow rule or hook approve it silently. The message explains that allow rules and hook approvals cover the command itself but not the specific hosts it's allowed to reach, and that only the auto-mode classifier can approve the `allowed_domains` list.

**Why**

This closes a gap where a command could be pre-approved without the specific network hosts it's allowed to contact also being vetted, ensuring host access still goes through the classifier meant to review it.

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

### MCP tool telemetry now sends hashed server/tool names even without consent

MCP tool telemetry now sends hashed server and tool names even when full-name consent is withheld

**What**

The function that builds the MCP server and tool name fields for telemetry previously sent nothing at all when the user hadn't consented to sharing full names. Now, in that same no-consent case, it sends hashed versions of the server name and tool name (`mcpServerNameHash` and `mcpToolNameHash`) instead of omitting the fields entirely.

**Why**

This lets Claude Code's telemetry distinguish and count distinct MCP servers and tools in aggregate even without consent to see their actual names, since a hash reveals usage patterns without exposing the original name.

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

### MCP server configs are redacted (headers/env/args) before being surfaced/displayed

MCP server details like headers, environment variables, and arguments are now redacted before being shown

**What**

When Claude Code displays or logs an MCP server's configuration, sensitive parts are now masked first. For servers connected over HTTP or SSE, headers are replaced with `[REDACTED]`. For servers run as local processes (stdio), environment variable values are replaced with `[REDACTED]` and command-line arguments are cleared. The server's URL or command itself also goes through a separate masking step. This applies to the `mcp status`, `mcp list`, and `mcp get` commands, as well as configuration diffs.

**Why**

MCP server configs often carry secrets like API keys or tokens in headers or environment variables. Redacting them before display prevents those secrets from being accidentally exposed on screen or in logs.

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

### Artifact file listing/reading now reports the Artifact's declared "type"

Listing or reading artifact files can now mention the artifact's declared type in its response text

**What**

When Claude Code lists or reads files through the artifacts tool, the response text can now say the file comes from "an Artifact of type X" when the artifact has a declared type, rather than describing it as a plain artifact.

**Why**

This gives more descriptive, useful context about type-specific artifacts when their files are listed or read.

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

### Domain-pattern validation rejects overly-broad wildcards for allowedDomains/deniedDomains

Sandbox domain lists now reject overly broad wildcard patterns like *.com

**What**

Entries in `allowedDomains` and `deniedDomains` (the sandbox's network allow/deny lists) must now be a real domain name, a single-level wildcard like `*.example.com`, `localhost`, or a bracketed IPv6 address. Overly broad patterns such as a bare `*` or `*.com` are rejected for `allowedDomains`; `deniedDomains` still allows a bare `*` since that means "deny everything".

**Why**

This prevents an accidentally or intentionally overbroad allow rule from opening network access far wider than intended, closing off a class of overly permissive sandbox configurations.

- Area: Sandbox Network
- Names: `allowedDomains`, `deniedDomains`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Clearer guidance that usage-credit toggles need a restart/new session

Usage-credit toggle message now clarifies you must restart or start a new session for it to take effect

**What**

The message shown when 1M-token context usage credits are required now explicitly says that turning credits on only takes effect in a new session or after restarting Claude Code, rather than sounding like it applies immediately.

**Why**

This prevents confusion where a user enables credits, expects it to work right away, and doesn't realize a restart or new session is needed.

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

### Plugin marketplace/details view computes a config-warning summary for the selected MCP client

Plugin marketplace view now computes a configuration-warning summary for the MCP client tied to the selected item

**Unclear.** What the computed warning summary actually displays or triggers in the UI is not stated.

**What**

In the plugin marketplace/details screen, Claude Code now identifies which MCP client (a connected tool or integration) the currently selected item belongs to, and computes a summary of any configuration warnings for that client.

**Why**

This appears to prepare the interface to surface configuration warnings relevant to the selected plugin's client, though the finding doesn't describe what is shown to the user as a result.

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

### API error banners get a link for organization-verification errors

Organization-verification API error messages can now include a clickable link

**What**

When Claude Code shows an error banner for an API error of the kind "organization verification required," it can now include a clickable link in addition to the plain text message.

**Why**

This makes it easier to act on an organization-verification error directly from the error message instead of having to search for where to go.

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

### Background agent status messages adapt when the agent has no readable output file

Background agent status messages now avoid pointing to output when there isn't any to read

**What**

When a background agent (a task running separately from your main conversation) stops or is interrupted, Claude Code shows a status message. That message now checks a flag called `canReadOutputFile`. When there is no readable output file, the message no longer tells you to go check the agent's worktree or output for partial work; instead it tells you to resume the agent and ask it for a status report.

**Why**

This avoids pointing users toward output files that don't actually exist or can't be read, giving them a working next step instead.

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

### Relaxed sandbox mode gets its own summary text instead of a directory list

Relaxed sandbox mode now explains itself in plain text instead of listing directories

**What**

When the filesystem sandbox (the mechanism that confines what files a command can read or write) is set to 'relaxed' mode, the permission-prompt summary no longer lists specific allowed and denied directories. Instead it plainly states that the sandbox does not confine commands to particular directories for reading or writing. Configured working and deny paths are still shown, but only as informational context. The summary also reminds Claude to leave Claude Code's own configuration, hooks, and skills, as well as git's hooks and configuration, untouched unless specifically asked to change them.

**Why**

A directory list implied restrictions that relaxed mode doesn't actually enforce; the new wording states plainly what relaxed mode does and doesn't do, while still warning against touching sensitive configuration.

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

### Chrome DevTools bridge now pushes external config to every connected peer, not just one

Chrome DevTools bridge now pushes config updates to all connected devices, not just the selected one

**What**

The bridge relay client used for the Chrome DevTools connection gained two new methods: `pushExternalConfigToPeer(deviceId, config)` and `pushExternalConfigToAllPeers(config)`. Messages sent over the bridge now carry a `target_device_id`. When a pairing event ('paired') occurs, the client now calls `pushExternalConfigToAllPeers()` to update every connected peer, instead of only updating whichever device was currently selected. A newly connected peer also receives its own targeted push.

**Why**

This keeps configuration consistent across every connected device rather than only the one currently selected, which matters when more than one device is bridged at once.

- Area: Chrome & Browser
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Artifact-store write guidance now distinguishes types with vs. without endpoints

Artifact write guidance now tells the model plainly when a type has no writable store at all

**What**

When an Artifact (a piece of generated content Claude Code manages, like a shared document or canvas) declares a shared store, Claude Code gives the model guidance on how to write to it. That guidance now takes into account whether the artifact's type actually declares any endpoints (ways to write to the store). If it doesn't, the model is now told plainly that no store-write call is available for that type, rather than being pointed toward `run_script` as a possible option regardless.

**Why**

This stops the model from being nudged toward trying `run_script` to write to a store when that path doesn't actually exist for the artifact's type, avoiding wasted or confused attempts.

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

### Group-pool ('team's shared budget') overage messaging

Usage-limit messages now have a distinct wording for teams sharing a group pool budget

**What**

When a rate limit is hit, Claude Code shows a message explaining the type of usage cap involved. A new case, `group_pool`, now produces its own message referring to "team's shared budget" and pointing admins and users to claude.ai/admin-settings/usage, separate from the existing messages for an organization spend cap or a channel-scoped limit.

**Why**

This makes the rate-limit message accurate for teams that share a pooled usage budget, telling them specifically that it's their team's shared allowance that's been used up, and where to go to check or raise it, rather than showing generic or misleading wording.

- Area: Rate Limits
- Names: `group_pool`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Memory/CLAUDE.md truncation warnings now name where content was cut

Truncation warnings for CLAUDE.md and memory files now say exactly which line and text got cut

**What**

When a memory file (such as CLAUDE.md) or its index gets truncated for being too long, the warning message now states exactly which line the cut started at, and where possible, quotes the first roughly 80 characters of that line.

**Why**

Previously the warning only said a file was too long, without saying where. Naming the exact line and showing its content makes it much easier to find and fix the part of a memory file that's causing content to be dropped.

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

### upload_image tool tightened to computer-tool screenshots only, with expiry guidance

upload_image now only accepts computer-tool screenshots, with guidance on expiry and retry limits

**What**

The `upload_image` tool's description was rewritten to narrow its scope: it now only accepts screenshots taken via the computer tool's screenshot action, not images a user has directly uploaded. It states that screenshot IDs expire a few minutes after being captured, so a screenshot should be uploaded right after it's taken. It also tells Claude not to reuse the ID from a failed upload, instead retaking the screenshot and retrying at most once, and never retrying after a user has declined. For files a user has attached, Claude is told to use `file_upload` instead.

**Why**

This prevents Claude from misusing `upload_image` for the wrong kind of file and avoids repeated failed upload attempts with a stale or already-rejected screenshot ID.

- Area: Chrome & Browser
- Names: `upload_image`, `file_upload`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### WebFetch now explicitly blocks dotless/localhost hostnames with a dedicated error

WebFetch now gives a specific error for localhost and other dotless hostnames, pointing to curl instead

**What**

WebFetch (the tool Claude Code uses to retrieve a URL) now throws a specific error when the requested URL's hostname has no dot in it, such as `localhost` or a bare hostname. The error tells the user to use `curl` via the Bash tool instead. The tool's own description was also updated with this caveat.

**Why**

WebFetch was never able to reach local servers, but previously the failure was less clear. Now the error explains why it failed and points directly to the working alternative for hitting something running on your own machine.

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

### Managed-settings 'notices' surfaced separately from errors

Managed-settings startup output now separates non-error notices from actual errors

**Unclear.** Whether the tengu_managed_settings_validation_errors gate is on for any account is unread, so nothing can be said about its current state.

**What**

When Claude Code starts up and reports on managed settings (organization-provided configuration), it now also collects and prints non-error "notices" under their own "Managed settings notices:" heading, separate from the existing reporting of fatal errors and invalid entries.

**Why**

This lets Claude Code flag things worth knowing about managed settings without implying something is actually broken, and keeps genuine errors from being buried among informational notices.

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

### Plugin status listing now flags org-required MCP plugins

Plugin status now shows "required by your org" when a loaded MCP plugin is mandated by org settings

**What**

The status report shown by `/plugin` (and `claude mcp`) now adds the text "required by your org" next to a plugin's status line when that plugin is enabled and your organization's settings mark it as required. This is shown alongside the existing statuses for disabled plugins, plugins that loaded with errors, and plugins that loaded normally.

**Why**

This makes it clear at a glance which plugins are enabled because your organization requires them, rather than by your own choice, so you understand why a plugin can't simply be turned off.

- Area: Plugins
- Names: `/plugin`, `claude mcp`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### C4E slash-command upsell now distinguishes signed-out users

Claude for Enterprise upsell message now differs for users who are fully signed out versus just missing an enterprise org

**Unclear.** Whether this new messaging is active for any given account is unread for this release; the `tengu_c4e_slash_upsell` gate was previously read on for this site's account and the anonymous baseline, and `tengu_c4e_slash_upsell_shown` has no recorded reading at all.

**What**

The upsell message shown for the Claude for Enterprise (C4E) slash command now checks whether you're completely signed out, with no API key and no OAuth login, versus signed in but just not belonging to a C4E organization. Each case now shows a different message and is tracked with a different telemetry label. A signed-out user sees a message telling them to run `/login` to sign in with their claude.ai account.

**Why**

This makes the upsell message more relevant by pointing signed-out users toward signing in first, rather than showing the same generic message regardless of why they lack access.

- Flag `tengu_c4e_slash_upsell`: Not enough to say (read for one account on one subscription tier against v2.1.268; this account: no value returned, anonymous baseline: on, compiled default: off)
- Area: Elsewhere
- Names: `/login`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### New git-safety instruction in the commit/PR prompt template: avoid bulk `git add`

Commit/PR guidance now warns against bulk `git add -A` or `git add .`

**What**

The built-in guidance Claude Code follows when committing changes or creating pull requests now includes a warning to stage files by name rather than using `git add -A` or `git add .`.

**Why**

Bulk-adding all files can accidentally sweep in things like `.env` files, credentials, or large binary files that shouldn't be committed; staging specific files by name avoids that risk.

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

### New "model not available for your account" validation error

New clearer error when a chosen model isn't available for your account

**What**

When Claude Code checks whether a requested model can be used, it now tells the difference between a permission problem and a generic API error. If your account simply doesn't have access to the model you asked for, you'll now see a specific message: "Model '...' isn't available for your account."

**Why**

This makes it clearer when a model failure is because of account access rather than a transient API issue, so you know to check your plan or permissions instead of retrying or debugging a connection problem.

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

### New "github_not_connected" outcome for Claude GitHub/cloud-session access checks

New "github_not_connected" reason distinguishes unlinked GitHub accounts from other access failures

**What**

When Claude Code checks GitHub access for Cloud sessions and background-task remote execution, it now separately reports a `github_not_connected` case for when your linked account simply isn't connected to GitHub at all, instead of grouping it in with other, more transient failures.

**Why**

This makes it easier to tell that the fix is to connect your account to GitHub, rather than treating it as a temporary glitch to retry.

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

### Publish/artifact content-type gate broadened beyond exact text/html

Live/reseed artifact publishing now accepts a broader set of content types, not just exact text/html

**Unclear.** The finding does not list which other content types are now included.

**What**

The check that decides whether live or reseed publishing options are available for an artifact now tests the content type against a set of allowed values instead of requiring it to be exactly `text/html`.

**Why**

More kinds of published artifact content can now use the live/reseed publishing options, where previously only content typed as exactly `text/html` qualified.

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

### Resume picker now forwards pending SessionStart hook messages

Resuming a session from the picker now carries forward any pending SessionStart hook messages

**What**

When you resume a previous session from the resume picker, Claude Code now carries forward that session's recorded `SessionStart` hook messages (hooks are scripts that run automatically at points like session start) and shows them as pending messages in the resumed session's interface.

**Why**

This means messages produced by startup hooks aren't lost when you resume a session; they show up in the resumed session the same way they would have shown up originally.

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

### New reply-suppression reason: pages that own their own comment threads

Claude Code now recognizes pages that manage their own comment threads and skips posting replies there

**What**

When Claude Code would normally reply to or resolve a comment thread on an artifact (a generated file or output), it now checks for a new condition: whether the page itself owns and manages its own comment threads. When this applies, it shows a specific message, "reply not posted (the page keeps its own comment threads)" or "not resolved (the page keeps its own comment threads)", instead of the generic messages about needing thread activation.

**Why**

This avoids confusing or misleading messages about needing to "activate" a thread when the real reason a reply wasn't posted is that the page manages its own commenting system.

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

### Team shared-budget ('group_pool') hit message

New message when your team's shared usage budget runs out, with a path to raise it or switch models

**What**

When a team's pooled usage budget (a shared limit across a group) is exhausted, Claude Code now shows: "You've hit your team's shared budget. Switch to another model... to continue." If purchasing extra usage is available, it adds "Run `/usage-credits` to raise it and keep using [model] or switch models..."; otherwise it points you to `/model` to switch models instead.

**Why**

This gives people on team or organization shared budgets a clear, specific message about what happened and what they can do next, rather than a generic limit-reached message.

- Area: Rate Limits
- Names: `/usage-credits`, `/model`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Plugin menu shows auto-reload deferred/queued state with new copy

Plugin menu now tells you when plugin changes are queued to apply after the current response finishes

**What**

A new helper detects when changes to plugins (add-ons that extend Claude Code) need a reload to take effect, and reports it as either "deferred" or "queued" via telemetry. When a response is still being generated, Claude Code now shows: "Plugin changes apply when the current response finishes (`/reload-plugins` is queued)."

**Why**

This makes it clear that plugin changes made mid-response aren't lost or ignored; they're just waiting for the current response to finish before `/reload-plugins` applies them.

- Area: Plugins
- Names: `/reload-plugins`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Push-default remote detection now returns multiple candidate remotes

Git push permission rules can now include both origin and a custom pushDefault remote at once

**What**

When Claude Code figures out which git remotes to grant push permission for (so it can suggest a rule like `git push origin *`), it now returns multiple candidate remotes instead of picking just one. It includes `origin` when present, plus whatever remote is configured as `remote.pushDefault`, as long as that name fits an expected naming pattern.

**Why**

Repos that push to both `origin` and a separate configured push remote (like a fork or an upstream) now get permission rules covering both, instead of Claude Code having to choose only one and potentially still prompting for the other.

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

### Bash monitor timeout message now reports event count and distinguishes flush/bounded behaviour

Bash monitor timeout messages now report how many events fired instead of a generic message

**What**

When a background monitor watching a running bash command times out, Claude Code used to show a flat "[Monitor timed out — re-arm if needed.]" message. Now the message reports how much time passed and how many events the monitor actually delivered before it expired, or says plainly that no events were delivered. Monitors also gained a way to flush pending events and count how many have fired, plus a "bounded"/"quiet" mode that can flush accumulated output right before the timeout fires instead of just cutting off.

**Why**

This gives a clearer picture of whether a monitor missed activity or simply saw nothing happen, making it easier to decide whether to re-arm the watch or move on.

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

### Artifact publish `files` copy-by-artifact now infers contentType from destination path

Publishing an artifact file copy now figures out its content type from the destination path automatically

**What**

When publishing an artifact and copying a file into it (whether given as a plain source string, a `{from, ...}` entry, or a `{artifact, path}` copy), Claude Code now works out the file's content type from where it's being placed, combined with any content type you explicitly set. Previously, the content type was only recorded when you specified it yourself via `{from, contentType}`; otherwise it wasn't carried through at all.

**Why**

This fills in a detail that used to require the file's content type to be set by hand for these copy forms, so files copied by path or by referencing another artifact are more likely to be published with the right type without extra input.

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

### New deny path for asset saves outside working folders in no-consent-surface sessions

Artifact asset saves outside the working folder are now auto-denied when no one can approve the prompt

**What**

Artifacts can save files (`read_asset` requests) outside the session's normal working folders, but only with the user's approval. In sessions where there's no way to show that approval prompt at all — such as Cowork or local-agent sessions running without a live user to ask — this request is now automatically denied instead of falling through to whatever the previous logic happened to produce.

**Why**

This closes a gap where a permission request that can never be answered could previously behave unpredictably; now it's refused outright, keeping asset saves confined to the working folders when there's no one present to grant an exception.

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

### New unreadable/no-consent guard added to upload_asset flow

Uploading a local file as an artifact asset is auto-denied when unreadable and unapprovable

**What**

When Claude Code is about to ask for permission to upload a local file as an artifact asset, it now checks first for a case where there's no specific read rule for that path, the path looks suspicious or is outside expected bounds, and the session has no way to show a consent prompt. In that situation, the upload is denied immediately instead of proceeding to build and show the normal permission request.

**Why**

This prevents a permission prompt that could never be answered from stalling or behaving unpredictably, denying the upload outright when the file's safety can't be confirmed and no one is available to approve it.

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

### OAuth error screen now hyperlinks trailing URLs and supports verbatim messages

Login error screen turns trailing URLs in OAuth errors into clickable links and can show messages verbatim

**What**

The screen shown when logging in via OAuth fails now looks for a URL at the end of the error message and, if found, displays it as a clickable link rather than as plain text. The screen also gained a `verbatim` mode, which shows the raw error message as-is without prefixing it with "OAuth error:".

**Why**

This makes it easier to act on login errors that include a link, such as one pointing to a page to resolve the issue, and lets some error messages be shown exactly as received when a prefix wouldn't make sense.

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

### Plugin settings view prompts a reload after changes that need one

Plugin settings screen now prompts a reload only when a change actually needs one

**What**

The plugin manager screen now tracks whether a change you made needs a reload to take effect. When you exit, Claude Code either does nothing, queues a reload for later, or takes you straight into `/reload-plugins` (a command that reloads all active plugins to apply pending changes without restarting), depending on what you changed.

**Why**

This means you're only prompted to reload plugins when a change actually requires it, instead of having to remember to run `/reload-plugins` yourself every time.

- Area: Plugins
- Names: `/reload-plugins`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Teleport failure message now suggests /web-setup and points users to retry

Teleport failure messages now suggest running /web-setup to reuse your GitHub login, then retrying

**What**

When a teleport to the cloud fails or is blocked on a precondition, the error message now suggests running `/web-setup` (which connects your GitHub account using your local `gh` CLI login) to reuse your existing GitHub CLI login, then tells you to rerun `/teleport` (which pulls a Claude Code on the web session into your terminal).

**Why**

This turns a teleport failure into an actionable message, giving you a concrete next step to fix a missing GitHub connection instead of just reporting that it failed.

- Area: Teleport
- Names: `/web-setup`, `/teleport`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### MCP 'needs auth' servers are now tracked and surfaced once per session/persistently

Claude Code now avoids repeatedly nagging you about the same MCP server needing authentication

**What**

When an MCP server (a connected external tool server) needs authentication, Claude Code now keeps track of which servers it has already flagged to you, both for the current session and persisted across sessions (with a cap on how many are remembered). Once a server successfully connects, it is cleared from that list.

**Why**

This stops the same 'needs auth' notice from being shown over and over for a server you already know about, while still re-flagging it if it later needs attention again.

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

### New gateway config warning for empty access_control.allow_cidrs

The gateway now warns if access_control.allow_cidrs is left empty and any client address can connect

**What**

When validating the Claude Code Gateway's configuration, Claude Code now warns if `access_control.allow_cidrs` is left empty and the listener isn't otherwise restricted to local connections. The warning spells out that this means the gateway will accept connections from any client address, and that such clients can push commands that then run on developer machines.

**Why**

This flags a configuration that could let an unintended client connect to the gateway and issue commands, before it becomes a real security problem rather than after.

- Area: Gateway
- Names: `access_control.allow_cidrs`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Bulk plugin-disable now skips org-required plugins and their dependents

Bulk-disabling all plugins now leaves organization-required plugins and their dependents enabled

**What**

When you disable all enabled plugins at once, Claude Code now figures out which plugins your organization has marked as required, along with anything those plugins depend on, and leaves them enabled instead of disabling everything. It reports how many plugins were skipped for this reason and how many other plugins depend on them.

**Why**

This prevents a bulk disable action from accidentally turning off plugins your organization requires, which could otherwise break required functionality.

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

### GitHub connector access-check reworked with explicit not-connected reason

GitHub connection check now distinguishes 'not connected' from other setup problems, with its own message

**What**

The check Claude Code runs during setup to see whether it has GitHub access now returns a structured result with a `hasAccess` flag and a `reason`, instead of a plain yes/no. A new specific reason, `github_not_connected`, gets its own tailored message, separate from the generic message telling you to run `/web-setup`.

**Why**

This lets Claude Code tell you specifically that your GitHub account isn't connected, rather than giving the same generic setup instructions for every kind of access problem.

- Area: Elsewhere
- Names: `github_not_connected`, `/web-setup`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Permission-prompt tool cards get structured rendering

Permission prompts get a new structured 'card' layout with truncated values and an overflow indicator

**What**

Permission-request prompts (the ones asking whether to allow a tool action) can now render as a structured "card": a bold question, informational lines, and values that are dimmed and truncated to fit the available width, with a "… (+N more lines)" indicator when content is cut off. The prompt display checks whether this card layout fits within a height budget before using it, falling back to the old plain-text rendering if it doesn't fit.

**Why**

This makes permission prompts easier to scan by giving them consistent visual structure, while still falling back to the simpler text display when there isn't enough room to show the card properly.

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

### @mention file references get a distinct 'not read' rendering

Files referenced with @-mention but not actually read are now labeled '(not read)'

**What**

When a message references a file using an @-mention but that file was never actually read, Claude Code now renders it distinctly as 'Referenced (not read)', listing the mentioned names.

**Why**

This makes it clear when a file you mentioned wasn't actually opened and read into context, instead of leaving that ambiguous.

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

### New VerificationRequiredError surfaces its message verbatim during OAuth login

Login errors that require extra verification now show their exact message instead of a reworded one

**What**

The login flow now recognizes a new error type, `VerificationRequiredError`. When this specific error occurs, Claude Code marks it to be shown verbatim, meaning the original error message is displayed exactly as received rather than being reformatted or summarized.

**Why**

This ensures that when a login attempt needs extra verification, you see the precise message from the server rather than a generic or altered version of it, which should make it clearer what to do next.

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

### Plugin details screen can show "Required by your org"

Plugin details screen can now show a plugin as 'Required by your org'

**What**

The plugin details screen now checks a plugin's installation preference and, when it indicates the plugin is required by the organization, shows a dim ' · Required by your org' label next to the plugin's enabled or disabled status.

**Why**

This gives users in a managed organization a visible signal, directly in the plugin details view, when a plugin isn't optional but is required by their organization's settings, building on the managed-plugin admission checks introduced previously.

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

### Cowork-frame session file-read denials for out-of-folder or unreadable local files

Cowork sessions now auto-deny local file reads outside connected folders or that can't be checked, instead of asking for approval

**What**

In Cowork sessions (a mode where Claude works inside a shared frame), attempts to read local files that fall outside the folders connected to that session, or files that can't be examined at all, are now automatically denied rather than triggering an approval prompt.

**Why**

These denials happen because there is no one available to answer an approval card inside a Cowork session, so rather than leaving the request stuck, it's declined outright, keeping file access scoped to the folders the session is actually connected to.

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

### /rc-style upsell now distinguishes signed-out users from Enterprise-gated ones

The Enterprise upsell message now tells signed-out users to sign in instead of showing the generic admin message

**What**

The upsell message that appears when a Claude for Enterprise related slash command isn't available was previously a single fixed message. It now branches into three cases:

- the command is disabled by a managed (admin-controlled) setting

- the user is signed out entirely, with no credentials found

- the original case, telling the user to ask their admin about migrating

A new `variant` field is now logged alongside the existing `tengu_c4e_slash_upsell_shown` telemetry event, recording which of the three messages was shown.

**Why**

This avoids telling a signed-out user to "ask their admin" when the real issue is that they simply aren't signed in, pointing them to the correct next step instead.

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

### New "github_not_connected" state threaded through GitHub-access checks

GitHub access checks now report a distinct 'not connected' state pointing you to /web-setup

**What**

Checks for GitHub App or cloud-session access now distinguish a specific `github_not_connected` state, meaning your linked GitHub account isn't connected, from a generic transient failure. This state flows through the `bg_remote_eligibility_check` and into the cloud-access-reason UI, which now shows a dedicated message: "Connect it on the web at ..." pointing to `/web-setup`.

**Why**

This gives a clearer, more actionable message when GitHub access fails specifically because the account was never connected, directing the user straight to `/web-setup` instead of a generic error.

- Area: Elsewhere
- Names: `github_not_connected`, `/web-setup`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Plugin git/marketplace error output now redacts repo URLs

Plugin and marketplace git error messages now hide repository URLs instead of showing raw output

**What**

When a git clone, fetch, or checkout fails while installing a plugin or marketplace, Claude Code used to show the raw error text from git, which can include the full remote repository URL and sometimes embedded credentials. Error messages are now passed through a redaction step that masks the URL before it's shown to the user or written to logs. A related helper produces a safe version of the URL for log lines like `git clone: url=...`.

**Why**

This prevents credentials or sensitive repository addresses from leaking into error messages or log files when a plugin or marketplace git operation fails.

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

### PowerShell tool validateInput now also checks sandbox network-list applicability

PowerShell commands are now checked against the sandbox's allowed-domains network list, like Bash commands already were

**What**

The validation that runs before a PowerShell command executes now includes the same network-list check that Bash commands already had, using the same underlying helper. This runs alongside the existing Windows-policy and sleep-blocking checks that PowerShell already performed.

**Why**

Previously the sandbox's `allowed_domains` network restriction only applied to Bash; PowerShell commands can now also be refused if they attempt to reach domains outside that allowlist.

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

### write_db 'field' parameter validation tightened

write_db's str_replace 'field' parameter now has a stricter length and character check

**What**

The `field` parameter used by `write_db`'s `str_replace` operation used to be validated with a simple regular expression. It's now checked against an explicit length bound of 1 to 200 bytes plus a named rule: the field must name a single top-level key, with no dots, slashes, brackets, quotes, backslashes, control characters, or invisible formatting characters, and it can't be the reserved `__name__` key.

**Why**

This closes off ways a malformed or crafted `field` value could reference something other than a simple top-level key, such as by using path-like separators or hidden characters.

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

### Away-summary generator now caps repeated failures and coordinates with a background job scheduler

The 'away summary' recap now stops retrying after repeated failures and avoids overlapping generations

**What**

Claude Code can generate a summary recap of what happened while you were away (after the terminal window was blurred/unfocused). This generator now tracks how many times in a row it has failed during a given turn and stops trying again once it fails three times. It also skips starting a new generation if one is already in progress. The way this background work is saved and tracked internally was also reworked.

**Why**

This prevents the away-summary feature from repeatedly failing and retrying in a loop, or from running duplicate generations at once, making it more predictable when it fails and quieter when it does.

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

### Plugin enable/disable toast no longer hard-codes "Run /reload-plugins to apply."

Plugin enable/disable messages no longer always tell you to run /reload-plugins

**Unclear.** It is unclear what determines the replacement fragment shown in each case, or whether it still points to `/reload-plugins` in most situations.

**What**

When you enable, disable, update, or uninstall a plugin, or disable/uninstall one via a settings file, Claude Code used to always append the fixed instruction "Run /reload-plugins to apply." to the confirmation message. That fixed text is now gone, replaced by a fragment that is supplied separately depending on the situation.

**Why**

This lets the confirmation message vary by context instead of always pointing you to `/reload-plugins`, which is useful since `/reload-plugins` lets you apply plugin changes without restarting Claude Code.

- Area: Plugins
- Names: `/reload-plugins`
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### New wording for plugin-enable confirmation depends on a changesApplyOnClose flag

Plugin-enable confirmation message now varies based on whether changes apply automatically when the menu closes

**What**

The reminder text shown after enabling a plugin now depends on a `changesApplyOnClose` condition: when set, it tells the user the change takes effect as soon as they close the menu; otherwise it still tells them to run `/reload-plugins` to apply pending changes.

**Why**

This gives users an accurate instruction depending on whether their plugin change needs the explicit `/reload-plugins` step or applies automatically.

- Area: Plugins
- Names: `/reload-plugins`
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Served model catalog fetch surfaces credential-specific access errors

Model catalog errors now flag when a credential specifically can't read the served list

**What**

When Claude Code fetches the server-provided list of models and gets back an error response, it now parses the error body to check whether the problem is credential-related. If so, it appends '(this credential cannot read the served list)' to the logged message and returns this more specific error, instead of a generic HTTP-status error.

**Why**

This makes it clearer, from the error itself, when the model list failed to load because of a credential permissions problem specifically, rather than an unspecified server error.

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

### navigate tool now instructs Claude to clean up tabs it opens implicitly

navigate tool now tells Claude to close tabs it opens on its own once no longer needed

**What**

The `navigate` tool's description now tells Claude that when it opens a browser tab implicitly (by calling `navigate` on its own, without first creating a tab via `tabs_create_mcp`), that tab is still Claude's responsibility to clean up. Claude is instructed to close such tabs with `tabs_close_mcp` once they're no longer needed, unless the user wants the tab kept open.

**Why**

This reduces browser clutter left behind by Claude's own navigation actions, so a session doesn't accumulate tabs that Claude opened but never closed.

- Area: Chrome & Browser
- Names: `navigate`, `tabs_close_mcp`
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Chrome-extension bridge tool-call error handling replaced with generic timeout race

Chrome-extension bridge errors lose their detailed, tailored troubleshooting messages

**What**

The function that produced specific error messages for failed Chrome-extension bridge tool calls (distinguishing timeouts, disconnects, and generic errors, each with its own troubleshooting advice) has been replaced with a generic timeout wrapper that just races the call against a timeout and returns a plain fallback value.

**Why**

Users hitting a Chrome-extension bridge failure will now see a generic outcome instead of a tailored explanation of what went wrong and how to fix it.

- Area: Chrome & Browser
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Feedback survey followup payload now whitelists included transcript/session fields

Feedback survey followups now send only a fixed, named list of fields instead of a free-form object

**What**

When you submit a followup to a feedback survey, Claude Code now builds the data it sends from a fixed list of named fields: `latestAssistantMessageId`, `message_count`, `datetime`, `description`, `surface`, `platform`, `gitRepo`, `commitSha`, `remoteWorkspace`, `remoteSessionId`, `version`, `transcript`, `subagentTranscripts`, `rawTranscriptJsonl`, `recentSessionTranscripts`, and `debugLog`. Previously the submission passed through whatever object it was given.

**Why**

Restricting the payload to a known allowlist of fields prevents unintended or extra data from being included in a feedback submission.

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

### Task-status tool result now conditionally omits output file path based on available tools

Background task status can now omit the output file path depending on which tools are available

**What**

When reporting the status of a background task, Claude Code now checks which tools are available to it. If that check fails, the report omits the output file path, forcing the task to report back only via `SendMessage` rather than pointing to a saved output file. This is in addition to an existing check based on `webFetchSavedFiles`.

**Why**

This prevents background tasks from referencing an output file path in cases where the tools needed to make use of it aren't actually available.

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

### Teammate resume message can append a definitionNotice

Resuming a teammate can now show an extra definitionNotice message alongside the usual resume text

**Unclear.** What kind of notice definitionNotice carries or when it is set is not stated.

**What**

When you resume a teammate (an in-process collaborator) that isn't currently running, the success message can now include an extra `definitionNotice` line, appended after the existing text about prior messages or a missing transcript.

**Why**

This allows an additional, specific notice to be surfaced to you at the moment a teammate is resumed, when one applies.

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

### New limitScope: group_pool value for Slack spend-cap telemetry

Claude in Slack usage records can now flag a denial as coming from a shared team budget rather than a personal cap

**What**

Usage data recorded for Claude in Slack gained an optional `limitScope` field, which can be `service`, `channel`, or `group_pool`. The new `group_pool` value marks a request that was denied because a pooled team budget was used up, as opposed to the individual member's own spending cap.

**Why**

This lets admins and telemetry distinguish "your team ran out of shared budget" from "you personally hit your limit," which matters for diagnosing why a Slack request was denied.

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

### Background-agent restart failure message distinguishes readable output files

Failed background-agent restarts now suggest messaging the agent for a status report when its output file can't be read

**What**

When Claude Code can't restart a background agent left over from a previous session, the advice it gives now depends on whether that agent's output file can still be read:

- If the output file is readable, it still suggests checking the agent's worktree (its own copy of the project files) or output for partial work.

- If the output file is not readable, it now instead suggests messaging the agent directly and asking it for a status report.

Either way, the guidance warns not to assume the task actually finished.

**Why**

This gives more useful next steps when a background agent can't be resumed, tailored to whether there's any output left to inspect.

- Area: Background Agents
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### OAuth API key creation can now surface a verification-required error distinctly

OAuth API key creation now surfaces a distinct 'verification required' error instead of a generic failure

**What**

When creating an API key via OAuth fails, Claude Code now checks the underlying error response for a verification-required condition. If found, it throws a specific error carrying that detail instead of falling through to the previous generic 'request failed' error.

**Why**

This lets Claude Code (and anyone debugging the failure) distinguish a case where additional verification is needed from other kinds of API key creation failures.

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

### Self-hosted runner/gateway logs how it determines client IPs

Self-hosted Claude Code runner/gateway now logs how it determines a client's IP address at startup

**What**

When a self-hosted runner or gateway starts up, it now logs whether it reads a client's IP address from the raw TCP connection or from the `X-Forwarded-For` header, based on the configured trusted proxies, along with how many trusted-proxy entries are configured.

**Why**

This makes it easier for someone running their own Claude Code server to verify it's reading client IPs correctly, which matters for things like rate limiting or access logs behind a proxy.

- Area: Self-Hosted Runner
- Names: `X-Forwarded-For`
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Token-cost validation caps values at 10,000 instead of allowing any finite positive number

Per-model cost figures in config are now capped at 10,000 instead of allowing any finite positive number

**What**

When Claude Code validates per-model cost settings (input, output, cache-read, cache-write pricing), a cost value now must be no greater than 10,000. Previously any positive finite number was accepted; a config with a cost figure above 10,000 now fails validation instead of being allowed through.

**Why**

This catches unreasonably large cost values in configuration, which were likely typos or misconfigurations rather than intentional, by rejecting them at validation time instead of silently accepting them.

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

### MCP UI shows a resolved display endpoint instead of raw command when they differ

MCP server panel now shows a resolved endpoint instead of the raw command when they differ

**What**

The MCP server status panel now computes a `displayEndpoint` for each server, and only shows a "Command:" row when this resolved endpoint is different from the raw command written in the server's configuration. When they differ, the resolved endpoint is what's shown, not the literal configured command.

**Why**

This avoids showing a raw, possibly less meaningful configuration string when a clearer, resolved endpoint is available, making it easier to see what an MCP server is actually connecting to.

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

### Artifact copy/read blocked-message text consolidated with new "Copying from this artifact is" phrasing

Artifact copy/read block messages consolidated, plus a new check for a headless capability flag

**Unclear.** The finding does not say what the new `headless` capability check is used for beyond being checked.

**What**

The code that builds the error message shown when a deny rule blocks reading or copying from an artifact was consolidated into one shared helper, which now produces one of three phrasings depending on the situation: "Copying from this artifact is", "Artifact reads are", or "Reading this artifact is" blocked by a rule. A separate new helper also checks whether a fetched artifact's capabilities include a `headless` comment flag.

**Why**

This is mostly an internal cleanup that produces more precise, situation-specific wording when an artifact read or copy is blocked by a permission rule.

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

### OAuth local-callback port selection now takes a configurable range/fallback and adds a last-resort ephemeral-port bind

OAuth login's local callback port picking is now configurable and adds a last-resort random free port

**What**

When Claude Code logs in via OAuth, it opens a temporary local web server to receive the login callback and needs a free network port for it. The function that picks this port now takes a configurable range and fallback port instead of hardcoded values.

- If no port in the configured range is free, and the fallback port is also taken, Claude Code now tries one more thing: asking the operating system to hand it any free port, before giving up.

**Why**

This makes OAuth login more resilient on machines where the usual port range or fallback port is already in use, reducing login failures due to port conflicts.

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

### Cloud headless session creation surfaces bundling notices

Creating a cloud headless session now surfaces bundling notices as messages, not just failures

**What**

When Claude Code creates a remote or cloud headless session, it can now report "notice"-level messages during the bundling step (packaging code to run remotely), in addition to the existing handling for outright bundling failures.

**Why**

This gives you visibility into non-fatal issues during bundling that previously would have gone unreported unless bundling failed outright.

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

### Push-on-release message clarifies runner-side credential behaviour and pushInsteadOf skip

Push-on-release failure message now explains credential and pushInsteadOf behavior more precisely

**What**

The error message shown when a push-on-release fails for a governed git mount was reworded. It now says "this runner-side push does not use the session's git-mount push URL," replacing older wording that described the governed mount as simply read-only. When a remote name is involved, the message now also explains that git skips every `url.*.pushInsteadOf` rule, including global and system-level ones, for this particular push, so the credential being used has to work on its own without relying on such a rule.

**Why**

This gives a more accurate explanation of why a runner-side push might fail with credential errors, clarifying that push-URL rewriting rules don't apply and the credential must work unassisted.

- Area: Self-Hosted Git
- Names: `pushInsteadOf`
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Header status badge is clickable and hoverable, with telemetry on click

The new header status badge can be hovered and clicked, and clicking it sends a telemetry event

**Unclear.** The finding does not say what clicking the badge actually does beyond sending telemetry.

**What**

The status indicator added to the CLI header (showing Remote Control's connection state) now responds to the mouse: hovering highlights it, and clicking it fires a `click` telemetry event that records the status label shown at the time.

**Why**

Making the badge interactive suggests it is meant to do more than just display status; the telemetry lets Anthropic see how often people interact with it.

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

### Plugin config-save confirmation no longer tells users to run /reload-plugins

Plugin config-save confirmation no longer tells you to run /reload-plugins

**What**

After saving a plugin's configuration, whether through the schema-based config flow or the MCPB config flow, Claude Code used to show a message telling you to run `/reload-plugins`. That message has been shortened to simply 'Configuration saved.' The success message shown when enabling or configuring a plugin now uses a variable suffix instead of a hardcoded instruction to run `/reload-plugins`.

**Why**

The confirmation message is now simpler, and no longer assumes `/reload-plugins` is always the next step you need to take.

- Area: Plugins
- Names: `/reload-plugins`
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### select_browser MCP tool can now be explicitly disabled, and its confirmation text changed

select_browser MCP tool can now be disabled, and its success message changed to 'Selected browser'

**What**

The `select_browser` tool now checks whether it has been disabled and, if so, responds as if it doesn't exist, returning 'Unknown tool: select_browser'. Separately, its success message when choosing a browser was changed from 'Connected to browser' to 'Selected browser'.

**Why**

The ability to disable the tool lets it be turned off cleanly rather than left reachable, and the reworded success message more accurately describes what the tool actually does, since it selects a browser rather than establishing a connection.

- Area: Chrome & Browser
- Names: `select_browser`
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### MCP server detail/tools views now compute a displayEndpoint

MCP server screens in Settings now compute a displayEndpoint for each server

**Unclear.** The finding does not say what displayEndpoint looks like or how it differs from the raw endpoint value.

**What**

The Settings screens for viewing an MCP server's details, its list of tools, and an individual tool's detail now compute a `displayEndpoint` value and pass it into the server data shown on screen. This applies across all transport types: stdio, sse, http, and the claudeai-proxy connection.

**Why**

This gives these screens a consistent, presentable form of a server's endpoint to show regardless of which transport it uses, rather than each screen formatting or omitting it differently.

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

### TUI opt-out reason now goes through the feedback pipeline, not raw analytics

Feedback text typed when opting out of the new terminal UI now goes through the feedback system instead of raw analytics

**Unclear.** Whether telemetry previously included the raw text is not stated; nothing has been read yet about how the `tengu_tui_optout_reason` gate itself is set.

**What**

When a user opts out of the new terminal interface (TUI) and types a reason, that reason is now submitted as a proper feedback description through Claude Code's feedback-submission system, with its own timeout and a cap on how many characters it will send. Only the length of the reason, plus a feedback ID if the submission succeeded, is then recorded to the `tengu_tui_optout_reason` telemetry event.

**Why**

Previously this kind of free-text reason risked going straight into raw analytics; routing it through the feedback pipeline instead means the actual text is handled like other user feedback, while telemetry only keeps a length and an ID.

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

### Comment-thread replies/resolves now special-case artifact pages that own their own threads

Claude now recognizes when an artifact page manages its own comment threads and stops retrying replies or resolves on it

**What**

When Claude tries to reply to or resolve a comment thread and the target page reports that it owns and manages its own comment threads, the tool now returns a specific message explaining this instead of a generic error. Claude is told this is expected and that retrying the action through the session's relay tool won't do anything.

**Why**

This prevents Claude from repeatedly retrying a comment action that can never succeed through this path, on pages that handle their own commenting separately.

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

### Model catalog fetch now reports a distinct 'credential cannot read served list' refusal

Model list now reports a specific reason when your credential can't fetch the served catalog

**What**

When Claude Code tries to fetch the current list of available models from the server and is refused specifically because the credential in use doesn't have permission to see it, a new handler now fires a `model_catalog_primary` telemetry event recording the decision as 'off' with the reason `credential_scope`, and prints a console note explaining that the built-in, compiled-in model list is being used instead.

**Why**

This makes it clearer, both to telemetry and to the user via the console note, why the served model list wasn't used and the fallback list is in effect, distinguishing it from other kinds of fetch failures.

- Area: Model Catalog
- Names: `credential_scope`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact create-from-type message wording changed from "icon" to "emoji"

Artifact creation notice now calls the default favicon an 'emoji' instead of an 'icon'

**What**

When creating an Artifact from a type and supplying extra fields that get ignored, the notice explaining that the favicon and description default to the type's own values now calls the favicon an 'emoji' rather than an 'icon'.

**Why**

This is a small wording fix so the message matches what that default value actually is.

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

### Comments listing summary text can omit the 'open' count

Artifact comments list header can now hide the 'N open' count and gains a new leading label

**Unclear.** The condition that suppresses the open count and the content of the new leading text are not specified.

**What**

The summary line shown at the top of an artifact's comments list can now leave out the "N open, " portion depending on a new condition, and the whole summary line now starts with a new leading piece of text.

**Why**

This changes what information appears at a glance in the comments list header, though the finding doesn't specify exactly when the open count is hidden or what the new leading text says.

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

### Hidden tabs_context_mcp lookup failure message now covers offline/asleep browser host

Browser tab-lookup timeout error now also suggests the browser's machine may be offline or asleep

**What**

When a hidden lookup used internally by `navigate` (`tabs_context_mcp`) times out waiting for a response, the resulting error message now also mentions that the machine running the Chrome extension's browser could be offline or asleep, in addition to the existing possibility that the extension itself was just slow to start.

**Why**

This gives a more accurate and actionable explanation when browser-based tools fail to respond, since a sleeping or disconnected machine is a distinct problem from a slow-starting extension and points toward a different fix.

- Area: Chrome & Browser
- Tier: You'll notice
- Useful: 1/5
- Signal: 0/5

### Background subagent progress-check instructions simplified to drop tool-based polling suggestion

Blocked duplicate subagent launches now only suggest messaging it for a progress update, not a separate polling tool

**What**

When Claude Code blocks launching a subagent because a duplicate is already running, the instructions it shows no longer mention checking on progress with a dedicated tool. They now simply suggest sending the running subagent a message via `SendMessage` if you need a progress report.

**Why**

This simplifies the guidance shown in this situation to a single, consistent way of checking on a running subagent's progress.

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

### Artifact fetch "ask" permission message wording changed from URL-fetch framing to artifact-read framing

The approval prompt for fetching a claude.ai artifact now describes it as reading the artifact, not fetching a URL

**What**

When Claude Code asks for permission to fetch a claude.ai artifact, the wording of the prompt changed. It previously said an existing "ask" rule covers fetching the URL; it now says the rule covers reading the artifact.

**Why**

The new wording more accurately describes what's actually happening (reading an artifact) rather than framing it as a generic URL fetch, which should make the permission prompt less confusing.

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

### Chrome bridge "Bridge received" debug logging now gated behind isDebugEnabled

Chrome bridge's verbose "Bridge received" debug log now only prints when debug mode is actually enabled

**What**

When Claude in Chrome's bridge receives a message it doesn't recognize, it used to always log the full payload (`Bridge received: ...`) for debugging. Now this logging only happens if debug mode is enabled; if there's no way to check, it defaults to still logging.

**Why**

This avoids dumping potentially large or sensitive message payloads to logs during normal use, restricting the verbose output to when debugging is actually turned on.

- Area: Chrome & Browser
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### New watch/artifact tool guidance: clean up opened tabs before finishing

Claude is now told to close any browser tabs it opened for a task before finishing

**What**

When Claude Code opens browser tabs as part of a task (via the tab-management tools), it now receives instructions telling it that those tabs are its own responsibility to close, using the `tabs_close_mcp` tool, once it no longer needs them and before finishing the task. This doesn't apply if you asked to see the tab or keep it open.

**Why**

This should reduce leftover, cluttering browser tabs left open after Claude Code finishes a task that involved browsing.

- Area: Chrome & Browser
- Names: `tabs_close_mcp`
- Tier: You'll notice
- Useful: 1/5
- Signal: 0/5

### '/rc' footer wording and status labels

Reconnect messages and status labels for /remote-control (/rc) got clearer, more specific wording

**What**

The message shown when a `/remote-control` (alias `/rc`) session is reconnecting changed from "...it'll appear in the footer shortly." to "...it'll show as `/rc` shortly." New, more specific status labels were also added: "/rc failed" (shown as an error), "/rc reconnecting" (shown as a warning), and "/rc active" (shown as success), replacing more generic footer wording.

**Why**

These clearer, `/rc`-specific labels make it easier to tell at a glance whether your Remote Control session (which makes a session available for control from claude.ai) is active, reconnecting, or has failed.

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

### Agent 'check output' guidance changed to 'send it a message'

Guidance for checking a background agent's output now says to send it a message instead

**What**

When a background agent (a task Claude Code has running in the background) is still in progress, the guidance text shown changed from "You can check its output using the [tool] tool" to "Send it a message with [tool] to retrieve its result."

**Why**

This changes how Claude is told to interact with a running background agent, framing it as sending a message rather than just checking output, which should make Claude use the tool the way it's actually meant to be used.

- Area: Background Agents
- Tier: You'll notice
- Useful: 1/5
- Signal: 0/5

### Artifact page-data publish emoji wording change

Artifact publish error message now says "emoji" instead of "icon" is kept when updating an existing artifact

**What**

When you try to publish page data for an artifact and Claude Code asks you to pass the existing artifact's URL to update it instead of creating a new one, the message now says the artifact's "emoji" is kept, where it previously said its "icon" is kept.

**Why**

This is a wording correction so the message matches what the artifact actually carries forward when it's updated.

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

## Bug Fixes

### SDK reinit now redelivers pending permission/dialog requests on full reinit too

SDK session reinit now resends pending permission and dialog requests even on a full reinit

**What**

When the Agent SDK's control protocol reinitializes a session and has to rebuild the full system prompt and response, it now also includes any pending permission requests and pending user dialog requests in that response. Previously this information was only resent on the lighter-weight reinit path, not the full one.

**Why**

This closes a gap where a full reinit could otherwise drop or lose track of permission and dialog requests that were still waiting for an answer, so consumers of the SDK see them either way.

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

### Command-suggestion suppression while browsing history now respects edits

Command suggestions no longer disappear when you edit a history entry while browsing past commands

**What**

While paging through your input history (previous commands you've typed), Claude Code suppresses command/prompt suggestions. Previously this suppression happened any time a history entry was selected. Now it only happens when the selected history entry hasn't been edited by you.

**Why**

If you pull up a past command from history and start editing it, you'll now get suggestions again as you type, instead of suggestions staying hidden just because you started from a history entry.

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

### Model list can now backfill served-catalog defaults when the active catalog source is a flag override

The model picker now fills in default models even when a flag override supplies the catalog

**What**

When Claude Code builds the list of models shown in the model picker, it can pull that list from different sources, including a 'flag' override. Previously, the built-in default catalog of models was only added to the list when there was no override at all. Now, even when a 'flag' override is the active source, the default catalog's models are still merged in.

**Why**

This means fewer cases where a flag-based override accidentally hides models that should still be available, since the default set now always backfills the list.

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

### Session-message cache priming now merges into an in-flight cache entry instead of skipping

Session-message cache priming now merges into an already-in-progress cache load instead of dropping the new data

**What**

When Claude Code primes its cache of session message UUIDs and a cache entry for that session is already being built, it used to simply skip the new priming request and do nothing further. Now it waits for the in-flight cache load to finish and merges the newly supplied UUIDs into the resulting set.

**Why**

This prevents UUIDs from being silently lost when two priming calls for the same session overlap, ensuring the cache ends up complete rather than missing entries that arrived while a load was already underway.

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

### setTimeout/setInterval globally proxied to clamp overflow delays

Claude Code now clamps overly long setTimeout/setInterval delays instead of letting them silently misbehave

**What**

Claude Code now wraps the global `setTimeout` and `setInterval` functions at startup so that any delay value greater than 2147483647 (Node.js's 32-bit limit for these timers) is automatically clamped down to that maximum before the timer runs. When a clamp happens, it logs a warning and, once per relevant case, records telemetry about it.

**Why**

Without this, a timer scheduled with too large a delay would silently fire almost immediately instead of after the intended wait, an easy-to-miss bug; clamping it and warning makes that situation visible instead of silent.

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

### 403 responses with oauth_scope_insufficient now classified as not_permitted

Insufficient OAuth scope errors are now classified distinctly instead of as a generic HTTP failure

**What**

When a server request fails with a 403 response whose body reports the error code `oauth_scope_insufficient`, Claude Code now recognizes this specifically and reports it as a `not_permitted` error rather than a generic HTTP status error. Fetching the list of available models also gained a shortcut: if this same condition is detected, it returns cached results immediately with reason `not_permitted` instead of retrying the network request.

**Why**

This avoids retrying requests that will keep failing for the same permission reason, and gives a more precise, actionable error when the current authorization doesn't have the required scope.

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

### Bash command-substitution parsing hardened against untrusted backtick/`$()` bytes

Bash command parsing now rejects unclear backtick or $() substitutions instead of guessing

**What**

The safety parser that analyzes bash commands before running them now specifically detects malformed or unaccounted-for backtick and `$()` command-substitution syntax, such as an empty or overrun backtick body, or an unsupported escape inside one. When it finds bytes in the command that its parse tree can't account for, it now downgrades the command to "too complex" instead of proceeding on a parse it can't fully trust.

**Why**

This closes a path where a command containing tricky or malformed substitution syntax could have been misread by the safety parser, by refusing to trust an uncertain parse rather than risk approving something incorrectly.

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

### Git URL validation now masks credentials in error messages

Git URL validation now masks embedded credentials before showing an invalid-URL error, with clearer messages for wrong schemes

**What**

The validator for SSH git URLs was reworked so that, when it rejects an invalid URL, it builds a masked copy of that URL before putting it in the error message: any embedded username/password (userinfo) is replaced with `***`, and query or fragment content is replaced with `***`. Errors about a mismatched protocol now also distinguish between a scheme that's simply spelled wrong and other kinds of malformed input, with more specific messages for each.

**Why**

This stops credentials that were accidentally embedded in a git URL from being echoed back in plain text inside an error message, while giving clearer feedback about why a URL was rejected.

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

### Rate-limit overage check now excludes 1M-context credit-clamp cases

Rate-limit errors caused by needing 1M-context credits now show the correct dedicated message instead of a generic overage one

**What**

When Claude Code hits a 429 rate-limit response, it decides whether to show an 'extra usage' (overage) message or a different one. That check now specifically excludes cases where the error is actually about needing 1M-context usage credits, so those get routed to the dedicated usage-credits message instead.

**Why**

This prevents a case where a 1M-context credit issue was being mislabeled as a generic overage-disabled error, which would have pointed users toward the wrong fix.

- Area: Rate Limits
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Plugin toggle confirmation now waits for in-flight changes before closing

Plugin manager now waits for pending enable/disable changes to finish before showing the closing reminder

**What**

When closing the plugin manager menu after toggling plugins on or off, Claude Code used to immediately show a reminder message. Now it tracks any enable/disable operations still in progress and waits for all of them to finish before showing that reminder.

**Why**

This avoids showing a misleading reminder before the actual plugin changes have completed.

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

### Skill descriptions reject angle brackets

Skill descriptions can no longer contain angle brackets

**What**

When creating or improving a saved skill (a packaged set of instructions Claude Code can invoke), the `description` field now fails validation if it contains angle brackets (`<` or `>`). A new error message tells the caller to reword the description without them.

**Why**

This catches a class of malformed or unsafe skill descriptions earlier, at creation time, instead of letting them through.

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

### SDK bridge permission_request/notification handling hardened

SDK bridge handles permission requests and malformed notifications more defensively

**What**

The SDK bridge (the layer that lets an external host application talk to Claude Code) now handles a few edge cases more carefully:

- Errors while handling a permission request are now caught and logged instead of crashing unhandled.

- Notification messages whose `method` field isn't a string are now dropped with a warning instead of being passed through.

- Permission request messages are now validated with proper type checks on their `tool_use_id` and `request_id` fields, fixing what looks like a latent bug where the check referenced an undefined variable and so never worked as intended.

**Why**

These changes make the SDK bridge more robust against malformed or unexpected messages, preventing crashes and silently-broken validation.

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

### Bridge error now clears device selection via clearSelectionIfGone instead of unconditional reset

Bridge errors now clear a selected device only if it's actually gone, not unconditionally

**What**

When the remote-control bridge reports an error while a device is selected, Claude Code now checks whether that device is still available (`clearSelectionIfGone`) instead of always clearing the current device selection and discovery state.

**Why**

This avoids unnecessarily dropping a valid device selection just because an unrelated bridge error occurred.

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

### Domain blocklist check gains cancellation via AbortSignal

Domain blocklist check can now be cancelled mid-flight instead of just timing out

**What**

The internal check that looks up whether a domain is blocklisted now accepts a cancellation signal. If the check is aborted, it re-raises the abort instead of silently treating it as a failed check, and a cleanup step now always runs afterward to clear its timer.

**Why**

This distinguishes a genuinely cancelled lookup from a failed one, and prevents leftover timers from lingering after the check finishes or is cancelled.

- Area: Sandbox Network
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### list_connected_browsers tool now respects an isDisabled check

The list_connected_browsers tool now checks if it has been disabled before running

**What**

The `list_connected_browsers` tool, which lists browsers connected to Claude Code, now checks whether it has been disabled before doing any work. If it's disabled, it immediately returns an "Unknown tool" message instead of proceeding.

**Why**

This prevents a disabled tool from doing any work or returning results, keeping it consistently unavailable when it's meant to be off.

- Area: Chrome & Browser
- Names: `list_connected_browsers`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Escape-key double-press 'absorb' logic gained a second qualifying window

Double-tapping Escape to interrupt now checks an additional timing window before deciding to absorb the keypress

**Unclear.** The finding does not say what practical difference this makes to when a keypress is absorbed versus passed through.

**What**

Claude Code's logic for handling a quick double-press of the Escape key (used to trigger an interrupt gesture) now also checks a second timer, tracking when the last qualifying press happened, against a defined time window. This is in addition to the existing checks it already used.

**Why**

This is an adjustment to the timing rules that decide whether a second Escape press counts as part of the same gesture, likely intended to make the double-press detection more accurate.

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

### Policy-block error detection extended to "required by your organization" phrasing

Organization policy-block detection now also matches "required by your organization" phrasing

**What**

Claude Code's check for whether a CLI error means an organization's policy blocked an action now also recognizes messages phrased as "required by your organization", in addition to the existing "blocked by your organization's policy" phrasing.

**Why**

This means more organization-policy error messages get correctly identified and handled as policy blocks rather than being treated as some other kind of failure.

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

### UI-close/render engine adds cross-instance requestId guard

UI rendering now rejects events with a requestId from a different session instance

**What**

The validator that checks arguments for `ui.render` events (used to draw interactive UI elements) now also rejects an event if its `requestId` doesn't match the specific instance the UI element was originally drawn in, returning an error about "a requestId other than the instance the element was drawn in". Separately, the logging for `ui.close` events now logs the event's `kind` rather than the raw event object.

**Why**

This prevents a UI event meant for one session or instance from being mistakenly applied to a different one, closing a potential cross-instance mix-up when multiple UI elements or sessions are active.

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

### Artifact read permission check for WebFetch now runs a deny check both before and after network egress probing

WebFetch's permission check for reading claude.ai artifacts now re-checks deny rules after probing network access

**What**

When WebFetch is used to read a claude.ai artifact, Claude Code now runs its deny-rule permission check a second time, after the step that probes network access and shows any consent surface, in addition to the check that already ran earlier. Only after this second check passes does the flow move on to handling ask rules.

**Why**

Running the deny check again after the network probe closes a gap where a deny rule might otherwise be missed if conditions changed between the first check and the actual network access.

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

### URL host parsing hardened against protocol-relative and scheme-prefixed strings

URL host parsing now rejects scheme-prefixed strings and strips whitespace before building fallback URLs

**What**

Before Claude Code builds a fallback `https://` URL out of a bare host string, it now checks whether that string already looks like it starts with a URL scheme (something like `foo:` at the start) and bails out if so, instead of blindly prepending `https://`. It also now strips tab, newline, carriage-return, and surrounding whitespace characters from the string before parsing it.

**Why**

This closes off ways a crafted host string could be misinterpreted as pointing somewhere other than intended, such as smuggling in a different scheme or hiding characters in whitespace.

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

### computer-use browser tools check isDisabled before acting

Computer-use browser tools now check if they're disabled before switching browsers or typing

**What**

The `switch_browser` computer-use tool, and the "type" action of the general computer-tool, now check whether they've been disabled before doing anything. If disabled, they return a response saying the tool is unknown instead of carrying out the action.

**Why**

Previously these two actions would attempt to run even when they should have been turned off; now they properly respect being disabled, closing a gap where a disabled tool could still act.

- Area: Chrome & Browser
- Names: `switch_browser`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Session-plugin load-failure messages now redact URL credentials, not just query strings

Plugin load-failure error messages now mask credential-looking URL segments, not just query strings

**What**

When a plugin loaded from a URL fails to load, the resulting error message used to only strip out query strings from that URL before showing it. Now a new helper scans the whole message for embedded URLs and also masks any segment that looks like it contains login credentials (matching an `@` sign next to quote or bracket characters), in addition to still stripping query strings.

**Why**

This reduces the chance that a plugin load-failure message accidentally displays a URL containing a username, password, or token.

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

### Session resume now carries session-start hooks across resume

Resuming a session now also restores its session-start hooks, not just its regular hooks

**Unclear.** The finding does not say what visible effect the missing field previously had, so it's unclear what behavior this fixes in practice.

**What**

When Claude Code resumes a previous session, it rebuilds the session's pending hook messages. This restoration now includes a `sessionStartHooks` field alongside the existing `sessionHooks` field, which was previously missing from the restored session data.

**Why**

Hooks that are meant to run at session start can now carry over correctly when a session is resumed, rather than being silently dropped.

- Area: Sessions
- Names: `sessionStartHooks`
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Pricing-override validator now accounts for non-admin upstream priority

Gateway's pricing-override warning now accounts for which upstream actually serves a model

**What**

The Claude Code Gateway's check for pricing overrides that could never actually take effect was updated: when there's no admin/meter configuration in play, an override is now only treated as reachable if it sits on the first upstream server that would actually serve that model.

**Why**

This avoids false warnings (or missed ones) about dead pricing overrides in setups without an admin/meter block, by correctly accounting for upstream priority order.

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

### Plugin skill/monitor path checks now surface unreadable-path errors instead of silently treating them as absent

Plugin loading now reports unreadable SKILL.md or monitors.json paths instead of treating them as missing

**What**

When Claude Code checks whether a plugin has a `SKILL.md` or `monitors.json` file, it previously used a simple yes/no check. Now it uses a three-way check: present, absent, or unknown (for example, when a permission error prevents checking). When the state can't be determined, Claude Code now logs a message noting the plugin and path that could not be checked and records a `path-not-found` diagnostic, rather than silently treating it as if the file didn't exist.

**Why**

This makes it clearer when a plugin fails to load because of a permissions or filesystem problem, rather than looking like the plugin simply doesn't have that file, matching how `hooks.json` loading already behaved.

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

### Datadog model-sanitization now runs on any defined model value, not just strings

Datadog telemetry now sanitizes any defined model value, not just string ones, dropping events it can't sanitize

**What**

In the internal Datadog telemetry pipeline, the step that checks and cleans up the `model` field before sending an event used to only run if the model value was a text string. Now it runs whenever the model value is defined at all, including cases where it is something else, like a number or `null`. If the value can't be recognized as a known model, the entire telemetry event is now dropped rather than being sent with an unrecognized or malformed model field.

**Why**

This prevents malformed or unexpected model values from being forwarded in telemetry data, at the cost of silently dropping the whole event when the model field isn't a recognizable string.

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

### Remote-served model catalog can now merge dynamic models when catalog source is "flag"

The model picker can now merge in extra dynamic models when the model catalog is being served via a flag

**What**

When Claude Code is using a remotely served list of available models and that list's source is reported as "flag", the model-option builder now also merges in any additional model entries that aren't already present in the served list.

**Why**

This lets a flag-driven model catalog be supplemented with extra models rather than being treated as the complete list, so new or experimental models can show up in the picker without replacing the whole served catalog.

- Area: Model Catalog
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Truncating quoted text now avoids splitting curly-quote pairs mid-way

Truncated quoted text no longer cuts a curly-quote pair in half

**What

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

### Prompt-suggestion acceptance matching is now case-insensitive

Matching your reply to a suggested prompt is now case-insensitive

**What**

When Claude Code checks whether what you typed matches a prompt it suggested (used for `tengu_prompt_suggestion` telemetry), it now compares the two strings case-insensitively instead of requiring an exact match.

**Why**

This means typing a suggested prompt back with different capitalization still counts as accepting the suggestion, giving more accurate telemetry about when suggestions are actually used.

- Flag `tengu_prompt_suggestion`: Not enough to say (read for one account on one subscription tier against v2.1.268; this account: no value returned, anonymous baseline: on, compiled default: not a boolean we can read)
- Area: Elsewhere
- Tier: You'll notice
- Useful: 1/5
- Signal: 0/5

### CLI login OAuth-failure output gains a conditional extra newline

Login failures over OAuth may now print an extra blank line before the error

**Unclear.** What condition triggers the extra newline, and which login failure cases it affects, is not specified.

**What**

When `/login` fails during the OAuth (the sign-in protocol Claude Code uses to authenticate with your Anthropic account) step, Claude Code now checks a condition before printing the "Login failed" message to the terminal's error output, and if it's met, writes an extra blank line first. The internal error-classification helpers used here were also renamed.

**Why**

This is a small formatting fix intended to make failed-login output easier to read in the cases where the extra line is triggered.

- Area: Auth
- Names: `/login`
- Tier: You'll notice
- Useful: 1/5
- Signal: 0/5

### Bug fix: wrong exception object interpolated into connected-client wiring error

Fixed a bug where connected-client wiring errors logged the wrong exception

**What**

In the code path that adopts a connected MCP client, an error message logged when wiring fails previously referenced an unrelated variable instead of the actual exception that was caught. It now correctly logs the real caught error.

**Why**

This makes the "connected-client wiring failed" log message actually useful for diagnosing what went wrong, since it now shows the real error instead of an unrelated value.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Bug fix: malformed AskUserQuestion entry message stringified the wrong value

Fixed a bug where a malformed AskUserQuestion entry's error message showed the wrong value

**What**

When `AskUserQuestion` receives input containing a question entry that isn't a properly formed object, the diagnostic message shown now correctly stringifies the actual malformed entry, instead of an unrelated variable left over from an outer loop.

**Why**

This makes the "[malformed question entry]" diagnostic actually show the problematic data, making it easier to see what was wrong with the input.

- Area: AskUserQuestion
- Tier: You'll notice
- Useful: 1/5
- Signal: 0/5

## In Development

### New gated sandbox-boundary system-prompt text (tengu_elegant_ocean)

New system-prompt text explains the sandbox's boundaries to the model, gated behind an unread flag

**Unclear.** Whether this gate is enabled for any accounts is unread; it isn't known when or for whom this sandbox explanation appears.

**What**

A new block of instructional text can be added to the system prompt that explains, in detail, what the sandbox (the restricted environment a session runs in) does and does not give access to: which directories, which network destinations, and which credentials are available. It tells the model to report when something it needs is missing rather than try to work around the sandbox's limits.

**Why**

This is controlled by a gate called `tengu_elegant_ocean`, and nothing is yet known about whether or how it is being turned on for any account, so it isn't possible to say whether or when this text is currently shown.

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

### New coordinator_context / context_sections message attachments, gated behind tengu_indexed_corbato

Conversations can now carry coordinator/worker context and named context sections, behind an unreleased gate

**Unclear.** Whether this is switched on for any account is unknown; the `tengu_indexed_corbato` gate controlling it has not been read.

**What**

Claude Code's conversation-building internals gained two new kinds of message attachment: `coordinator_context`, which injects a worker's tool context into a coordinator's conversation, and `context_sections`, a list of named text sections. The `coordinator_context` injection only happens when a new internal check allows it.

**Why**

This looks like groundwork for passing more structured context between a coordinating agent and the workers (subagents) it manages, though the feature is not confirmed to be active yet.

- Flag `tengu_indexed_corbato`: Not enough to say (read for one account on one subscription tier against v2.1.268; this account: no value returned, anonymous baseline: no value returned, compiled default: off)
- Area: System Prompt
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### Tool-additions mid-conversation tether reset gated by tengu_lucid_anchor

Adding tools mid-conversation can still force a session reset, gated by an unread flag

**Unclear.** Nothing has been read yet about how the `tengu_lucid_anchor` flag is set for any account, so it's unknown whether resets are currently being forced or avoided.

**What**

When tools are added partway through a conversation, Claude Code's server-side continuation planner decides whether to keep using the same underlying thread or reset and start a new one. A new check now controls this: if a flag called `tengu_lucid_anchor` is off, adding tools mid-conversation still forces the thread to reset rather than continue.

**Why**

This means whether tool additions can continue smoothly in the same thread, instead of forcing a reset, currently depends on this flag's setting.

- Flag `tengu_lucid_anchor`: Not enough to say (read for one account on one subscription tier against v2.1.268; this account: no value returned, anonymous baseline: no value returned, compiled default: off)
- Area: Conversation Threading
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 3/5
- Present in the build but not switched on

### New canned deny path for allowed_domains network classification, gated behind tengu_flickering_rain

A new gated shortcut can deny network access to hosts outside a command's allowed_domains without running the full classifier

**What**

When classifying whether a command may reach a given network host, Claude Code can now skip the full classifier and immediately deny access with the message "not in this command's allowed_domains — re-run the command with this host listed if it needs it", if a specific condition is met and it isn't an auto-mode-classifier case. This shortcut is controlled by a new internal gate tied to `tengu_flickering_rain`.

**Why**

This can make denials for out-of-list hosts faster and more predictable by short-circuiting the classifier, but whether it is active for a given account cannot be determined from this release.

- Area: Sandbox Network
- Names: `allowed_domains`
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 3/5
- Present in the build but not switched on

### Teleport-relay thinking-strip decision functions built but uncalled

New but currently unused code was added to decide how to handle 'thinking' content after a teleport relay reverts

**Unclear.** What the teleport relay feature does overall, and when the unused functions are meant to be wired in, is not stated.

**What**

Four new internal helper functions were added to decide whether to strip or mark 'thinking' content (Claude's intermediate reasoning output) after a "teleport relay" falls back to its standard path, and to log a `cli_teleport_relay_thinking_settled` event when that decision is made. Of these, only one function, which triggers the relay reverting to the standard path, is actually called anywhere in the current build; the three functions that would make the strip/mark decision and log the settle event are not called from anywhere.

**Why**

This appears to be groundwork for a feature that is not active yet, so it should have no visible effect for users in this release.

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

### New CCR worker flags: event-hold and drop-unwatched-stream-events

Two new remote flags control telemetry event-holding and dropping unwatched stream events

**What**

Two new remotely-configured flags were added to the relay worker that handles telemetry and streaming:

- `eventHoldEnabled`, on by default, which is what turns on the new server-served telemetry holding behavior

- `dropUnwatchedStreamEvents`, off by default, which drops stream events entirely when nothing is subscribed to watch them

**Why**

These give server-side control over telemetry batching and stream event handling without needing a client update, letting Anthropic tune this behavior remotely.

- Flag `tengu_ccr_event_hold_enabled`: Not enough to say (read for one account on one subscription tier against v2.1.268; this account: no value returned, anonymous baseline: no value returned, compiled default: on)
- Flag `tengu_ccr_drop_unwatched_stream_events`: Not enough to say (read for one account on one subscription tier against v2.1.268; this account: no value returned, anonymous baseline: no value returned, compiled default: off)
- Area: Telemetry
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 2/5
- Present in the build but not switched on

### New bash-command classification added to tool telemetry, gated behind an enhanced-telemetry beta flag

Bash tool telemetry now breaks commands into class, program name, subcommand, and pipe usage, behind a beta flag

**What**

When a Bash tool call runs, Claude Code now parses the command into structured parts: a class, the program being run (`argv0`), a subcommand, and whether it uses a pipe (`has_pipe`). This breakdown is attached both to an internal `tool.output` event and to the `tengu_tool_use_success`/`tengu_tool_use_error` analytics events. The feature sits behind an enhanced-telemetry beta flag.

**Why**

This gives more structured visibility into what kinds of bash commands are being run, without exposing full command text, for analytics purposes tied to the beta flag.

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

### PR/bridge status line gated by tengu_copper_thistle (defaults off)

A combined bridge status and PR/branch segment in the status line is now gated behind tengu_copper_thistle

**Unclear.** Whether or how this segment will actually appear once the gate is enabled is not established.

**What**

The footer status line (the small bar showing session info at the bottom of the terminal) has code that decides whether to show a combined segment for bridge status together with pull-request/branch info, controlled by the `tengu_copper_thistle` setting.

**Why**

This lets Claude Code turn the combined display on or off for different accounts without a new release. The setting reads off for both this site's account and the general default, so this combined segment is not expected to appear yet.

- Flag `tengu_copper_thistle`: Not enough to say (read for one account on one subscription tier against v2.1.268; this account: no value returned, anonymous baseline: off, compiled default: off)
- Area: Status Bar
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 2/5
- Present in the build but not switched on

### Artifact publish gets a new (currently disabled) 'ldx_unsupported' 400 response path

Artifact publishing adds a currently-inactive error path for an 'ldx_unsupported' response

**What**

Artifact publishing now has a code path to specifically detect and report an "ldx_unsupported" condition when the server returns an HTTP 400 error. However, the check that would trigger this path is currently a stub that always returns false, so it has no effect yet.

**Why**

This appears to be groundwork for a future feature; it doesn't change any current behavior since the gating check is disabled.

- Area: Artifacts
- Names: `ldx_unsupported`
- Tier: Nothing to try yet
- Useful: 1/5
- Signal: 2/5
- Present in the build but not switched on

### Background-monitor guidance changes wording when an experimental re-arm flag is on

Background-monitor guidance text can now mention re-arming instead of saying notifications run indefinitely

**What

- Flag `tengu_breezy_crescent`: Not enough to say (read for one account on one subscription tier against v2.1.268; this account: no value returned, anonymous baseline: off, compiled default: off)
- Area: Monitor Tool
- Tier: Nothing to try yet
- Useful: 1/5
- Signal: 2/5
- Present in the build but not switched on

## Internal Changes

### Session resume reworked to compute session-start hooks asynchronously, plus partial-history resume support

Session resume now computes startup hooks asynchronously and can resume from just part of a session's history

**What**

The startup path used to receive `hookMessages`/`hooksPromise` directly. Now, resuming or forking a session returns a `sessionStartHooks` promise instead, wired through a new abortable queue. Resume also gains a `precedingRows` option, letting a caller resume a session starting from a subset of its prior transcript rows rather than replaying the whole session history.

**Why**

Computing session-start hooks asynchronously and abortably makes startup more resilient to slow or cancelled hook execution, and being able to resume from a partial history opens the door to resuming sessions without always replaying everything that came before.

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

### Prompt-time model-id remapping ("breezy_horizon") gets stricter validation and a self-mapping warning

Model-id remapping via CLAUDE_CODE_BREEZY_HORIZON now validates ids more strictly and warns on no-op mappings

**What**

The mechanism that lets a model id be substituted for another before a prompt is sent (driven by the `CLAUDE_CODE_BREEZY_HORIZON` environment variable or server-supplied config) now validates candidate model ids more precisely. It also warns distinctly when a mapping's target is the same model it's meant to replace, reporting that the mapping "maps nothing," instead of silently treating it as a no-op.

**Why**

This makes a misconfigured or pointless model-id mapping visible as a warning instead of failing silently, making it easier to notice when a substitution rule isn't actually doing anything.

- Area: Model Routing
- Names: `CLAUDE_CODE_BREEZY_HORIZON`
- Tier: Under the hood
- Useful: 2/5
- Signal: 3/5

### CCR event-upload holding reworked around a server-driven "flush policy", with a kill switch

Claude Code's telemetry uploader now follows a flush policy sent by the server, with a switch to turn holding off

**What**

The part of Claude Code that batches up telemetry events before sending them ('CCR') was reworked. It now accepts a flush policy from the server, via a new `takeUpFlushPolicy` mechanism, that can set the maximum number of events to hold, the maximum age or byte size before sending, whether to flush right when sampling ends, and which event types must always be flushed. Adopting, changing, or clearing this policy is logged (`cli_ccr_flush_policy_adopted`, `cli_ccr_flush_policy_changed`, `cli_ccr_flush_policy_cleared`), and a malformed policy from the server logs a `cli_ccr_flush_policy_unreadable` warning.

There is also a new `eventHoldEnabled` switch that can turn off event-holding entirely, logging `cli_ccr_event_hold_switched_off` when it does. Hold decisions are now tracked separately depending on whether they come from a server-provided policy or from a local flag with no active subscriber.

**Why**

This gives the server more control over how Claude Code batches and sends its own diagnostic events, and gives the client a documented way to fall back to unheld sending if the policy can't be understood or needs to be disabled.

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

### Model access deny caching reworked into a 'reprobe' system with contested-deny tracking

Claude Code can now re-check a cached 'model access denied' result instead of trusting it forever

**Unclear.** Whether this reprobe behavior is active for any given user is unread, since the gate `tengu_session_model_cached_deny_reprobe` has no recorded reading.

**What**

When Claude Code decides a model isn't accessible, it caches that denial so it doesn't have to check again right away. This caching logic has been rewritten so that a cached denial can now be flagged as contested and re-verified in the background (a 'reprobe'), and that reprobe can overturn the original denial if it turns out access is actually fine.

**Why**

This guards against a stale or wrong 'access denied' result getting stuck for a session, since the system can now quietly double-check and correct itself.

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

### New desktop-surface plugin UI messaging (ui.message / ui.press / ui.input / ui.select)

New plugin UI plumbing routes ui.message and press/input/select events to a desktop app surface

**Unclear.** What specific desktop client or surface consumes these dispatched events isn't detailed in the evidence.

**What**

Two new internal functions dispatch plugin-authored UI events, including `ui.message` and press/input/select events, to a message target marked as `surface: "desktop"`. Before dispatching, they check whether the relevant UI component (`Q4.isDrawn`) is actually drawn, and log a message noting 'nothing ran' when it isn't.

**Why**

This appears to add the plumbing needed for plugin-driven UI events to reach a desktop client interface, separate from the terminal-based UI, though what desktop surface consumes these events isn't detailed in the evidence.

- Area: Plugins
- Names: `ui.message`, `ui.press`, `ui.input`, `ui.select`
- Tier: Under the hood
- Useful: 2/5
- Signal: 3/5

### Model-access cached-deny reprobe before demoting a model

Claude Code now double-checks with the server before demoting a model it thinks was denied

**What

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

### New 'coordinator_context' and 'context_sections' system-prompt injectors

System prompts gain new coordinator and context-section injectors, and prior suppression of several was removed

**Unclear.** The `tengu_indexed_corbato` gate mentioned alongside this change has not been read, so nothing is known about its current state or exactly which part of this change it governs.

**What**

Claude Code builds part of its system prompt (the hidden instructions sent alongside a request) from a set of 'injectors' that each add a specific block of context. Two new injector types have been added:

- `coordinator_context`, which lists available worker tools when running in a coordinator or multi-agent mode

- `context_sections`, which adds arbitrary named text sections

Separately, a condition that previously could suppress the environment, model, output style, session context, instructions, date, and language injectors entirely has been removed, so those now always run.

**Why**

Removing the suppression condition means the system prompt more consistently includes context like the current date, environment, and session details, rather than sometimes dropping it. The new injectors support coordinator/multi-agent setups and let arbitrary named context be attached to a prompt.

- Flag `tengu_indexed_corbato`: Not enough to say (read for one account on one subscription tier against v2.1.268; this account: no value returned, anonymous baseline: no value returned, compiled default: off)
- Area: System Prompt
- Tier: Under the hood
- Useful: 2/5
- Signal: 3/5

### Model access checks now do a live entitlement re-probe before blocking

Blocked model access now triggers a live re-check with the server before finalizing the block

**What**

When Claude Code blocks access to a model, the block result now carries an `underEnforcement` flag. During a model switch, if a model was previously denied, Claude Code now calls a new helper that re-probes the server (with a time limit and a forced fresh check) to see whether that denial has since been overturned, before finalizing the block. If this re-check itself fails, that's tracked separately (`entitlement_probe_failed`) from an outright access denial (`not_allowed`). The same re-probe is also used when restoring a session's previous model on resume: if that model was declined for being `not_allowed`, Claude Code awaits the re-probe before deciding whether to actually overturn the decline, and logs the outcome as `entitlement_reprobe` alongside the existing decline reason and EAP (early access program) status.

**Why**

This prevents a stale or outdated "not allowed" decision from permanently blocking a model that a user's account has since been granted access to, giving Claude Code a chance to catch up with the current entitlement state before refusing or restoring a model.

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

### New session-scoped model deny/reprobe tracking state

Session state now tracks which models were denied, retried, or contested with a new sessionModelDenyReprobe object

**Unclear.** The finding does not say what user-visible behavior this bookkeeping change produces.

**What**

Claude Code now keeps a new piece of per-session state called `sessionModelDenyReprobe`. It tracks whether a reprobe (a recheck of whether a model is usable) is underway, which models have been confirmed usable, which denials are contested, which models were refused, a generation counter, and whether access is currently restricted. This replaces two older fields, `lastGoodAntOverrideConfig` and `antCapabilitiesByModelId`.

**Why**

This is internal bookkeeping for how Claude Code decides which models are available to use during a session, likely making it more reliable at detecting and recovering from a model being denied or becoming unavailable partway through.

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

### New "auto mode" diagnostic snapshot function sEt()

A new internal function assembles a full diagnostic snapshot of Claude's "auto mode" state

**Unclear.** What "auto mode" itself does is not described in this finding.

**What**

A new internal function builds a combined diagnostic snapshot describing the state of Claude's "auto mode." It reports whether auto mode is available, why it might be unavailable, whether it's disabled by a settings or policy source, whether it's disabled by trusted policy, its current enabled state and where that state came from, whether its circuit breaker has tripped, the default permission mode, and whether it fell back to something else.

**Why**

This consolidates several separate pieces of auto-mode state into one diagnostic view, which should make it easier to understand or troubleshoot why auto mode is or isn't active in a given session.

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

### Headless remote-control fork now tracks a fork_seed_sha256

Headless remote-control sessions now record a fork_seed_sha256 identifier in session metadata

**Unclear.** The finding shows the metadata field being written but not what consumes fork_seed_sha256 or remoteControlForkChild or why.

**What**

The headless mode (started with the `-p` flag) that supports remote control forking now includes a helper that writes a `fork_seed_sha256` value into the session's internal metadata when given an SDK URL and credentials, and threads a `remoteControlForkChild` value through its streaming loop.

**Why**

This appears to be internal bookkeeping to identify and track forked remote-control sessions, though the finding doesn't specify exactly how this identifier is used downstream.

- Area: Remote Control
- Names: `fork_seed_sha256`
- Tier: Under the hood
- Useful: 2/5
- Signal: 3/5

### 'projectsUserTurn' flag added alongside verifiedSlackHumanTurn throughout turn-origin plumbing

A new projectsUserTurn flag now tags turns alongside the existing verifiedSlackHumanTurn flag

**Unclear.** What user-facing behavior, if any, currently depends on the projectsUserTurn flag is not stated.

**What**

A new internal flag called `projectsUserTurn` is now carried alongside the existing `verifiedSlackHumanTurn` flag through the same internal machinery: message comparisons, saving and loading a turn, and restoring queued notifications. It gets set to true when a verified human message relayed into Claude Code comes from what the system identifies as a "projects user."

**Why

This is internal bookkeeping that lets Claude Code distinguish turns coming from projects users from other relayed human turns; the finding doesn't say what user-facing behavior depends on it yet.

- Area: Projects
- Names: `projectsUserTurn`
- Tier: Under the hood
- Useful: 2/5
- Signal: 3/5

### New permission-request fields: defaultToNo and suppressAlwaysAllowRule

Permission requests now carry defaultToNo and suppressAlwaysAllowRule fields from the server

**Unclear.** What specifically triggers suppressAlwaysAllowRule to be set is not stated.

**What**

Permission requests (the prompts Claude Code shows before running a risky action) can now include two new pieces of information sent from the server: `defaultToNo`, and `suppressAlwaysAllowRule`. The second one is passed on internally as `askSuppressesAlwaysAllowRule` so that other parts of the code can check whether a given permission ask should skip offering an "always allow" rule.

**Why**

This lets the server mark certain permission prompts as ones where you shouldn't be offered a blanket "always allow" option, presumably for actions considered too sensitive to auto-approve going forward.

- Area: Permissions
- Names: `defaultToNo`, `suppressAlwaysAllowRule`
- Tier: Under the hood
- Useful: 2/5
- Signal: 3/5

### New bypass-immune classifier category: denyRulesUnjudged

A new denyRulesUnjudged permission category bypasses classifier judging but still can't be bypassed by rules

**Unclear.** Which specific deny rules or actions fall under denyRulesUnjudged is not stated.

**What**

A new category called `denyRulesUnjudged` has been added to Claude Code's internal permission configuration, alongside existing categories like `isolatePeerMachines`, `restrictedMode`, and `outsideReadsBlocked`. It's marked as "bypass-immune" (meaning permission-bypass settings can't skip it) but not "classifier-routed" (meaning it isn't decided by the automatic safety classifier).

**Why**

This adds a class of deny rules that always gets enforced directly rather than routed through the classifier, and that can't be sidestepped by bypass settings, though the finding doesn't specify which actions this new category actually covers.

- Area: Permissions
- Names: `denyRulesUnjudged`
- Tier: Under the hood
- Useful: 2/5
- Signal: 3/5

### Print-mode resume gains cloud-session fork seed adoption and a hydration pass

Print-mode session resume can now pick up where a forked cloud session left off

**What**

When resuming a session with `--print --resume`, Claude Code can now adopt a 'seed' from a cloud session fork (identified by a `fork_seed_sha256` value) via `remoteControlForkChild.adoptSeed`. The rows from that seed are fed into the session as preceding history, and a new filtering step keeps already-adopted rows from being duplicated in the loaded transcript. A new normalization pass also runs over the loaded session data before existing checks are applied.

**Why**

This lets a `--print --resume` session properly continue history that originated from a forked cloud session, rather than losing or duplicating that context.

- Area: Sessions
- Names: `--print --resume`, `fork_seed_sha256`
- Tier: Under the hood
- Useful: 2/5
- Signal: 3/5

### New internal-model-safeguards skip tracking flags added to session state (no visible call site in this slice)

Session state gained two new tracking flags for internal-model-safeguards skip refusals, not yet wired to any visible behavior

**Unclear.** What "internal model safeguards skip" refers to and how these flags get triggered or used is not shown.

**What**

Claude Code's internal session-state class gained two new boolean flags, each with a getter and a setter: one tracking whether an "internal model safeguards skip" was refused, and one tracking whether that refusal was announced. No code that actually sets or reacts to these flags is visible yet.

**Why**

The finding doesn't show what triggers these flags or what they'll be used for, so their practical effect isn't yet apparent from this change alone.

- Area: Model Safeguards
- Tier: Under the hood
- Useful: 1/5
- Signal: 3/5

### Remote-session org-policy denials now emit telemetry

Blocked remote-session actions from org policy now emit a tengu_org_policy_denied telemetry event

**What**

When an organization's policy blocks a remote or cloud-session action, such as running `/ultrareview` or resuming a session with `--print --teleport`, Claude Code now records a `tengu_org_policy_denied` telemetry event. The event carries which policy setting caused the block (`org_policy_key`), the kind of denial (`org_policy_deny_kind`), and where it happened (`surface`: `slash_command` for `/ultrareview`, `cloud_session` for teleport). A related check also fires for blocked `--environment`/remote-session or `/login` remote-control flows, naming the specific policy (`allow_remote_sessions` or `allow_remote_control`) with reason `cli_flag`.

**Why**

This gives organizations and support staff visibility into when and why a policy is blocking a user's action, rather than the block happening silently apart from an on-screen error.

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

### New pure-JS zip reader added

Claude Code adds its own pure-JavaScript zip file reader for extracting entries like MCPB packages

**What**

A new, self-contained zip-file parser was added, handling local file headers, the central directory, the end-of-central-directory record, Zip64 (for large archives), and both stored and deflate-compressed entries. It exposes a function that reads a zip file's contents into a map of entry names to their raw bytes, and is used for extracting entries such as those from MCPB packages.

**Why**

This gives Claude Code its own zip-reading code for unpacking archives like MCPB packages, rather than relying on some other mechanism for that job.

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

### Large expansion of the internal telemetry event-name catalog (Rne) plus new gate-name validators

Claude Code's internal telemetry catalog gained hundreds of new event names plus stricter permission-rule-name validation

**What**

Claude Code's internal list of telemetry and event identifiers has grown substantially, now covering areas like agents, artifacts, the bridge, ccr, MCP, sandboxing, self-hosted runners, and workflows. Alongside this, new internal constants define standard event sources (`slash_command`, `cli_flag`, `startup`, `tool`, `dispatch`, `cloud_session`) and denial reasons (`org_denied`, `cache_miss`, `route_missing`), and a new pattern now requires permission rule names to start with `allow_` followed by lowercase letters, numbers, or underscores.

**Why**

This is mostly internal bookkeeping that expands what Claude Code can track and validate; the permission-rule-name pattern in particular tightens what counts as a valid rule name.

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

### Bash tool telemetry gains detailed shell-command shape fields

Bash tool telemetry now records a detailed breakdown of each command's shape

**What**

The telemetry events fired when a bash command succeeds (`tengu_bash_tool_command_executed`) or fails (`tengu_bash_tool_command_failed`) now include a much richer breakdown of the parsed command, on top of the existing `command_type` field:

- the command's class and its first argument (`argv0`)

- the last command's `argv0` in a chain

- whether it used pipes, redirects, chains, subshells, or heredocs

- a count of simple commands within it

**Why**

This gives more detailed visibility into the structure of bash commands being run, which can help with understanding usage patterns and diagnosing issues, though the underlying `tengu_bash_tool_command_executed` and `tengu_bash_tool_command_failed` gates have no recorded reading yet.

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

### Artifact publish results can include a new "ldxBuild" segment for live docs

Publishing an artifact or live doc can now include a new 'ldxBuild' build step in its result

**Unclear.** What the ldxBuild segment displays to the user or what triggers it is not stated.

**What**

When Claude Code publishes an artifact (a generated file or live document), the result can now include a new `ldxBuild` segment reflecting a build step that runs after publishing, alongside the existing step that links newly created working copies.

**Why**

This lays groundwork for reporting build status on live documents as part of the publish flow, though the finding doesn't say what visible effect it has yet.

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

### Transcript reconstruction gains a 'precede' pass to stitch pre-context entries onto later ones

Transcript rebuilding gets a new 'precede' pass that reconnects orphaned entries to prior context

**What**

When Claude Code reconstructs a conversation transcript, it now runs an extra pass called `precede` over a batch of entries first. This pass remembers the last relevant entry it saw, and if a later entry in the main conversation (not a side branch) has no recorded parent, its parent is retroactively set to that remembered entry, unless it's already anchored some other way.

**Why**

This stitches transcript entries back together that would otherwise appear disconnected from their preceding context, likely improving how conversation history is displayed or replayed.

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

### Artifacts tool tracks unverified path spelling

Publishing an artifact now checks its file path for disguised or lookalike spelling

**What**

When the artifacts tool resolves the file path for something being published, its result now includes a new `unverifiedSpelling` field alongside the existing pin and redirect information. This points to the same check for obfuscated or disguised path names already used elsewhere (such as when registering a repository root) now also being applied to files being published as artifacts.

**Why**

This helps catch cases where a published artifact's path looks legitimate but uses a disguised spelling, closing a gap between two features that previously applied this check inconsistently.

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

### Teleport relay fallback is now scoped per attempt, with reconciliation if the standard path served a request the relay skipped

Claude Code now notices and corrects when its network relay skipped a request the normal path ended up serving

**What**

Claude Code has an internal relay for streaming requests, used when a session is being handed off between machines (teleportation). Previously, whenever this relay failed, it just fell back to the normal request path and logged that the relay stayed 'armed' (ready to try again). Now each failure is recorded with its reason, and the fallback request goes through the normal path as before. If that normal-path request succeeds while the relay still thinks it's active, Claude Code logs a warning that the normal path served a request the relay didn't take, and disarms the relay accordingly.

**Why**

This keeps the relay's own idea of whether it's active in sync with what actually happened, so it doesn't keep believing it's handling requests it's actually missing.

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

### Transport now tracks resultDelivery for numbered results

Session transport now tracks a resultDelivery object so 'result' messages can be numbered

**Unclear.** What actually consumes the numbered results, and why numbering was needed, isn't shown in the evidence.

**What**

At startup, Claude Code now wires a new `resultDelivery` object onto the session's transport layer. It's used to stamp outgoing 'result' type messages so they can be delivered with a sequence number, and a separate counter reads that number back off `resultDelivery` elsewhere.

**Why**

Numbering result messages likely helps consumers of the session transport track ordering or detect gaps in delivered results, though the evidence doesn't spell out the specific consumer.

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

### Model catalog schema gains effort-level, family, and image-limit metadata

Model catalog metadata now also includes image size limits alongside its existing effort and family fields

**What**

The schema used to describe models in the catalog now also accepts `image_limits`, with `max_width` and `max_height` fields, in addition to the `effort_levels`, `default_effort`, `capabilities`, `family`, `knowledge_cutoff`, `default_for_family`, and `fast_default_for_family` fields it already carried.

**Why**

This lets the model catalog record per-model image size limits alongside the effort and capability metadata it already tracked, supporting more accurate handling of image inputs per model.

- Area: Model Catalog
- Names: `image_limits`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Stream-event flush policy reworked around a 'served_policy' hold rule and unwatched-stream dropping

Stream event uploads now hold under a 'served_policy' rule and can drop events nobody is watching

**What**

The internal logic that decides when to flush (upload) streamed events now tracks a specific reason for each flush: round trip completion, a discrete event, or the end of sampling. It can also hold events under a new 'served_policy' regime that only flushes once sampling ends, and it can drop ephemeral stream events entirely, without uploading them, when nothing is actively subscribed to watch that stream. Dropped events are now counted in a new telemetry field, `stream_events_dropped_unwatched`.

**Why**

This reduces unnecessary uploads of streaming data that no one is consuming, while still tracking, via telemetry, how many events were skipped this way.

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

### Session-refresh context restructured into flattened sections list

Session-refresh context now builds a flat list of named sections instead of separate user/system context blobs

**Unclear.** What the workerTools field is used for, and what condition gates it, is not stated.

**What**

When a session is resumed, Claude Code refreshes its context (the background information given to Claude, split into user context and system context) before continuing. That refresh now builds a single flattened list of `{name, text}` sections merged from both sources, keeping a special cache-tracking key separate rather than mixed in. The refresh also gained a `workerTools` field that only appears under a certain condition, and if the refresh hits an error, it now explicitly marks the result as bare (minimal) context instead of quietly reusing old, possibly stale context.

**Why**

This is an internal restructuring of how resumed sessions rebuild their context. The main practical effect for users is the error-handling fix: if something goes wrong while refreshing context on resume, Claude Code no longer silently continues with outdated context, it explicitly falls back to a minimal, known state.

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

### Governed-git sessions can now carry a push base URL and direct-upstreams list

Governed-git runner sessions can now be configured with a push base URL and a list of direct upstream repos

**What**

Governed-git runner sessions (a controlled way of running git operations) can now be configured with a push base URL, read via a new helper. They can also be given a list of "direct upstreams" - repositories to treat directly rather than through the usual proxying - when the git mount's URL structure supports it.

**Why**

If a direct-upstreams list is supplied but the git mount's URL shape can't support keeping it as a session remote, Claude Code now warns that every source will instead be reset back to its normal upstream URL after setup. This avoids silent misconfiguration where a requested direct-upstream setup wouldn't actually be honored.

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

### Feedback survey follow-up submission simplified, drops explicit policy/first-party pre-checks and adds char-capped description

Feedback survey follow-up submission drops some pre-checks and now caps and can cancel description text

**Unclear.** Whether the dropped policy and telemetry checks were moved elsewhere or simply removed is not stated.

**What**

The function that submits a feedback survey follow-up no longer independently checks the `allow_product_feedback` policy or logs telemetry for the not-first-party or policy-blocked cases before submitting. Instead, it now accepts a maximum character count and truncates the description to fit, and it can be cancelled via a cancellation signal. Several old parameters (`appearanceId`, `surveyResponse`, `surveyType`) were removed from it.

**Why**

This reworks how feedback follow-ups are validated and sent; descriptions that run long are now trimmed automatically rather than rejected, and the submission can be cancelled mid-flight.

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

### Tracing headers for cross-session turns via a specific MCP config

New tracing headers link related turns and events across sessions for a specific MCP configuration

**What**

Claude Code can now attach tracing information to certain requests: a trace context and an event identifier are carried across merged turns and sent as `anthropic/ccr-turn-event-uuid` and `anthropic/ccr-turn-linked-event-uuids` request headers. This only happens when a specific MCP server configuration is detected, and a related cross-session variant only applies when the `CLAUDE_CODE_REMOTE` environment setting is present.

**Why**

This lets backend systems correlate related turns and events across sessions for diagnostic or tracing purposes, but only in specific remote/MCP-connected setups rather than for ordinary local use.

- Area: Telemetry
- Names: `CLAUDE_CODE_REMOTE`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New internal SDK field: user_output_styles_dir

SDK session data now exposes user_output_styles_dir, the resolved path to the user-level output-styles folder

**What**

The session data exposed to developers building on the Claude Code SDK gained a new internal field, `user_output_styles_dir`. It holds the absolute path to the user-level output-styles directory (where personal output style customizations live), resolved after settings environment blocks are applied and honoring any `CLAUDE_CONFIG_DIR` set in managed or user settings. This field is absent when talking to older versions of the CLI.

**Why**

This gives SDK consumers a reliable, already-resolved path to the user's output-styles directory instead of having to recompute it themselves, accounting for any custom config directory location.

- Area: SDK
- Names: `user_output_styles_dir`, `CLAUDE_CONFIG_DIR`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Permission decisions now record how they were decided (`decidedBy`)

Permission approvals now record whether a hook, the host tool, or a normal prompt approved them

**What**

When Claude Code allows a tool call, it now records how that decision was made: a new `decidedBy` field is set to `hook` (an automated hook approved it), `host_prompt` (the host application's own permission prompt approved it), or `prompt` (the normal interactive permission prompt approved it). This is captured through a new `recordApprovedBy` call and ultimately shows up in telemetry as `approved_by`.

**Why**

This gives more visibility, mainly for diagnostics and telemetry, into which mechanism actually approved a given tool call, which is useful for understanding permission flows especially when hooks or host-provided prompts are involved.

- Area: Permissions
- Names: `decidedBy`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### MCP discovery can skip cache/connect when tools are already known

MCP server setup can now skip the discovery cache and connection entirely when a server's tools are already known

**What**

When Claude Code connects to an MCP server and discovers its available tools, the setup function can now be given a pre-supplied map of tools. If a server's tools are already known this way and it isn't a live connection, discovery short-circuits straight to building the result, skipping the discovery cache lookup and skipping opening a new connection entirely.

**Why**

This avoids redundant cache checks and connection attempts when the tool list for a server is already known, which should make repeated MCP setup faster in that case.

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

### Forced (destructive) removal of agent worktrees

Agent worktrees can now be force-removed, deleting all their files after verifying they're linked worktrees, not standalone repos

**What**

Cleaning up a git worktree used for an agent (a separate working copy of a repository, stored under `.claude/worktrees`) now supports a forced, destructive removal path. It deletes all files in the worktree directory except a verified `.git` file, then removes the directory itself. Before doing this, it checks that the target is actually a linked worktree, meaning it has a `.git` *file* pointing elsewhere rather than being a standalone repository with its own full history. If the deletion only partially succeeds, the `.git` gitlink pointer is restored.

**Why**

This lets Claude Code fully clean up an agent's worktree when needed, while the standalone-repo check guards against accidentally deleting the only copy of a repository's history, and the pointer restoration protects against leaving things in a broken half-deleted state if something goes wrong partway through.

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

### Strict network allowlist check consolidated and extended with CLAUDE_CODE_EVAL_CONFINED

Network sandbox strict-allowlist check consolidated into one helper, now also considering CLAUDE_CODE_EVAL_CONFINED

**What**

The check for whether the sandbox's strict network allowlist setting (`sandbox.network.strictAllowlist`, which denies hosts outside an allowlist instead of prompting) is active has been consolidated into a single helper function, replacing a previous inline chain of checks across configs. A related combined check now decides whether allowed network domains should be forced empty by considering this strict-allowlist setting together with another existing check and the `CLAUDE_CODE_EVAL_CONFINED` environment variable, which marks Claude Code as running as a confined evaluation child.

**Why**

This is mostly an internal cleanup that consolidates logic, but it means the confined-evaluation-child mode is now tied more directly into the same decision path that governs strict network allowlisting.

- Area: Sandbox Network
- Names: `sandbox.network.strictAllowlist`, `CLAUDE_CODE_EVAL_CONFINED`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Cloud/remote commands now share a common policy gate object and 'claude-ai' availability tag

Cloud-related commands now share one policy gate requiring an 'allow_remote_sessions' organization policy

**What**

The `remote-control`, `teleport`, `autofix-pr`, plan-in-web ("Draft an editable plan..."), and `remote-env` commands now all declare the same availability tag, `claude-ai`, and the same shared policy gate, which checks for an `allow_remote_sessions` organization policy under the feature label "Cloud sessions."

**Why**

This consolidates how these cloud-dependent commands check organization permissions, so an organization can now allow or block all of these cloud session features together through one consistent policy rather than separate checks per command.

- Area: Cloud Sessions
- Names: `allow_remote_sessions`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Session/agent auto-naming gains a 'cache' mode

Session/agent auto-naming adds a 'cache' mode with its own path for new names and name collisions

**Unclear.** What triggers 'cache' mode naming and what the dedicated collision path does differently is not stated.

**What**

The internal function that assigns or renames a conversation's auto-generated name now takes an explicit source setting, defaulting to "transcript" as before. It also adds a new "cache" mode: when naming happens in cache mode and no session has been established yet, it goes through a different, dedicated path rather than registering the name the normal way, and if the chosen name collides with an existing one, that collision is also resolved through the cache path instead of the usual collision resolver.

**Why**

This gives conversation naming a separate track for cache-driven naming, keeping it distinct from the normal transcript-based naming and collision handling.

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

### API dispatch requests now carry a per-attempt client request ID and richer retry telemetry

API requests now carry a per-attempt request ID and log more detail about retries

**Unclear.** Whether this is controlled by the tengu_api_success gate is unread for this account, so nothing can be said about whether it is switched on.

**What**

Every time Claude Code makes an API request, it now generates a fresh client request ID for each attempt and sends it in an extra header alongside the existing one. It also tracks an attempt counter and reports more detail about each request's lifecycle: whether it succeeded or failed, the status code, the error class, the attempt number, the client request ID, and the request ID. The success telemetry event also gains an `attempt` field, a `clientRequestId` field, and a `durationMs` value that excludes time spent on retries.

**Why**

This gives more precise data for tracking down what happened to a specific request, including which attempt it was and how long the successful attempt actually took, separate from any retry delays.

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

### New lightweight JS-object-literal parser for `meta` exports

A new lightweight parser safely reads meta object literals out of file source without using eval

**Unclear.** The finding doesn't say which feature (skills, commands, or something else) actually calls this parser.

**What**

Claude Code adds a small self-contained parser for JavaScript-style object literals, including handling for strings, numbers, arrays, nested objects, comments, trailing commas, and different kinds of quoted strings. It's paired with a pattern that locates a line like `export const meta = {...}` in a file's source and pulls out just that object.

This looks like the machinery used to read `meta` information out of things like skill or command files.

**Why**

Extracting this kind of data without using `eval` (a way of running arbitrary code found in a string) is safer, since it avoids executing anything from the file being read.

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

### New bash-command taxonomy for telemetry

Claude Code now classifies every bash command you run for internal telemetry

**What**

Claude Code has added a large internal classification system for bash commands. When a command runs, it is parsed and tagged with details like:

- `bash_command_class` — the general category of the command

- `bash_argv0` and `bash_last_argv0` — the program name(s) invoked

- `bash_subcommand` and `bash_subcommand2` — the subcommand, including special handling for tools like `git`, `gh`, `npm`, `pnpm`, `yarn`, `pip`, `uv`, `cargo`, `go`, `docker`, and `kubectl`

- `has_pipe`, `has_redirect`, `has_chain`, `has_subshell`, `has_heredoc` — whether the command uses shell features like pipes (`|`), redirects, chaining, subshells, or heredocs

- `simple_command_count` — how many individual commands were run

The parser also knows to look past wrapper commands like `sudo`, `env`, `time`, `nice`, `timeout`, `xargs`, `stdbuf`, and `caffeinate` to find the real command being run.

**Why**

This is purely internal telemetry infrastructure, letting Claude Code understand what kinds of shell commands are commonly run without exposing anything new to the user directly.

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

### OTel span/error telemetry now separates a normalized error_class from the raw error message, and can suppress the raw message off-box

Telemetry now records a normalized error_class alongside error text, and can drop the raw message off-box

**What**

Claude Code's OpenTelemetry (OTel) diagnostics, a standard format for exporting logs and metrics, now record errors differently. Previously a span or event just carried a raw `error` string. Now it carries both that `error` string and a new `error_class` field, a short normalized code made only of letters, numbers, and underscores. When telemetry is being sent off the local machine, the raw `error` text is now left out entirely, leaving only the sanitized `error_class`.

**Why**

This lets error telemetry stay useful for spotting patterns (via `error_class`) without leaking potentially sensitive raw error text when data leaves the machine.

- Area: Telemetry
- Names: `error_class`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### System-prompt diff telemetry expanded with change-scope classification

System-prompt diff telemetry now classifies how the prompt changed between turns

**What**

The internal telemetry that compares the previous system prompt to the new one now records more detail: the previous model (`prevModel`), hashes of the previous and new beta feature sets (`prevBetasHash`/`newBetasHash`), counts of previous and new system turns (`prevSystemTurns`/`newSystemTurns`), and a new `changeScope` classification of the diff, which can be `none`, `unknown`, `rewrite`, or `tail_append`.

**Why**

This lets internal analysis distinguish minor prompt changes, such as an appended tail, from a full rewrite, and correlate prompt changes with model or beta-feature switches, without exposing anything new to end users.

- Area: System Prompt
- Names: `changeScope`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Artifact publish runs a new post-publish "ldx build" step

Publishing an artifact now triggers a follow-up ldx build step

**Unclear.** What the ldx build step actually does, and what consumes the ldxBuild result, is not stated in the finding.

**What**

After an artifact is successfully published, if the artifact registry module is available, Claude Code now also calls a new `ldxBuildAfterPublish` step, passing along the artifact's slug, files, live status, whether it was reseeded, a cancellation signal, and credentials. The result of this step is returned as `ldxBuild` in the tool's output, alongside the existing live working-copy binding.

**Why**

This adds an automatic post-publish build step for artifacts, so a build can be kicked off right after publishing without a separate manual step.

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

### New model-catalog schema fields: effort_levels, default_effort, image_limits, family

Model catalog entries gain image_limits and family fields alongside the existing effort-level metadata

**What**

The schema describing each model in the model catalog now includes `image_limits` and `family` fields, added to the existing set covering token limits, `effort_levels`, `default_effort`, capabilities, and knowledge cutoff. These now live under a `runtime` section within a larger catalog entry that also covers notices, selection notices, badges, tooltips, and quick-select behavior.

**Why**

This gives the model catalog more structured information to work with, such as image handling limits and model family grouping, which the app can use to describe and organize models more precisely.

- Area: Model Catalog
- Names: `image_limits`, `family`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New `tool_kind` field on permission requests, wired for browser tools

Permission requests can now carry a tool_kind field so SDK apps can route browser tool prompts to a custom UI

**What**

The `can_use_tool` permission request, which is what Claude Code sends when it needs approval to use a tool, now includes an internal `tool_kind` field. Right now the only value it can take is "browser". It is actually set to "browser" on real permission requests for browser-related tools like Claude in Chrome, Cowork, and remote-device MCP tools, not just declared as a possibility.

**Why**

This lets applications built on the Claude Code SDK show a specialized approval screen for browser tool requests without having to guess based on the tool's name.

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

### Auto mode availability tracked as ongoing telemetry, not just at init

Claude Code now tracks whether auto mode's availability changes during a session, not just at startup

**What**

Startup telemetry can now include a snapshot of auto mode's availability (whether it's available, whether its circuit breaker has tripped, and similar state) alongside the existing startup event. Claude Code also now watches for changes to that availability during the session, and fires a `tengu_auto_mode_availability_changed` event if it flips.

**Why**

This gives visibility into cases where auto mode becomes available or unavailable partway through a session, not just its state at launch.

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

### Bash tool execution now threads sandbox network lists computed at permission time into the actual spawn

Bash commands now reuse the network access list computed when permission was checked, instead of recalculating it at run time

**What**

When Claude Code runs a shell command inside its sandbox (a restricted environment that limits what a command can access), it now carries forward the network access list that was already worked out during the permission check for that command, and hands it directly to the process that actually runs the command. This is done through a small cache (holding up to 256 entries) keyed to the specific command, so the cached list is only reused if the command text still matches.

**Why**

This keeps the network rules used at execution time consistent with the ones the user (or policy) already approved, rather than recomputing them separately and risking a mismatch.

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

### Sandbox network list registration exposed to command wrapping

Claude Code can now register a per-command network allow/deny list inside the sandbox before running it

**What**

The part of Claude Code that runs commands in a sandbox (an isolated environment that limits what a command can do) gained two new internal functions, `registerCommandNetworkLists` and `unregisterCommandNetworkLists`, plus a flag called `askCallbackDenyReason`. Together they let a command have its own network allow/deny list set up right before it runs, and cleaned up again once it finishes or errors out.

**Why**

This gives the sandbox finer control over which network destinations an individual command can reach, and lets it report a reason when a network request is denied, rather than applying one blanket network policy to everything.

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

### CCR heartbeat can adopt a server-pushed event flush policy

CCR client can now adopt an event-flush policy pushed by the server in heartbeat responses

**Unclear.** The finding does not say what CCR is or what effect changing the flush policy has in practice.

**What**

When the CCR client receives a response to its heartbeat, it now checks for an `event_flush_policy` field in the response data and, if present, calls a new `takeUpFlushPolicy` method to adopt it. This happens alongside the existing handling for refreshed authentication in heartbeat responses.

**Why**

This lets the server adjust how the client flushes events at runtime by pushing a policy through the regular heartbeat, rather than that behavior being fixed on the client side.

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

### CCR (remote session) client gains ability to drop unwatched stream events

Remote session client can now be set to drop stream events nobody is watching

**Unclear.** Whether this behavior is active for any given account depends on the tengu_ccr_drop_unwatched_stream_events gate, which is unread for this account, so nothing can be said about whether it is switched on.

**What**

The client used for CCR (a remote/cloud Claude Code session) now supports a `dropUnwatchedStreamEvents` option, and this setting can be toggled live whenever the underlying feature-flag configuration refreshes, without needing to restart the session.

**Why**

Dropping stream events that nothing is watching for can reduce unnecessary work in a remote session, and making it toggleable live means it can be adjusted without disruption.

- Flag `tengu_ccr_drop_unwatched_stream_events`: Not enough to say (read for one account on one subscription tier against v2.1.268; this account: no value returned, anonymous baseline: no value returned, compiled default: off)
- Area: Telemetry
- Names: `dropUnwatchedStreamEvents`
- Tier: Under the hood
- Useful: 1/5
- Signal: 2/5

### New 'event hold' toggle for CCR client

A new 'event hold' toggle is added for remote session clients

**Unclear.** Whether this feature is active for any given account depends on the tengu_ccr_event_hold_enabled gate, which is unread for this account, so nothing can be said about whether it is switched on. It's also unclear what effect enabling the hold has in practice.

**What**

The client used for CCR (a remote/cloud Claude Code session) now has a new `eventHoldEnabled` option, controlled by a feature flag.

**Why**

The finding doesn't explain what holding events accomplishes, only that the toggle now exists.

- Flag `tengu_ccr_event_hold_enabled`: Not enough to say (read for one account on one subscription tier against v2.1.268; this account: no value returned, anonymous baseline: no value returned, compiled default: on)
- Area: Telemetry
- Names: `eventHoldEnabled`
- Tier: Under the hood
- Useful: 1/5
- Signal: 2/5

### SDK-only MCP-server filtering relaxed for CCR-injected configs in remote/bridge contexts

MCP server filtering in remote sessions now also allows non-SDK servers injected by CCR

**Unclear.** What CCR refers to and the full effect of a server being CCR-injected is not explained in the finding.

**What**

In `CLAUDE_CODE_REMOTE` mode, Claude Code's logic for deciding which MCP servers (connected external tool servers) are allowed to run now also registers each server configuration individually, and the filter that previously let only `sdk`-type servers through in restricted/remote scenarios now also admits non-SDK servers that were injected by CCR, as long as the process isn't running as a bridge-carrier child.

**Why**

This loosens a previously strict SDK-only filter so that CCR-injected MCP servers can also run in remote/bridge contexts, where before they would have been blocked.

- Area: MCP
- Names: `CLAUDE_CODE_REMOTE`
- Tier: Under the hood
- Useful: 1/5
- Signal: 2/5

### Auto-mode classifier now also skips its fast path when a tool declares per-call sandbox network lists

Auto-mode's classifier now runs on tools that declare per-call network allow/deny lists, instead of skipping them

**What**

In accept-edits mode, Claude Code's auto-mode classifier normally has a fast path that lets certain tool calls through without full classification. That fast path now also checks whether a tool declares sandbox network lists (allow or deny lists of network hosts) for a given call. If it does, the call no longer takes the fast path and instead goes through the classifier as normal.

**Why**

This means tool calls that carry their own per-call network restrictions get properly reviewed by the classifier rather than being waved through automatically, which matters for anything that reaches out over the network.

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

### `NAe` (proactivity-related gate used by shortcut/auto-mode logic) now hardcoded to return false

A proactivity-related check used by shortcut keys and auto-mode is now hardcoded to always say no

**Unclear.** What the disabled behavior actually did for users, and whether this is a temporary rollback or a permanent removal, is not stated.

**What**

An internal function used at four different call sites (a shortcut-key check and three places in auto-mode's default-mode logic) has been replaced with one that always returns false, no matter what it's given. Every one of those call sites now unconditionally takes the 'false' branch of its logic.

**Why**

In practice this disables whatever proactive behavior these shortcut and auto-mode branches used to enable, since the check that used to gate them can no longer return true.

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

### Governed-git session config gains an unwired direct-upstreams parameter

Governed-git sessions can now carry a directUpstreams setting, though nothing sets it yet

**Unclear.** Nothing found yet calls the builder with this fourth parameter set, so its practical effect for users is not established.

**What**

The internal configuration builder for governed-git sessions (a mode that manages git access under organizational controls) now accepts a fourth parameter. When present, and when the session has no explicit git configuration, no credentials embedded in its URL, and an unaltered mount URL, it gets attached to the session config as `directUpstreams`. That value is later used to decide whether a repository should be reset back to its plain upstream URL.

**Why**

This lays groundwork for governed-git sessions to track and enforce a repository's original upstream URL, though nothing yet appears to actually pass this new parameter in.

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

### api_request telemetry gains a ttft_ms field and firstContentMs tracking

Claude Code now records how long it took to get the first bit of a response back, as ttft_ms in telemetry

**What**

The internal logging that records API request completion now tracks a `firstContentMs` value, and when it's available, includes it in the `api_request` telemetry event as `ttft_ms` (time to first token, meaning how long it took before the model started sending back any response text).

**Why**

This gives visibility into response latency at the start of a request, not just total completion time, which is useful for understanding how responsive requests feel in practice.

- Area: Telemetry
- Names: `ttft_ms`
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Text component supports custom link-href mapping (linkHref prop)

Text rendering can now customize or suppress the link target for auto-detected URLs via a linkHref function

**What**

The component that automatically turns URLs found in text into clickable links now accepts an optional `linkHref` function. When provided, each detected URL is passed through this function to decide its actual link destination, and if the function returns nothing (undefined), that particular match is not turned into a link at all.

**Why**

This lets code using the text renderer redirect, rewrite, or selectively disable auto-linking of URLs, rather than always linking to the exact raw URL text that was detected.

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

### Read-outside-working-directory prompt text centralized behind a typed dialog kind

The 'Read outside the working directories?' permission prompt is now built from a dedicated dialog descriptor

**What**

The permission prompt Claude Code shows when it wants to read a file outside your project's working directories ('Read outside the working directories?') is now generated from a dedicated, named dialog descriptor (`auto_mode_outside_reads`) with a fixed set of choices: allow, block, or ask again. Previously this prompt and its explanatory text were assembled inline in the code, rather than from a single reusable descriptor.

**Why**

This is mostly a code organization change, centralizing how this specific permission prompt is built. For users, the visible prompt and its options (like 'Yes, keep allowing reads outside the working directories') stay conceptually the same.

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

### Bridge indicator reworked to carry an explicit status, not just a boolean

The bridge status chip in the status line now shows a real status value instead of just on/off

**Unclear.** What specific status values the indicator can now show, beyond the previous boolean, is not specified.

**What**

The small indicator ('chip') in the status line that shows bridge connection state used to appear only when a column-width check passed, and it only ever carried a true/false 'selected' flag. It now always computes and passes an explicit status value, and shows the chip whenever that status is present, regardless of column width.

**Why**

This lets the bridge indicator communicate more than just whether it's selected, so the status line can reflect the bridge's actual state rather than a simple on/off.

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

### Local-slash-command dispatch can now surface `localCommand` in its result

Local slash-command results now include a localCommand field when the command wasn't handed off to the model

**What**

When Claude Code runs a slash command locally rather than deferring it to the model, the result it returns now includes a `localCommand` field identifying it as such. This field is only present when the command was not deferred (`engineDeferredSlash` is false).

**Why**

This makes it possible for other parts of Claude Code, or tools consuming its output, to tell apart commands handled locally from those passed along to the model, without needing extra checks elsewhere.

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

### OTEL telemetry redaction for off-box remote-session traces

Remote-session telemetry now redacts prompts, model names and agent ids when sending traces off-box

**What**

When Claude Code is running as a remote session (`CLAUDE_CODE_REMOTE`) and sending OTEL (OpenTelemetry, a standard for exporting diagnostic traces) data to a traces endpoint that isn't on the local machine, telemetry spans for interactions, model requests, tool calls, and subagent launches now get scrubbed before they leave:

- User prompts are always shown as `<REDACTED>`, even if `OTEL_LOG_USER_PROMPTS` is turned on.

- Model names are replaced with a hashed, normalized stand-in, reported under a new `tool_name_safe`/`query_source_safe` field instead of the real value.

- Agent ids are anonymized with a hashing scheme.

- Custom subagent types are reported simply as `"custom"` rather than by name.

- The interaction span also gains link tracking (`queued_sends`) and a `parent.source` attribute.

**Why**

This closes a gap where a previous release added a way to log assistant responses in traces but only guarded the content itself; this change makes sure that when traces are sent to a remote collector outside your own machine, potentially sensitive details like prompt text, model identity, and agent identity aren't exposed even if local logging settings would otherwise include them.

- Area: Telemetry
- Names: `CLAUDE_CODE_REMOTE`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### SessionStart hooks can be cut short by an 'orphaned' signal

SessionStart hooks can now be stopped early if the session becomes orphaned

**What**

The code that runs `SessionStart` hooks (which fire when a session begins or resumes) now checks for a new `orphaned` signal in addition to the existing abort signal. If either is triggered, the hook run stops early instead of continuing to wait.

**Why**

This avoids waiting for hook results in a session that has already become orphaned, which is a change from the prior grace-period settling behavior that waited for pending async hooks to finish before continuing.

- Area: Hooks
- Names: `SessionStart`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### GitHub-not-connected / access errors for cloud review restructured with reusable builders

GitHub-access error messages for cloud review reworked with dedicated builders and a faster inconclusive path

**What**

When `/review`'s cloud review flow (`ultrareview`) can't find a GitHub account linked to your Claude account, or the linked account can't see the target repository, the error text is now assembled by dedicated helper functions instead of being built inline. The underlying check for GitHub access now has its own capped time budget, and it returns "inconclusive" immediately if the account isn't eligible, instead of always waiting on a full network call.

**Why**

This should make these GitHub-access errors return faster and more consistently, particularly when the account clearly can't proceed, rather than always waiting out a full request.

- Area: Elsewhere
- Names: `/review`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Advisor tool model-resolution path now also receives `credentials`

Model-resolution during the main loop now also receives credentials, and the advisor-tool consent call was renamed

**Unclear.** It's unclear what effect passing `credentials` into model resolution has for the user, beyond the internal rename.

**What**

The internal function that resolves which model to use during the main loop, now called `Jm` (previously `Hm`), takes an added `credentials` argument alongside the user-specified model, agent model, and other settings. Separately, the confirmation step in the advisor-tool consent flow was renamed internally, and still logs the `advisor_fable_consent` event.

**Why**

The finding doesn't say what using `credentials` in model resolution changes in practice; it's an internal wiring change rather than a new user-facing behavior.

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

### New telemetry events for the verification-required surface

Two new telemetry events fire when Claude Code shows a verification-required message and its link

**What**

Two new telemetry events, `tengu_ranch_rc_shown` and `tengu_ranch_rc_link_shown`, are now recorded: the first when a verification-required message is shown to the user, and the second when the link inside that message is shown.

**Why**

This is purely a change to what usage data is recorded around the verification-required message; it doesn't itself change what the user sees.

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

### Event-queue batching gains partial-pass/'owed' bookkeeping

The batched event-send queue now tracks 'owed' events and can let some events through while holding others back

**What**

The generic queue Claude Code uses to batch and send events was reworked. `takeBatch` now takes an explicit count of how many events are sendable, tracks an `owed` counter for events that were pulled ahead of a hold, and supports a `holdSpec.passes` setting that lets certain events through even while a hold is otherwise in effect. The `send` and `onDrained` callbacks now also receive a `rule` field explaining why events were held back.

**Why**

This is internal bookkeeping for how events get batched and released; it makes the hold-and-flush logic more precise about which events are let through and why, without changing what data ends up being sent.

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

### MCPB and plugin MCP-config load errors now redact URLs/paths before logging

MCPB and plugin MCP-config loading errors now redact URLs and file paths before logging them

**What**

Across several places that load MCPB packages and plugin MCP configuration, such as downloading an MCPB package, checking a modification-time cache, resolving a directory-loaded plugin's source, and loading `.mcp.json`, raw URLs and file paths that end up in log or error messages are now passed through a redaction helper first, and diffs are formatted through a separate helper. For example, a log line now reads `Downloading MCPB from ${mf(e)}` instead of including the raw URL directly.

**Why**

This keeps potentially sensitive URLs and file paths out of logs and error output when something goes wrong loading MCPB packages or plugin MCP configuration.

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

### Model catalog dedup helper (ust) drops override/provenance-override handling

The model catalog dedup helper no longer adds override-sourced model entries, only ones from the served catalog

**Unclear.** What effect this has on any model entries that previously came from an override source is not stated.

**What**

The function that builds the model-selection list dropped its `overrides` parameter and the code that used to add rows sourced from `ant_override` into the alias-keyed list. It now only builds the list from the catalog served by Anthropic.

**Why**

The finding doesn't say what drove this or what it means for users who relied on override-sourced models appearing in the selection list; it's a narrowing of where the list's entries can come from.

- Area: Model Catalog
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Hook telemetry span changes shape in remote (CCR) sessions

Hook telemetry looks different in remote (CCR) sessions, dropping hook_definitions and using the raw event name

**What**

In a remote Claude Code session (`CLAUDE_CODE_REMOTE`) that has no bridge carrier, the telemetry span recorded for a hook run now uses the raw event name in place of the resolved `hook_name` attribute, and omits the `hook_definitions` field entirely. `hook_definitions` is now only included when a separate condition (`Ol()`) is true and the session is not this kind of remote session.

**Why**

This changes what detail is available in hook-related telemetry for remote sessions specifically, which matters for anyone inspecting or debugging hook behavior through that telemetry.

- Area: Telemetry
- Names: `CLAUDE_CODE_REMOTE`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Policy limits fetch telemetry now reports restriction/compliance-taint counts

Policy limits telemetry now counts denied restrictions and compliance-taint occurrences

**What**

The `tengu_policy_limits_fetch` telemetry event, which fires when Claude Code fetches policy limits, now also records `restrictions_denied_count` (how many restrictions in the fetched policy were marked as not allowed) and `compliance_taint_count`.

**Why**

This gives Anthropic more visibility into how restrictive an account's fetched policy is and how often compliance-taint conditions occur, building on earlier additions to this same telemetry event that recorded authentication details and server error information.

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

### Remote Control eligibility check reworked to report org-policy denial distinctly

Remote Control availability checks now distinguish org-policy denial from other reasons

**What

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

### Event queue batching gains configurable hold rules with byte/item caps and named release reasons

Internal event batching now supports configurable size/age limits and reports why a batch was released

**What**

An internal queue used for batching and throttling events has been reworked to support configurable hold rules: limits on the number of items, total byte size, and maximum age before a batch is released. Each release now also reports which named rule triggered it, alongside the existing release reasons like hitting a maximum item count, byte size, age, or capacity.

**Why**

This is internal plumbing rather than a user-facing feature, but it gives Claude Code finer control over how event data is grouped and flushed, which can affect performance and telemetry accuracy.

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

### Startup now logs auto-mode availability and guards context-metrics collection against failure

Startup now logs auto-mode availability and won't crash if context-metrics collection fails

**What**

When Claude Code starts up, it now records whether 'auto mode' is available as part of its startup telemetry. Separately, the code that collects context metrics (data about how much of the context window is in use) is now wrapped so that if this collection fails, the failure is caught and logged rather than crashing the startup process.

**Why**

This makes startup more resilient: a problem gathering context metrics will no longer be able to take down the whole startup sequence, and it becomes easier to tell whether auto mode was available in a given session.

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

### MCP connect now threads a 'knownListings' set through server connection to skip redundant discovery

Claude Code now skips redundant tool/resource discovery for MCP servers it already has a listing for

**What**

When connecting to MCP servers (external tool providers via the Model Context Protocol), Claude Code now passes along a set of 'known listings' it already has. A server that's already in this known set is now also treated as eligible to always be loaded.

**Why**

This avoids repeating discovery work for MCP servers whose tools, commands, and resources are already known, which should make connecting to already-known servers faster.

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

### MCP OAuth error messages now clamp/redact server config detail before logging

MCP error messages (OAuth, reconnect, toggle failures) now redact sensitive server config details before logging or display

**What**

Error messages related to MCP servers now go through shared helpers that clamp and redact sensitive configuration detail before the error is logged or shown to the user. This covers:

- OAuth errors, including a rejected custom redirect URI and a failed localhost fallback

- MCP reconnect failures and failures listing a server's tools

- Failures when toggling multiple MCP servers on or off, which now report per-server errors instead of one generic message

- Auth-revocation failures

Also, a failed localhost OAuth fallback now throws an error instead of silently doing nothing.

**Why**

This keeps MCP server configuration details, which can include secrets, out of error messages while still giving more specific, contextual information about what went wrong, including per-server detail when toggling several servers at once.

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

### rewind_conversation and the new fork_conversation share a common target-lookup and blocked-state helper

rewind_conversation and the new fork_conversation now share the same logic for finding a target message and checking if the session is busy

**What**

The handling code for `rewind_conversation` and the newer `fork_conversation` control requests now shares a common function for looking up the target message and a common check for whether the session is busy or blocked. This replaces `rewind_conversation`'s previous, more elaborate custom logic for searching through stacked expansions and queued commands to find its target.

**Why**

This is a code consolidation that makes the two related features behave consistently, rather than a new capability for the reader.

- Area: Sessions
- Names: `rewind_conversation`, `fork_conversation`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact read-permission denial path unified across list_files/read_file/verify/read actions

Artifact read-permission errors now use the same wording across list_files, read_file, verify, and read actions

**What**

Previously, the `list_files` and `read_file` artifact actions produced a different error message when blocked by a read-permission deny rule than the `verify` and `read` actions did. Now all four actions route through the same shared error-handling logic, so a blocked read produces the same denial or target-changed message no matter which action triggered it.

**Why**

This makes the behavior consistent and predictable: whichever way an artifact read is blocked, the resulting error message is now the same across the board.

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

### Chat input component gains a new `ideSelection` prop

The chat input component now accepts an ideSelection prop again

**Unclear.** The finding does not say what using `ideSelection` in the input component actually changes for the user.

**What**

The component that renders the chat prompt input now takes an `ideSelection` prop as part of its inputs.

**Why**

This is an internal wiring change; the finding does not indicate what user-visible effect it has, though `ideSelection` refers to information about a selection in a connected IDE.

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

### Publish permission check for copied files now includes the requested action

Publish permission checks for copied artifact files now also record the requested action

**What**

When publishing an artifact that copies files from another artifact, the permission check now also passes along the specific action being requested, in addition to the existing flag marking it as a copy.

**Why**

This lets the authorization logic that decides whether the file source is allowed take the requested action into account, rather than judging only on the fact that files are being copied.

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

### Plugin sync gains a startup fast-path that reuses a recent round

Plugin sync can now skip a full sync round on startup if one recently completed

**What**

Similar to skills syncing, plugin syncing now checks on startup whether a sync round completed recently. If so, and a sync wasn't explicitly forced, it reuses that recent result instead of re-downloading and re-listing plugins, logging `plugins_sync_round_reused`.

**Why**

This avoids redundant plugin sync work on every startup, which should make starting Claude Code faster when nothing has changed since the last sync.

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

### Background agent status now records an explicit 'template'/agentType field with a 'bg' fallback

Background agent status now stores an explicit agent-type field, defaulting to 'bg' if none is given

**What**

When Claude Code saves the state of a background agent, the stored `template` value is now explicitly derived from the agent's `agentType`, falling back to the literal string `"bg"` if none is provided, rather than passing through whatever value the caller happened to supply.

**Why**

This ensures background agent records always have a consistent, well-defined type value instead of possibly storing something unexpected or missing from the caller.

- Area: Background Agents
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### MCPB source path sanitized in logs and errors

MCPB plugin bundle file paths are now sanitized before appearing in logs or error messages

**What**

When Claude Code loads an MCPB (a packaged Claude plugin bundle), the source path is now passed through a sanitizer before it shows up in logs or error text. A local file read failure now produces a distinct 'MCPB local file read failed' error that shows the sanitized display path instead of the raw resolved file path.

**Why**

This avoids leaking potentially sensitive local file path details into logs and error messages while still giving a usable, readable path for troubleshooting.

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

### 'projectsUserTurn' flag threaded into verified relay marking

A new projectsUserTurn flag is passed through when marking a verified human turn, tied to shared-project support

**What

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

### Session-start event now checks whether the session head is orphaned

Session-start telemetry now checks whether the session's starting point is orphaned before firing

**Unclear.** What exactly counts as an 'orphaned' session head is not specified in the evidence.

**What**

The telemetry call that fires when a session starts now first runs through a helper that determines whether the session's starting point (its 'head') is 'orphaned', and passes that status along with the event, instead of always firing unconditionally.

**Why**

This lets session-start tracking distinguish sessions that resume from a disconnected or missing starting point from normal ones, which is useful for diagnosing session continuity issues.

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

### Bash permission-rule matching gains compound bare-assignment support

Bash permission matching adds a compound-bare-assignment name list for allow/prefix rules

**Unclear.** The finding does not explain what a 'bare assignment' command pattern looks like in practice or which specific commands this affects.

**What**

The internal function that checks a bash command against your allow, deny, and ask permission rules now accepts a list called `compoundBareAssignmentNames`. For permission rules recognized as a 'bare assignment' pattern (a rule form the code detects via `Vct(U)`), that rule now only matches under allow-with-prefix rules, and only through a new check (`NIn(U, p, v)`) that consults this name list.

**Why**

This narrows when a bare-assignment-style permission rule is allowed to match, tightening how such rules are applied to bash commands.

- Area: Bash Permissions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Env-var telemetry allowlist and a no-op stub added near it

Telemetry now only logs recognized CLAUDE_CODE_*/ANTHROPIC_* env var names by name, bucketing the rest as 'other'

**What**

A new allowlist of about 30 named `CLAUDE_CODE_*` and `ANTHROPIC_*` environment variables is now used when logging which environment variables are set: names on the list are reported as-is, while any other environment variable name is bucketed and logged simply as "other". An unrelated no-op function was added nearby in the same change but does nothing.

**Why**

This keeps diagnostics and telemetry from recording arbitrary, potentially sensitive environment variable names that happen to start with those prefixes, only known/expected variable names are reported individually.

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

### Catalog fetch tracks 'not_permitted' errors as a distinct served-catalog state

Plugin catalog fetch failures now distinguish a 'not_permitted' state, and errors can carry an error code

**What**

When fetching a marketplace or plugin catalog fails for the reason `not_permitted`, Claude Code now records this as a distinct state by setting a `servedCatalogNotPermitted` flag on shared state. Error results from catalog fetches can also now carry an optional `errorCode` field.

**Why**

This lets Claude Code (and anything reading this state) tell apart a catalog that failed to load because access wasn't permitted from other kinds of failures, enabling more precise handling or messaging around that specific case.

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

### Subagent progress events now carry the underlying API error kind

Subagent progress events now include the specific API error kind, not just a yes/no flag

**What**

When a subagent (a secondary Claude instance handling part of a task) reports a tool-use event that involved an API error, the event now carries an `apiErrorKind` field with the specific error value, in addition to the existing plain yes/no `isApiError` flag.

**Why**

This gives the interface and telemetry more detail about what specifically went wrong with a subagent's API call, rather than only knowing that some error occurred.

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

### Resumed in-process teammates now report an agent-definition-change notice

Resuming an in-process teammate can now surface a notice that its agent definition changed

**Unclear.** What the definitionNotice actually contains or when it is populated is not specified.

**What**

When an in-process teammate (a subagent running within the same session) is resumed, the result now includes a `definitionNotice` field, passed through from a new parameter at the point where the resume happens, alongside the existing agent ID, task ID, and count of resumed messages.

**Why**

This allows Claude Code to surface a notice when a resumed teammate's underlying agent definition has changed since it was last active, though the finding doesn't specify what that notice says or when exactly it appears.

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

### gatewayInternalNetworks added to managed-settings merge exception list

gatewayInternalNetworks added to the list of managed-settings fields that replace rather than merge

**What**

The documentation for managed settings' "merge" composition mode now lists `gatewayInternalNetworks` among the fields where a helper's whole value replaces the existing one outright, rather than being combined with it. It joins the existing list that includes `fallbackModel`, `forceLoginOrgUUID`, and `sandbox.filesystem.allowRead`.

**Why**

This keeps the newly added `gatewayInternalNetworks` setting consistent with how other security- and identity-related managed settings behave under merge mode: an organization's configured network list is applied wholesale, not blended with another source's list.

- Area: Managed Settings
- Names: `gatewayInternalNetworks`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Remote-control bridge: distinguishes org-policy denial and logs it before exiting

Remote Control now logs and distinguishes org-policy denials before exiting

**What**

When a `--remote` (deprecated alias for `--cloud`) or cloud/remote session request is refused because organization policy disallows it, Claude Code now logs that denial specifically before exiting, in addition to showing the existing error message to the user.

**Why**

This gives administrators and support better visibility into when and why organization policy is blocking remote control features, rather than the refusal only appearing as a message in the terminal.

- Area: Remote Control
- Names: `--remote`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Non-interactive stream-input refusal now logs remote-session policy denial

Non-interactive stream mode now logs when remote sessions are blocked by policy

**What**

When a non-interactive, stream-based session is refused because remote sessions aren't available, Claude Code now logs that this was an organization-policy denial before returning the refusal.

**Why**

This adds visibility into policy-driven refusals in non-interactive mode, matching similar logging elsewhere for remote control denials.

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

### Bash tool monitor spawn now carries sandboxNetworkLists

Background and monitored Bash commands now carry the same per-command network allowlist

**What**

When the Bash tool spawns a command under its monitor (used for background or long-running commands), it now also passes along the per-command sandbox network allowlist, the same mechanism that lets an individual command reach extra network domains beyond the sandbox's global allowlist.

**Why**

This makes sure background and monitored bash commands get the same per-command network permissions as commands run directly, instead of missing out on them.

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

### Job/worktree deletion gains a 'force removed' outcome

Deleting a job now separately tracks when its worktree had to be force-removed

**What**

When a session or job is deleted, Claude Code's telemetry and result data now distinguish a forced worktree removal (a git worktree, the separate working copy tied to that job, being deleted forcibly) from the existing case where the worktree is simply left in place. This adds a new `worktree_force_removed` outcome and a `forcedWorktreeRemoval` field.

**Why**

This gives clearer visibility into how job cleanup actually resolves worktrees, rather than lumping a forced removal in with other outcomes.

- Area: Agent Worktrees
- Names: `worktree_force_removed`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Terminal identity (XTVERSION) response now normalized/classified for telemetry

Claude Code now classifies terminal identity replies into known terminal names for telemetry

**What**

Claude Code queries the terminal for its identity (an XTVERSION reply) and now runs the raw response through a new classifier that matches it against known terminal names, such as iTerm2, ghostty, WezTerm, and tmux, plus a version-like suffix. Unrecognized replies fall into an "other" bucket, and a missing reply falls into a "no_reply" bucket. The result feeds an `xtversion` telemetry field.

**Why**

This gives Claude Code cleaner, more consistent data on what terminals people actually use, rather than raw, inconsistent reply strings.

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

### Plan-mode model clamp warning routed through a return value instead of an inline call

Plan-mode model-clamp warning is now returned as data instead of logged directly

**What**

The internal logic that clamps (restricts) which model can be used in plan mode now returns the chosen model along with a `clampWarning` value, instead of directly issuing the warning itself. The calling code is now responsible for deduplicating and logging that warning.

**Why**

This is an internal restructuring of how the clamp warning is delivered; it doesn't change what a user sees, but centralizes where the warning is logged.

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

### Client-side data cache key getter now accepts a model parameter

Client-side data cache can now be keyed per model, not just globally

**What**

The function that reads Claude Code's local client-data cache now accepts an optional parameter that gets factored into the cache key, and cached entries can carry a `model` field alongside their data.

**Why**

This allows cached client data to be stored and retrieved separately per model, rather than sharing a single cache entry regardless of which model is in use.

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

### CCRClient adds explicit stream-delta drop/resume logging tied to subscriber presence

Streaming client now logs when it starts and stops dropping updates due to no active viewers

**What**

When the option to drop unwatched stream events is enabled, the client now logs a message when it begins dropping incremental stream updates because no subscribers are watching, and logs again when it resumes sending them once a viewer returns. It also tracks whether an absent viewer has already been reported and releases a 'served_policy' upload hold once a watcher reappears.

**Why**

This gives clearer visibility into when and why stream updates are being suppressed, making it easier to diagnose gaps in streamed output that are caused by no one currently watching.

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

### SDK/control-protocol pending-request lists now documented as always present as of this build

SDK docs now guarantee the pending-request lists in the initialize response are always present from v2.1.268 onward

**What**

The documentation for the `initialize` response used by SDK and control-protocol clients now states that the pending-request lists for `request_user_dialog` and `can_use_tool` are always present, even if empty, as of Claude Code v2.1.268 or later.

**Why**

This lets SDK clients reliably tell the difference between an older CLI version that could simply omit the field and a newer one reporting that nothing is currently pending.

- Area: SDK
- Names: `request_user_dialog`, `can_use_tool`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### claudeMd block now always sent to model, even when empty

The claudeMd block is now always included in what's sent to the model, even when there's no content

**What**

When assembling project context to send to the model, Claude Code now always includes a `claudeMd` block, defaulting to an empty string if there's nothing to put in it. Previously this block was only included when there was actual CLAUDE.md content, or when a particular internal setting was enabled.

**Why**

This makes the shape of the assembled project context consistent regardless of whether CLAUDE.md content exists, rather than varying based on content or configuration.

- Area: System Prompt
- Names: `CLAUDE.md`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Model catalog now logs why it fell back to compiled model list (credential_scope)

Claude Code now logs a specific reason (credential_scope) when it falls back to the built-in model list due to credential permissions

**What**

When the model list Claude Code shows can't be fetched because the current credentials aren't allowed to read the server's model data, it now records a telemetry event, `model_catalog_primary`, with `decision: 'off'` and `off_reason: 'credential_scope'`. The event also logs the HTTP status and refusal code involved, before Claude Code falls back to its built-in, compiled-in list of models.

**Why**

This makes it possible to tell, from telemetry, specifically when a fallback to the built-in model list happened because of a credential's permissions, rather than some other failure.

- Area: Model Catalog
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### MCP tool-schema meta-validator now loaded lazily via dynamic chunk import

MCP's tool-schema validator is now loaded lazily from a separate bundled chunk instead of built upfront

**Unclear.** Whether this lazy-loading change has any user-visible effect beyond internal structure is not stated.

**What**

When Claude Code checks that an MCP (Model Context Protocol) server's tool definitions conform to the JSON Schema draft 2020-12 standard, it now loads the validator function lazily from a separate bundled chunk of code, rather than constructing the validator instance directly every time.

**Why**

This is an internal implementation change to how the validator is obtained; if that validator ever fails to load, tool schema checks fail open (meaning they don't block the tool from being used), so the practical behavior for users should stay the same.

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

### Event-flush policy schema reworked around a policy_version and byte/age/count caps

A validation schema for per-model settings was replaced by one for event-buffer flush policy with caps on count, age and bytes

**What**

An internal validation schema (used to check that data matches an expected shape before Claude Code trusts it) that used to describe per-model configuration, things like token limits and effort levels, now instead describes a policy for flushing buffered telemetry events. The new schema covers `max_events`, `max_age_ms`, `max_bytes`, `flush_on_sampling_end`, `flush_on_assistant`, `must_flush_types`, and a `policy_version` field.

**Why**

This is a server-controlled policy shape for deciding when buffered telemetry gets sent, based on how many events have piled up, how old they are, or how large they've gotten, rather than a model-configuration schema. It supports the broader move toward server-tunable telemetry buffering behavior.

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

### Skill-loading instruction text replaced by a connecting-status label at one call site

A leftover skill-loading instruction at one code path was replaced with the '/rc connecting…' status label

**What**

A spot in the code that used to hold a large block of instructional text about loading a design-calibration skill before writing files now instead holds the small status label used for the `/rc connecting…` indicator (the Remote Control status shown when a remote session is connecting).

**Why**

This is a cleanup at one call site rather than a user-facing feature: the leftover instructional text is gone and that location now correctly reflects the `/rc connecting…` status label.

- Area: Remote Control
- Names: `/rc`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Plugin API `session.turnCount` renamed to `session.turns`

Plugin API hook `session.turnCount` renamed to `session.turns`

**What**

The plugin hook (a named entry point plugins can call into) used to read a session's turn count is now registered as `session.turns` instead of `session.turnCount`.

**Why**

Plugins that call this hook need to use the new name `session.turns`; the old name `session.turnCount` is no longer registered.

- Area: Plugins
- Names: `session.turns`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New OAuth error code list for token/auth error classification

New internal list of standard OAuth error codes for classifying auth failures

**Unclear.** The finding does not say where these codes are now used or what specific messages they produce.

**What**

A new list of standard OAuth (the protocol used for authentication/login flows) error codes was added, including things like `invalid_request`, `invalid_grant`, `authorization_pending`, `expired_token`, `slow_down`, `invalid_client_metadata`, `insufficient_scope`, `invalid_target`, `method_not_allowed`, and `too_many_requests`.

**Why**

This lets Claude Code recognize and classify a wider range of standard authentication error responses, which can lead to more accurate error handling and messaging when a login or token exchange fails.

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

### Teleport revert now marks pending thinking-block stripping

Reverting a teleport session now flags pending thinking-block cleanup and skips one telemetry event

**Unclear.** The finding does not explain what a teleport/relay session is used for or what consuming the `relayThinkingStripOwed` flag does later.

**What**

When a teleport (relay) session reverts from active back to a non-active status, it now sets a `relayThinkingStripOwed` flag to true. It also now skips sending the "upgrade teleport cache" telemetry event specifically when the revert reason is `direct_served`.

**Why**

This marks that thinking content (the model's intermediate reasoning) still needs to be stripped after a relay session reverts, and avoids emitting a telemetry event that wouldn't apply in the `direct_served` case.

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

### MCP client bridge gains a global `isDisabled` kill-switch checked before every tool call

The Chrome/browser tool bridge now checks a global disabled switch before running any tool call

**What**

The browser control bridge (the part of Claude Code that talks to a connected Chrome/browser instance for things like switching tabs or listing connected browsers) now checks a kill-switch flag before running each step: dispatching a tool call, looking up tab context, switching or listing browsers, watching the connection, and listing available tools. If the switch reports the bridge is disabled, the call stops immediately and reports the tool as unknown instead of attempting it.

**Why**

This gives Claude Code a single, reliable way to turn off browser-bridge functionality everywhere it's used, so a disabled bridge can't be partially bypassed by one code path forgetting to check.

- Area: Chrome & Browser
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New URL redaction helpers for stripping credentials/query/hash before logging or telemetry

New helper functions strip credentials, query strings, and fragments from URLs before they're logged

**What**

Claude Code now has a set of internal helper functions that detect and remove sensitive parts of a URL, such as an embedded username and password (`user:pass@host`), query strings, and fragments, as well as sensitive parts of Windows/UNC file paths. When found, these are replaced with a fixed placeholder, `[redacted URL]`, before the URL is written to logs or telemetry.

**Why**

This reduces the chance that credentials or other sensitive data embedded in a URL or file path accidentally end up in logs or diagnostic data.

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

### New telemetry event tengu_web_fetch_transport records outcome and duration of the raw HTTP fetch

A new telemetry event records the outcome and duration of each raw WebFetch network request

**Unclear.** Whether the `tengu_web_fetch_transport` telemetry is active for any accounts is unread and not stated.

**What**

WebFetch (the tool Claude Code uses to fetch a URL's contents) now emits a telemetry event, `tengu_web_fetch_transport`, around its low-level network request. It records the outcome (error, redirect, HTTP error, or success), how long the request took (`httpDurationMs`), and how many bytes were returned.

**Why**

This gives Anthropic visibility into how WebFetch's network requests are performing and failing, which can help diagnose fetch reliability issues.

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

### Chrome bridge tool-result telemetry now includes response size and transport tag

Chrome bridge tool-call telemetry now records response size in bytes and tags the transport as "bridge"

**What**

The `chrome_bridge_tool_call_completed` and `chrome_bridge_tool_call_error` telemetry events now include a `transport: "bridge"` tag. Completed calls additionally record `response_bytes`, the size of the raw websocket response message.

**Why**

This gives more detail in telemetry about Claude in Chrome tool calls, letting response payload size and transport type be tracked alongside success and error outcomes.

- Area: Chrome & Browser
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### MCP tool-list telemetry now tracks description length stats

MCP tool-list telemetry now reports total, max, mean, and over-limit counts for tool description lengths

**What**

The `tengu_mcp_tools_listed` telemetry event, sent when Claude Code lists tools from an MCP server, now includes four new fields about the length of tool descriptions returned by that server: `descriptionTotalLength`, `descriptionMaxLength`, `descriptionMeanLength`, and `descriptionOverLimitCount` (how many descriptions exceed a configured size limit).

**Why**

This gives visibility into how verbose an MCP server's tool descriptions are, which can help identify servers whose overly long descriptions might affect performance or context usage.

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

### tengu_api_success gains firstContentMs, clientRequestId, user_message_uuid

API success telemetry now records time-to-first-content, a client request id, and the user message's UUID

**What**

The main `tengu_api_success` telemetry event, recorded on successful API calls, now includes three new pieces of data: `firstContentMs` (time to first content, tracked separately from time to first token), a client-generated `clientRequestId`, and `user_message_uuid`, identifying the user message that originated the request.

**Why**

Separating time-to-first-content from time-to-first-token gives finer-grained timing data for diagnosing responsiveness, while the client request id and user message UUID make it easier to trace a given API call back to the specific request and message that triggered it.

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

### Worktree dirty-check now distinguishes tracked vs untracked changes

Claude Code can now tell whether a worktree's changes are tracked edits or just untracked files

**What**

The internal check that decides whether a git worktree (a working copy of your repo) is "dirty" now returns a second signal, `trackedChanges`, alongside the existing `dirty` flag. This lets Claude Code distinguish between a worktree that has real edits to files git already knows about, versus one that only has new, untracked files sitting in it.

**Why**

This distinction lets other parts of Claude Code make smarter decisions about worktrees, such as whether it's safe to reuse or discard one, without treating stray untracked files the same as genuine uncommitted changes.

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

### Query telemetry can now carry a resume_reason

Query telemetry can now record a resume_reason when a query is triggered by resuming a session

**Unclear.** The finding does not say how or where resume_reason values are used or surfaced beyond internal telemetry.

**What**

When Claude Code sends a query, if the event that triggered it carries a `resumeReason` (a note explaining why a session was resumed), that reason is now attached as `resume_reason` in the telemetry data recorded for the query.

**Why**

This gives internal telemetry more context about why a given query happened, specifically when it follows a session resume, which can help with diagnosing and understanding usage patterns.

- Area: Telemetry
- Names: `resume_reason`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### overageScope now read generically from response headers instead of hardcoded 'channel'

Usage overage scope is now read generically from server response headers instead of only matching the literal value "channel"

**Unclear.** The finding does not say what other scope values the helper can now return besides "channel".

**What**

Previously, Claude Code set an internal `overageScope` value to the literal string "channel" only when a specific response header equaled "channel". Now a helper function parses that header more generally, so it can return other scope values as well, and the result is passed through into telemetry as `limitScope`.

**Why**

This lets Claude Code recognize and report additional kinds of usage scopes beyond just "channel" for tracking where a usage limit or overage applies.

- Area: Rate Limits
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New persisted state path: served-calls, added to backup/restore and gitignore-style deny lists

New state file .claude/state/served-calls added to backup/restore handling and paths that tools should leave alone

**Unclear.** The finding does not say what "served-calls" tracks or how it's used beyond being persisted and protected.

**What**

A new state path, `.claude/state/served-calls`, has been added both to the list of files Claude Code can restore during local state persistence, and to the list of paths that git and file operations should avoid touching, alongside other protected state files like `unattended-serving-consent.json`.

**Why**

Treating this new file the same way as other internal state files keeps it from being accidentally modified, deleted, or committed by normal git or file operations, while still letting Claude Code back it up and restore it as part of its own persisted state.

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

### New env vars added to passthrough/allow list

Four more environment variables are now recognized and passed through by Claude Code

**Unclear.** What effect being on this passthrough list has for each variable, and what the other three variables specifically control, is not described.

**What**

Claude Code's internal list of recognized environment variables gained four new entries:

- `CLAUDE_CODE_SANDBOXED`

- `CLAUDE_CODE_ATTRIBUTION_STATUS_TIMEOUT_MS`

- `CLAUDE_CODE_TOOL_USE_ID`

- `CLAUDE_CODE_MODEL_CAPABILITIES`

**Why**

Adding these to the recognized/passthrough list means Claude Code now acknowledges and forwards these variables where relevant, rather than treating them as unrecognized. `CLAUDE_CODE_MODEL_CAPABILITIES` was previously introduced to override model capability flags by model name pattern; this change means it's now included alongside the others in the same internal list.

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

### canReadOutputFile now defaults to true / is explicitly tracked per async agent launch

Background agent launches now default to allowing their output file to be read

**Unclear.** What situation would set canReadOutputFile to false is not stated.

**What**

When Claude Code launches a background or web-fetch agent, the result now explicitly includes a `canReadOutputFile` flag, and it defaults to true unless explicitly set to false.

**Why**

This makes read access to a background agent's output file an explicit, tracked property of each launch rather than an implicit assumption, defaulting to allowed.

- Area: Background Agents
- Names: `canReadOutputFile`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### 'Reload plugins' notification suppressible via warning notification id

The 'reload plugins' notification can now be suppressed under a condition

**Unclear.** What condition the check (Bn()) tests, and therefore when the notification is suppressed, is not stated.

**What**

A new high-priority warning notification setup was added for prompting you to reload plugins, but it's now skipped whenever a particular internal check returns true.

**Why**

This prevents the "reload plugins" notification from showing up in situations where it isn't relevant, though the finding doesn't say what that condition specifically checks for.

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

### Session shutdown now flushes held telemetry before exit

Claude Code now flushes any held-back telemetry before it shuts down

**What**

When a session is shutting down, if telemetry events are currently being held back under the new server-served flush policy, Claude Code now applies a "shutdown" hold, keeps client events open through the cleanup process, and performs an extra flush before finally closing.

**Why**

This makes sure telemetry that was deliberately delayed for batching isn't accidentally lost when the app or session exits.

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

### MCP-needs-auth count now factors into a storageV5-gated status component

A new check trims stale 'needs auth' notices for MCP servers and feeds the count into the status banner

**Unclear.** placeholder

**What

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

### Artifact type-catalog lookup gets a description cache with TTL/backoff

Artifact type lookups now cache their descriptions with a timeout and a shorter retry delay on errors

**What**

When Claude Code needs to look up an artifact type's description (for example, its title) as part of publishing or resuming an artifact, it now caches that result per environment and per type. Successful lookups are cached for a set amount of time, and failed lookups (other than a plain "not found") are cached for a shorter time before being retried. This only applies when the underlying type catalog feature is turned on for the session.

**Why**

Caching avoids repeating the same lookup over and over, while the shorter retry window for errors means a temporary failure doesn't get stuck for as long as a normal successful result.

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

### MCP tool call now merges additional call metadata via DPe/Jmt/Xbt

MCP tool calls can now attach extra metadata fields alongside the tool-use ID, behind a gate

**Unclear.** What the extra metadata fields contain and what they're used for is not stated.

**What**

When Claude Code calls an MCP (Model Context Protocol) tool — a tool provided by an external server rather than built in — it sends along a small metadata payload with the tool-use ID. Now, when an internal condition is met, extra fields are merged into that metadata payload as well. Previously the payload only ever contained the tool-use ID.

**Why**

This lets Claude Code pass additional context to MCP tool servers in some sessions, though the finding doesn't specify what that extra context contains or affects.

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

### Additional early no-consent-surface guard in a further artifact action

Another artifact action gets an early deny when there's no way to show a consent prompt

**Unclear.** The finding does not name which specific artifact action this guard applies to.

**What**

A further artifact action now checks, before reaching its usual publish-permission logic, whether a consent-related value is missing and the session is in the same no-prompt state used by Cowork or local-agent sessions. If so, the action is denied right away rather than falling through to the existing check further down.

**Why**

This is part of a broader pattern of denying artifact actions upfront when there's no user available to answer a permission prompt, rather than letting them proceed on unclear footing.

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

### Gateway setup screen gains an internalNetworks prop

Cloud gateway setup screen now receives an internalNetworks setting

**Unclear.** What internalNetworks controls in the gateway setup flow is not specified by the finding.

**What**

The screen used to set up OAuth for a Cloud gateway now takes an `internalNetworks` value, in addition to the `initialUrl` and `screenLocked` values it already had.

**Why**

This suggests the gateway setup screen can now be given information about internal network addresses, though the finding doesn't specify what it does with that information.

- Area: Gateway
- Names: `internalNetworks`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Tool-call error telemetry gains an errorClass field

Tool-call failure telemetry now records a separate error class alongside the error message

**What**

When a tool call fails, the telemetry Claude Code sends now includes a new `errorClass` field in addition to the existing error message or code. Telemetry is internal usage data, not something shown in your session.

**Why**

Recording a distinct error class makes it easier to tell failures apart by category rather than just by their raw message text, which helps with diagnosing patterns in tool-call failures.

- Area: Telemetry
- Names: `errorClass`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact-type instance freshness check now also considers declared endpoints

Artifact freshness checks now also factor in an artifact type's declared endpoints

**What**

When Claude Code checks whether a fetched Artifact page is still fresh, or whether it counts as coming 'from type,' the comparison now also looks at the Artifact type's declared endpoints, not just its declared store data as before.

**Why**

This makes the freshness check more accurate for artifact types that define endpoints, so the freshness/'from type' status better reflects what the type actually declares.

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

### Permission requests to remote bridge now tag browser-category tools

Permission requests sent to the remote bridge now flag whether the tool is a browser tool

**What**

When Claude Code asks a remote bridge session for permission to run a tool, the request now includes a new piece of information: whether that tool is a browser-related tool, determined by matching its name.

**Why**

Tagging browser tools separately lets the remote bridge treat permission requests for browser actions differently from other tool permission requests.

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

### Remote bridge session now sends the git repo URL to session config

Remote bridge sessions now also send the git repository URL as part of session setup

**What**

When a remote bridge session sends its configuration during handoff, it now includes a `gitRepoUrl` field that wasn't part of that payload before.

**Why**

This git remote URL passes through the same credential-stripping step already used elsewhere, so any embedded username and password are redacted before being sent, in line with how the git remote URL is already handled during bridge registration.

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

### Bridge teardown 'skip archive' path now also waits on a preflush hold and reports it

Bridge teardown's skip-archive path now also waits for pending uploads and reports timeouts

**Unclear.** Whether this behavior is active for any given account depends on the tengu_bridge_repl_teardown gate, which is unread for this account, so nothing can be said about whether it is switched on.

**What**

When a remote bridge session tears down and skips archiving, it now waits on a pending-uploads check if there are uploads still in flight, and logs a new failure reason, `skip_archive_flush_timeout`, if that wait doesn't finish in time. The teardown telemetry now also includes the fields `hold_preflush_ms` and `hold_preflush_landed` on this skip-archive path, which previously only recorded them on the full-archive path.

**Why**

This brings the skip-archive teardown path in line with the full-archive path, so timing and success information about the pre-teardown upload flush is captured consistently regardless of which teardown path runs.

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

### Plugin 'installed' manager now knows when changes apply immediately

Installed-plugins screen now knows which changes apply immediately without a reload

**What**

The screen for managing installed plugins now has a `changesApplyOnClose` setting, tied to the same tracking used to decide whether a reload prompt is needed.

**Why**

This lets the plugin manager distinguish changes that take effect as soon as you close the screen from ones that need an explicit reload, matching the reload-prompt logic added alongside it.

- Area: Plugins
- Names: `changesApplyOnClose`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Cloud session creation can now branch from HEAD explicitly

Creating a cloud session can now explicitly say it should branch from HEAD

**What**

When creating a remote/cloud session, Claude Code now sends an explicit `branchFromHead` flag, computed from whether the two possible branch-name sources are both empty, alongside the existing branch and ref parameters.

**Why**

This makes the branch-from-HEAD behavior an explicit signal sent to the server rather than something inferred implicitly, which should make cloud session creation more predictable.

- Area: Cloud Sessions
- Names: `branchFromHead`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Cloud session creation gains explicit branchFromHead flag

Cloud session creation sends an explicit branchFromHead flag instead of letting the server infer it

**What**

Creating a remote/cloud session now sends an explicit `branchFromHead` boolean, worked out from whether a reuse-branch value or an explicit ref was supplied, rather than leaving the server to infer that on its own.

**Why**

Sending this explicitly should make it clearer and more consistent whether a new cloud session starts from HEAD.

- Area: Cloud Sessions
- Names: `branchFromHead`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New 'undigested' cache-staleness state in git-attributes/hook expansion resolver

Git hook/attribute file expansion gains a new 'undigested' state for stale cached files

**Unclear.** The finding does not say what user-visible effect the `undigested` state has, only that the resolver can now return it.

**What**

The internal logic that expands file references in git hook and attribute configuration now tracks a modification 'stamp' for each file path, and can report a new `undigested` result when a file's cached state hasn't caught up with its current content. This sits alongside the existing not_text, unbounded, unexpandable, and contributes result kinds.

**Why**

This distinguishes files that simply haven't been processed yet from other reasons expansion might fail, which should make caching in this area more accurate.

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

### Session resume now filters out already-seen message UUIDs

Resuming a session no longer duplicates messages it has already seen

**What**

The function that rebuilds conversation history when resuming a session (renamed `YMe`) now accepts an optional set of message IDs already seen. When provided, any message whose ID is already in that set is filtered out before the resumed history is saved.

**Why**

This prevents the same message from being duplicated in a session's history when resuming, keeping resumed conversations accurate.

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

### Ask/approval state now tracks who approved it

Internal ask/approval tracking now records who approved a request

**What**

The internal class that tracks a pending ask or approval (such as a permission request) now has a new field for who approved it, along with a getter to read it and a `recordApprovedBy` method to set it.

**Why**

This is internal bookkeeping that lets Claude Code keep track of who approved a given request, alongside the addressee and settlement tracking it already had.

- Area: Permissions
- Names: `recordApprovedBy`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Bash static-analysis results now flag whether argv came purely from literals

Bash permission checks now note whether a command's arguments came purely from literal text

**What**

When Claude Code statically analyzes a bash command to decide on permissions, its 'simple command' parsing result now includes two new fields: `argvSourceLiteral`, which indicates whether all the command's arguments came purely from literal text, and `carveOutMayDesyncQuoteScan`. Both are computed from counters that increase whenever the parser encounters arithmetic expansion, simple expansion, or herestring redirects (shell features that compute or substitute values rather than using plain text).

**Why**

This gives the permission-checking logic more precise information about whether a command's arguments are trustworthy literal text or come from potentially dynamic shell expansions, which affects how safely the command's permissions can be evaluated.

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

### MCP claudeai-proxy 401 telemetry now sanitizes the proxy error code

MCP proxy 401 telemetry now sanitizes the error code before logging it

**What**

When the `tengu_mcp_claudeai_proxy_401` telemetry event records a `proxyErrorCode`, that value is now passed through a validator that only allows codes matching a simple letters/numbers/underscore/hyphen pattern starting with a letter. Any code that doesn't match is reported as `"nonconforming"` instead of being logged raw.

**Why**

This prevents arbitrary or malformed error code strings from being logged verbatim in telemetry, keeping the recorded data predictable and safe.

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

### Model-override settings-source enumeration reworked

Internal check for model-override settings now filters sources instead of excluding one

**Unclear.** The finding does not say what user-visible effect this has on model-override behavior.

**What**

A helper used internally when Claude Code checks model-override and enforcement settings was reworked. Instead of taking a full list of settings sources and removing one scope from it, it now filters the complete set of settings sources down to just `localSettings` and `projectSettings`, and it excludes project settings entirely in a certain condition.

**Why**

This is an internal implementation detail of how Claude Code decides which settings file takes precedence for model overrides. It doesn't change any user-facing behavior directly, but it affects which settings sources are consulted when enforcement checks run.

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

### MCP reconnect/error messages now use the server config to redact detail more precisely, matching the 'detail withheld on this connection' off-box pattern

MCP connection error messages now redact detail based on the specific server's configuration

**What**

When Claude Code fails to connect to or has an error with an MCP server (a Model Context Protocol server, which provides extra tools), the error-formatting code now receives that server's configuration alongside the error itself. This lets the message be tailored to the type of connection before deciding how much detail to show.

**Why**

This makes redaction more precise: rather than a one-size-fits-all message, Claude Code can now decide per connection whether to show full detail or fall back to a generic 'detail withheld on this connection' message when telemetry is leaving the machine.

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

### Auto-mode permission telemetry now tags MCP tool calls with connection/ambiguity info

Auto-mode telemetry now tags MCP tool calls with which server they connect to and whether that's ambiguous

**What**

When Claude Code's auto-mode (a mode that can approve or reject tool calls automatically) logs telemetry about falling back to asking the user, making a decision, or showing a permission prompt, calls involving an MCP tool (one provided by a Model Context Protocol server) now get extra information attached: which server connection the tool belongs to, and a flag for whether that association is ambiguous. This is computed only when needed and reused for the rest of that call.

**Why**

This gives clearer visibility into how auto-mode handles MCP tools specifically, which is useful since a tool name alone doesn't always identify which server it came from.

- Area: Auto Mode
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Sandbox network allowlist hosts are now attached to permission-approval telemetry and to the classifier record

Approving a sandboxed network permission now records the allowed domains in telemetry

**What**

When a tool's permission request includes a list of network hosts it's allowed to reach (a sandbox network allow-list), the permission dialog now pulls that list out and, if you approve the request, records the allowed domains against that tool call in telemetry.

**Why**

This makes it possible to see which network destinations were approved for a given tool call, adding traceability for sandboxed network access decisions.

- Area: Sandbox Network
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Self-hosted runner watchdog log gains a bg-result-grace budget component

Self-hosted runner's watchdog timeout calculation now includes a background-result grace period

**What**

The self-hosted runner's startup log line for its 'watchdog config,' and the calculation behind how long it waits before shutting down, now factor in an additional timing value alongside the existing stop-grace period, post-session-hook timeout, and push-outcome timing: a grace period for background results.

**Why**

This should make the runner's shutdown timing account more accurately for work still finishing in the background, reducing the chance it cuts off before background results are reported.

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

### Rate-limit / API error message component gets an apiErrorKind prop

The API-error/rate-limit message component now receives an apiErrorKind value

**Unclear.** The finding does not say what values apiErrorKind can take or how they change what is displayed.

**What**

The internal component that renders API error and rate-limit messages now takes a new `apiErrorKind` value in addition to the `isApiError` flag and its existing rate-limit callback handling.

**Why**

This lets that message component distinguish between different kinds of API errors when deciding what to show, rather than only knowing that an error occurred.

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

### Addon tools gain a permissionCard field and a wrapping helper

Addon tools now carry a permissionCard field and get wrapped by a new helper

**Unclear.** What permissionCard controls and what the wrapping helper (B_t) actually does are not specified in the finding.

**What**

The internal factory that builds addon tools now attaches a `permissionCard` property to the tool definition it produces, and wraps the finished tool object with a new helper before returning it. A related tool builder does the same, wrapping its output with two helpers together.

**Why**

This is internal plumbing for how addon tools are assembled; the finding does not say what the permission card displays or what the wrapping helper changes about tool behavior.

- Area: Elsewhere
- Names: `permissionCard`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### MCP connection telemetry now records server instructions length/truncation

MCP connection telemetry now records the length of a server's instructions and whether they were truncated

**What**

The `tengu_mcp_server_connection_succeeded` telemetry event, sent when Claude Code successfully connects to an MCP (Model Context Protocol) server, now includes two new fields: `instructionsLength`, the character count of the instructions text the server returned, and `instructionsTruncated`, which is true when that text is longer than 2048 characters.

**Why**

This lets Claude Code track how often MCP servers send unusually long instructions and whether those instructions get cut off, which can affect how well the server's guidance reaches the model.

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

### MCP tool/notification names are now sanitized before logging

MCP tool and notification names are now truncated and sanitized before appearing in logs

**What**

When Claude Code's internal MCP (Model Context Protocol) host logs which tool is executing or which notification method was received, it now truncates the name to 64 characters and converts it to a safe JSON string before writing it to the debug or info log, instead of inserting the raw name directly.

**Why**

This prevents an MCP server from injecting unexpected or oversized content into Claude Code's logs via a crafted tool or notification name.

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

### MCP OAuth/auth error messages now pass through a redaction helper

MCP OAuth error messages are now run through a redaction helper before being logged or sent

**What**

When Claude Code's MCP (Model Context Protocol, the system that lets Claude talk to external tool servers) authentication flow fails, the error text it produces is now built through a new redaction helper before it is logged or sent back over the control channel. This applies to errors from the authentication step, the OAuth callback URL handling, and the redirect-URI fallback logging.

**Why**

This reduces the chance that sensitive details (such as tokens or internal URLs) leak into logs or error messages shown to the user when an MCP server's authentication fails.

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

### New traceContext field attached to remote-relayed prompt messages

Prompt messages relayed remotely now carry a new traceContext field

**Unclear.** What traceContext is used for, or what consumes it, is not stated.

**What**

When Claude Code builds the internal message for an incoming user prompt, it now attaches a new `traceContext` field, computed by a new helper. This only happens when the `CLAUDE_CODE_REMOTE` environment variable is set, meaning it applies to messages relayed through a remote session rather than a normal local one.

**Why**

This is internal plumbing that likely helps trace or correlate remote-relayed prompts, though the finding does not say what consumes this field.

- Area: Sessions
- Names: `CLAUDE_CODE_REMOTE`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Interrupted-turn resume messages now carry a resume reason and originating uuid

Auto-resumed turns now record why they resumed and which message they resumed from

**What**

When Claude Code automatically resumes a turn that was interrupted (for example, if a session restarts mid-response), the reconstructed prompt now includes a `resumeReason` field explaining why the resume happened, and, when available, a `resumedTurnUserMessageUuid` field that points back to the original user message whose turn got interrupted.

**Why**

This gives more traceability around interrupted-and-resumed turns, making it possible to tell which original message a resumed turn corresponds to and why the resume occurred.

- Area: Sessions
- Names: `resumeReason`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Auto-mode projects owner-rows telemetry now tracks stale/former team members

Auto-mode projects telemetry now also flags stale and former team members among project owners

**What**

When Claude reads project owner metadata while working in auto/projects mode, an internal data-quality check now also counts two new kinds of problem rows: rows where the listed member is no longer active ("not live"), and rows where the member's role is `former_member`. These counts are folded in alongside the existing checks for malformed, truncated, and stamped rows, and factor into the `auto_mode_projects_owner_rows` telemetry event that gets logged.

**Why**

This is internal telemetry used to catch and diagnose stale or inaccurate ownership data behind the scenes; it does not change what the user sees.

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

### Result messages now get a per-session result_index stamp

Result messages sent over the SDK/stream-json transport now carry a per-session result_index number

**What**

Outgoing 'result' messages on the SDK and stream-json transport (the machine-readable output formats used by tools and scripts driving Claude Code) now get a `result_index` field, an incrementing number stamped on each message. A tracking mechanism ensures each message only gets stamped once, even if it passes through multiple times.

**Why**

This gives anything consuming Claude Code's programmatic output a reliable way to tell results apart and put them in order, which is useful for tooling that processes a stream of results rather than reading them one at a time in a terminal.

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

### Terminal identity/version now reported in a startup telemetry probe

Claude Code now identifies your terminal emulator and its version and reports it in a startup telemetry event

**Unclear.** Nothing has been read yet about how the `tengu_terminal_probe` gate itself is set for any account.

**What**

A new parser reads the terminal identification string your terminal sends (an XTVERSION-style response) and matches it against a list of known terminal emulators, such as kitty, WezTerm, and Ghostty, along with several version-number formats. The result is normalized and included as `xtversion` in the `tengu_terminal_probe` telemetry event sent at startup.

**Why**

Knowing which terminal and version a user is running helps Claude Code understand compatibility issues and tailor behavior to specific terminal emulators.

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

### Chrome bridge tool calls now emit a start telemetry event with request size

Chrome bridge tool calls now log a start event that includes the size of the outgoing request

**What**

Before Claude Code dispatches a tool call through the Chrome bridge (the connection to the Claude in Chrome browser extension), it now emits a `chrome_bridge_tool_call_started` telemetry event. It records the tool name, session ID, message ID, timeout, transport method, and the byte size of the request, calculated from the combined permission and allowed-domains data being sent.

**Why**

This gives visibility into how large and how often Chrome bridge requests are, which can help diagnose performance or timeout issues with browser-based tool calls.

- Area: Chrome & Browser
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Resumed in-process teammate can carry a definitionNotice

Resuming a teammate as an in-process agent can now show an extra notice appended to the success message

**Unclear.** What conditions produce a definitionNotice, or what text it contains, is not stated.

**What**

When a teammate (a subagent) is resumed to run in-process rather than as a separate process, the function that performs the resume can now return a `definitionNotice`. If present, it gets appended, with a leading space, to the success message shown to the user after the resume completes.

**Why**

This lets Claude Code surface additional context or a warning about the teammate's definition at the moment it's resumed, though the finding doesn't say what triggers a notice or what it says.

- Area: Teammates
- Names: `definitionNotice`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Frontmatter-shadow telemetry no longer conflates surface and detail

Frontmatter-shadow telemetry now logs surface and detail as separate values instead of one value duplicated into both

**What**

The internal helper that logs `frontmatter_shadow` telemetry events gained a fourth parameter, so the `detail` field it logs is now a distinct value rather than being derived from the same input as the `surface` field.

**Why**

This makes the `frontmatter_shadow` telemetry more precise, since `surface` and `detail` can now carry different information instead of always matching.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### New byte-scanning helper for checking a substring inside a file without loading it fully

New internal helper scans a file in chunks for a byte pattern without loading the whole file into memory

**Unclear.** The finding does not say which feature or code path now uses this helper.

**What**

Claude Code has a new internal helper that checks whether a file contains a given byte pattern by reading it in bounded chunks, rather than loading the entire file into memory at once.

**Why**

This makes checking whether a file contains something more memory-efficient, especially for large files.

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

### New helper extracts a structured summary from plugin-related error/event objects

A new helper pulls a consistent summary out of plugin-related error and event data

**What**

Claude Code has a new internal function that extracts a normalized set of details, such as the plugin, marketplace, dependency, server name, component, path, and URL, from the varied shapes plugin-related errors and events can take. It also resolves cases where a plugin is shadowed by, renamed to, or a duplicate of another plugin into a single 'related' field.

**Why**

This is internal groundwork that should make plugin-related error and event handling more consistent, likely leading to clearer messages when something goes wrong with a plugin.

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

### Version/build metadata bump only

Two code hunks are just the routine version bump to 2.1.268 with no logic change

**What**

A couple of code locations, in the OAuth gateway's response headers and in the self-update recovery error messages, only reflect the routine version, build-time, and git-commit metadata bump to 2.1.268. The surrounding code itself did not change in behavior.

**Why**

This is purely a build-identification update and does not affect how Claude Code behaves.

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

### Permission-mode control-request construction extracted into helper `YHe`

The code that builds permission-mode change events was pulled out into its own helper function

**What**

The internal logic that constructs the `set_permission_mode` event (sent when the permission mode changes) has been moved out of an inline object literal into a dedicated helper function. The resulting event has the identical shape as before.

**Why**

This is an internal code-organization change with no effect on what Claude Code does when the permission mode changes.

- Area: Permissions
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Skills-sync internal state gains a dedup Set and pending-claims array

Skills-sync internals gain new bookkeeping for pending and deduplicated items

**Unclear.** The finding does not say what specifically this bookkeeping tracks or fixes.

**What**

The internal process that syncs the skills manifest gained two new pieces of internal state, alongside its existing backoff timers and fields like `pendingClaims` and `staleDirs`: a set used to deduplicate items and a list of pending claims.

**Why**

This looks like internal bookkeeping for the skills sync process rather than a user-facing change.

- Area: Skills
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### register_repo_root and add_directory refactor (mostly renaming)

Internal renaming pass over the repo-registration and add-directory handlers, plus a small plugin-reload tracking addition

**What**

The internal handlers behind registering a repository root and adding a directory were renamed and reorganized with no clear change in behavior. One small addition: `register_repo_root` now sets a new internal flag after it reloads plugins, which looks like it tracks that a reload happened.

**Why**

Mostly internal cleanup with no expected effect on day-to-day use, though the new flag suggests some future or related logic will be able to check whether a plugin reload already occurred during repo registration.

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

### Artifact asset read/delete permission check refactored to a shared helper

Artifact asset read/delete permission checks now go through a shared internal helper

**What**

The check that decides whether you're allowed to read or delete an artifact asset was rewired to use a shared internal helper function instead of a separate inline lookup, and this helper now throws its denial directly rather than returning a value to be checked.

**Why**

This is an internal consistency change. It should not change what gets allowed or denied, but centralizes the logic so read and delete checks behave the same way.

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

### Task/session list rendering internals reshuffled

Internal rewrite of the task/session list panel's rendering code, no visible behavior change

**Unclear.** The finding shows no behavioral difference, so it's unclear whether this rewrite changes anything a user would notice.

**What**

The internal rendering function for the task and session list panel was rewritten with new variable names and cache slot arrangement in its memoization cache.

**Why**

This appears to be internal code cleanup with no clear effect on what you see or how the panel behaves.

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

### toolUses / toolResults validation schema renamed fields

toolUses/toolResults validation now expects tool_use_id and tool fields instead of id and name

**What**

The internal validation for `toolUses` and `toolResults` data now checks for fields named `tool_use_id` and `tool`, rather than the previous `id` and `name`. The corresponding error messages were updated to match.

**Why**

This is a naming change to the fields expected in this data; anything constructing these payloads directly needs to use the new field names to pass validation.

- Area: SDK
- Names: `tool_use_id`
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Plugin type-registry cleanup gains new per-type tracking sets

Plugin type registry now tracks stale replicas and splits instruction-related tracking into two sets

**Unclear.** The finding does not say what user-visible effect, if any, this tracking change has.

**What**

The internal registry that tracks plugin types now clears an additional `liveReplicas.tooOld` tracking set when it resets, and it replaces a single `typeShipsInstructions` set with two separate sets, `typeCatalogVouch` and `typeDescriptions`.

**Why**

This is internal bookkeeping for how Claude Code manages plugin types; it does not change any user-facing behavior on its own but reflects more granular tracking of plugin state.

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

### "[Thinking removed]" placeholder logic refactored into standalone helper functions

The code that replaces thinking blocks with a "[Thinking removed]" placeholder was reorganized into named helper functions

**What**

The internal logic that strips out thinking blocks, redacted-thinking blocks, and empty text blocks, replacing them with a "[Thinking removed]" placeholder, was restructured from an inline filter into two separate named helper functions: one that decides whether a block should be stripped, and one that builds the placeholder block itself.

**Why**

This is an internal code-organization change with no described effect on behavior; the placeholder still appears the same way when thinking content is removed.

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

### Plugin manifest path-traversal checks consolidated into a shared helper

Plugin path-traversal checks unified into one shared helper function

**What**

Several places that check plugin-declared paths for safety — commands, MCP server file references, and `plugin.json` marketplace source paths — used to each run their own simple check for ".." in the path. They now all call a single shared helper function instead. A related helper that checks whether a directory exists also changed: it now takes the plugin's root folder plus a subpath, rather than an already-resolved path.

**Why**

Consolidating these checks into one helper reduces the chance that one of the several places validating plugin paths is checked inconsistently or missed when the logic needs to change.

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

### Error box can now carry a clickable link

Error messages can now include a clickable link

**Unclear.** The finding does not say which errors currently use this or what the links point to.

**What**

The component Claude Code uses to display error boxes gained a `linkHref` property, which is passed through to the inner text so an error message can be shown together with an associated link.

**Why**

This allows error messages to point directly to relevant documentation or resources via a link, rather than only showing plain text.

- Area: Elsewhere
- Names: `linkHref`
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Web setup push-offer eligibility checks consolidated behind a() helper

Web setup push-offer logic consolidated into one shared eligibility check

**What**

The checks that decide whether to show the 'web setup push offer' prompt (whether it was dismissed forever, already shown, shown too recently, or shown too many times) used to be four separate checks. They are now combined into a single shared helper function, used both by the code that decides whether to show the offer and by another function (`tun`), which now also skips its 'not connected' check when the helper says the offer is eligible.

**Why**

This is an internal refactor that consolidates duplicated logic, making the push-offer eligibility rules consistent wherever they're checked.

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

### getSystemPrompt no longer takes additionalWorkingDirectories as an explicit parameter

System prompt assembly no longer takes additionalWorkingDirectories as its own parameter

**Unclear.** Whether additional working directories are still communicated to the prompt builder by another means is not stated.

**What**

The function that builds the system prompt (the instructions Claude Code sends to the model at the start of a conversation) no longer accepts `additionalWorkingDirectories` as a separate, explicit parameter, and no longer passes it that way into the underlying prompt-builder.

**Why**

This is an internal refactor of how extra working directories reach the system prompt. The finding does not indicate that the information about additional working directories is lost, only that it is no longer threaded through this particular parameter.

- Area: System Prompt
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Feedback survey eligibility check consolidated (kind check dropped from this branch)

Feedback survey eligibility check simplified into one combined helper

**Unclear.** Whether the interaction-kind restriction is preserved elsewhere or has effectively been dropped is not stated.

**What**

The check that decides whether a feedback survey branch should run has been consolidated into a single helper function. Previously it checked that the account type was 'firstParty' and separately required the current interaction to be of kind 'post' or 'share' (denying 'share' if an error state existed); now a single helper checks three conditions together, including the 'firstParty' account type and the absence of an error state.

**Why**

This is an internal simplification of the eligibility logic for showing a feedback survey; it does not change what users see, but it does drop the explicit 'post'/'share' interaction-kind check from this branch.

- Area: Feedback
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Model-clamp warning threading refactored, still single-fire per message

The plan-mode model-limit warning logic was restructured internally but still shows the warning only once per message

**What**

The function that enforces a model 'clamp' in plan mode (limiting which model can be used) now returns both the chosen model and a `clampWarning` value together, instead of just the model. The logic for deduplicating and logging that warning, which used to live inside the clamp function itself, now lives in the calling code.

**Why**

This is an internal restructuring of how the warning is passed around; the behavior a user sees, one warning per message at most, stays the same.

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

### storedImagePaths cleanup call sites swapped/renamed

The functions cleaning up storedImagePaths during draft restoration were swapped for renamed equivalents

**Unclear.** Whether the new functions behave identically to the ones they replaced, or only share the same role, is not established.

**What**

When restoring a draft message you were editing, the cleanup of `storedImagePaths` (bookkeeping for pasted images) now runs through differently named functions than before, for each pasted-content ID being cleaned up.

**Why**

This appears to be an internal rename or refactor of the cleanup functions rather than a change to what gets cleaned up or when.

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

## Removed

### "secDefault" managed-settings key removed

The `secDefault` managed-settings key has been removed entirely

**Unclear.** The finding does not say what, if anything, replaces `secDefault`.

**What**

The `secDefault` settings key, which used to be merged into managed (organization-controlled) settings and came with a special warning when it was set outside of managed settings, no longer exists anywhere in the code.

**Why**

Anyone relying on `secDefault` in their settings should be aware it no longer has any effect, since it has been dropped along with its associated warning message.

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

### Status/footer line's IDE badge appears to have been dropped from this component

The status bar's IDE badge appears to have been removed, while the bridge badge now reflects a status value instead of a plain on/off flag

**Unclear.** Whether the IDE badge's disappearance is an intentional removal or a side effect of restructuring the status bar's props is not shown in the evidence.

**What**

The function that renders the bottom status bar's badges (covering things like cloud, debug, bridge, and pull-request indicators) no longer reads `ideSelection` or `mcpClients` from its inputs at all, and no longer builds or shows an IDE-colored badge. Separately, the bridge badge's display condition changed from a simple true/false check to checking whether a `status` value is not null, with that `status` now passed down to the bridge badge component.

**Why**

Removing the IDE badge's inputs means it can no longer show IDE connection state in the status bar the way it previously could, while the bridge badge becomes able to reflect more than just on/off.

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

### Shared/all-scope artifact listing no longer has a kill-switch check

The kill switch that could disable shared/all-scope artifact listing has been removed

**What**

Artifact listing previously had a check that, when a feature flag was on and the requested scope wasn't `"mine"`, would immediately fail with "shared-scope listing is disabled." That check and its early-return branch have been removed entirely.

**Why**

Listing artifacts in shared or all scopes can no longer be blocked by that flag, so this path is no longer able to be disabled the way it previously was.

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

### Legacy 'd' flag and its dead branches removed from artifact-guard autoread

Old legacy code path removed from the internal check that guards stale or handed-over artifact files

**What**

An internal function that decides whether an artifact file can still be safely read (used when guarding against stale or already-handed-over files) has dropped an old on/off switch and the entire branch of logic it controlled. That removed branch used to return specific reasons like `legacy`, `not_plain_owner`, `strip_unsettled`, `control_bytes`, `interrupt_literal`, and `over_cap`. None of this logic runs anymore.

**Why**

This is internal cleanup rather than a user-facing feature. It shouldn't change what you see, but if you ever encountered one of those specific stale-file error reasons before, it can no longer occur.

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

### System prompt: 'scratchpad' and 'language' sections dropped from the coding system prompt

The coding system prompt no longer includes its 'scratchpad' and 'language' sections

**Unclear.** What, if anything, replaces the removed scratchpad and language guidance is not shown in the evidence.

**What**

The function that assembles Claude Code's system prompt no longer includes a 'scratchpad' section, nor the 'language' sections it previously had. Handling of environment info was also consolidated into a single call instead of being spread across the prompt assembly.

**Why**

Removing these sections changes what built-in guidance the model receives at the start of every conversation, though the evidence doesn't say what, if anything, replaced their function.

- Area: System Prompt
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### RemoteIO 'unapplied Safeguards skip' reporting removed / stubbed out

Reporting of skipped low-priority safety setting changes has been removed

**Unclear.** What 'Safeguards' settings are and why this reporting was removed isn't explained in the finding.

**What**

A piece of internal reporting that used to log when a below-floor 'Safeguards' setting change was skipped during a settings update has been removed. The method and the field backing it are gone, replaced by an empty stub that does nothing.

**Why**

This is an internal bookkeeping change; the finding doesn't say why the reporting was removed, only that it no longer happens.

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

### Artifact read-tracking: 'seeded'/skip-to-set upgrade path removed

Artifact viewer drops a special-case upgrade from 'skip' to 'set' read status

**Unclear.** Whether this behavior is switched on can't be said: the tengu_cobalt_plinth_fern gate reads on for both this account and the anonymous baseline, but no reading has been taken under this release.

**What**

In the artifact viewer's bookkeeping for tracking which versions of an artifact you've read, a special-case rule that upgraded a 'skip' read status to 'set' under a particular seeded condition has been removed. Only the general rule, which applies whenever the status isn't 'skip,' remains.

**Why**

The finding doesn't state the visible effect, but removing this special case means fewer paths by which a 'skip' status gets promoted to 'set.'

- Flag `tengu_cobalt_plinth_fern`: Not enough to say (read for one account on one subscription tier against v2.1.268; this account: no value returned, anonymous baseline: on, compiled default: on)
- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Model picker drops the "Comment on N selected lines" placeholder

Model picker no longer shows a "Comment on N selected lines" placeholder message

**What**

The model picker's keyboard shortcut handler used to show a placeholder message like "Comment on N selected line(s)..." when it detected a diff selection. That logic has been removed, and the picker now always shows a plain default placeholder instead.

**Why**

This removes a context-specific placeholder from the model picker, so it no longer reflects a selected diff range when choosing a model.

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

### MCP connection info panel drops the Args row

The MCP server info panel no longer shows the server's launch arguments

**Unclear.** The finding does not say why the row was removed or whether the information is shown elsewhere.

**What**

The panel that shows details about a connected MCP server (a Model Context Protocol server, an external tool provider Claude Code can connect to) no longer displays an "Args:" row listing the arguments used to launch that server.

**Why**

Anyone who used that row to check exactly how an MCP server was started will no longer find it in the detail panel.

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