/auto-mode-setup Now Requires File Hash Before Applying #
New
What
The --apply-file flag now requires a preceding --expect-sha256 <64-hex> argument. The apply step is refused unless the proposal file's exact bytes hash to the given SHA-256, preventing a file-swap attack between review and apply.
Usage
# Step 1: generate proposal (unchanged)
/auto-mode-setup --wizard posture=personal scope=all depth=both --propose
# Step 2: apply with hash
/auto-mode-setup --expect-sha256 <64-hex> --apply-file /tmp/auto-mode-proposal.json
Details
--expect-sha256 must come directly before --apply-file and must not use = syntax- Optional
--request-id <uuid> can be placed first; the UUID is echoed back in the JSON result as requestId, letting a host correlate replies to requests --request-id must be in canonical 8-4-4-4-12 hex-and-dash UUID format- Passing
--request-id after --apply-file is an error; it must come first - The hash mismatch error is: "The proposal file's bytes do not match the reviewed digest"
Evidence
New argument parser (search for "--expect-sha256 is required" or "--request-id must be a UUID").
MCP Tool Schema Validation Upgraded to JSON Schema Draft 2020-12 #
New
What
MCP tool input schemas are now validated against JSON Schema draft 2020-12. Tools with schemas that violate Anthropic API requirements are excluded when the server's tools are loaded; a system message lists which tools were dropped.
Details
- Added
$dynamicAnchor and $dynamicRef (replacing the deprecated $recursiveAnchor/$recursiveRef) - Added
dependentRequired and dependentSchemas (splitting the old dependencies keyword) - Added
maxContains and minContains - Added complete draft 2020-12 meta-schemas for core, validation, meta-data, format-annotation, content, applicator, and unevaluated vocabularies
tengu_mcp_normalize_root_combinators is a per-server-URL feature flag (configured as a list of hostnames, or "*" for all servers): when enabled for a server, tools whose input schema has a top-level anyOf, oneOf, or allOf keyword are flattened — properties are merged from all combinator branches into a single flat properties object, required fields are collected from every branch, and a plain-text constraint note summarising the original branches is prepended to the tool's description. Without this flag, tools with top-level combinators are skipped entirely and logged as tool_schema_normalize_gated.tengu_mcp_drop_invalid_tool_schemas is a per-server-URL feature flag: when enabled, tools whose input schema fails draft 2020-12 meta-validation (checked via an Ajv2020 meta-validator) or whose property keys do not match /^[a-zA-Z0-9_.-]{1,64}$/ are excluded from the tool list and added to a droppedTools list that feeds the "Unavailable MCP Tools" system reminder. Without this flag, such tools are kept but a debug warning is logged that API requests including them may fail.- A system-reminder block titled "Unavailable MCP Tools" lists each excluded tool and its rejection reason
Evidence
New validator module (search for "https://json-schema.org/draft/2020-12/meta/core" or "$dynamicAnchor"). Exclusion message (search for "# Unavailable MCP Tools").
Credential Sentinels Now Substituted in Request Bodies #
New
What
Masked credential sentinels (set up via sandbox.credentials.envVars) are now replaced with their real values in outgoing request bodies as well as headers. A streaming Transform walks the body for sentinel byte sequences and swaps them in place.
Details
- Only applies to methods that send a body (
POST, PUT, PATCH, etc.) - Skipped for requests with
Content-Encoding headers (compressed bodies cannot be substituted safely; a warning is logged) - If any sentinel differs in length from its real value, the
content-length header is removed so the stream can change size - Only sentinels where sentinel length equals real-value length preserve
content-length intact
Evidence
Body substitution transform (search for "[body-substitution]" or "substitution skipped — a sentinel in this body").
Skill Doctor Shows 7-Day Token Attribution #
New
What
The /skill-doctor command now shows a 7d tokens column alongside the existing context, uses, and last used columns, reporting how many API tokens each loaded skill has consumed over the past 7 days of sessions on this machine.
Details
- Token counts are aggregated from local session transcripts (cached + cache-create + uncached + output)
- Skills with no attributed tokens still show
0 rather than being omitted - The column header is
7d tokens - Context cost is still shown separately as the tokens the skill's listing takes per turn
Evidence
New skill-doctor display (search for "7d tokens" or "attributionSkill"). Token aggregator (search for "NOd" with pattern $Od callback).
Forge Classification for PR/MR URLs #
New
What
PR and MR URLs are now classified by forge type — github, github-enterprise, gitlab, or bitbucket — based on URL shape, not just hostname. This information is surfaced to tools and hooks that work with pull/merge request URLs.
Details
- GitLab detected by
/-/merge_requests/ in the path - Bitbucket detected by
/pull-requests/ in the path - GitHub detected by matching known GitHub hostnames
- Anything else is classified as
github-enterprise - Described as "a naming hint, not host trust" — an unrecognised host with a PR-shaped path classifies as
github-enterprise
Evidence
Forge classifier (search for "/-/merge_requests/" or "forge classification derived from").
Worktree Safety: Full Path-Component Symlink Checks #
New
What
The worktree removal and creation code now walks each directory component in a path without following symlinks, refusing to write into or remove a directory if any ancestor is a symlink (O_NOFOLLOW at every level). Rootless worktrees (agent directories that lost their git root) are now handled with a dedicated safe-remove path.
Details
- New
assertDirChainReal function raises ELOOP/ENOTDIR at the first symlinked component removeAgentWorktree now handles the rootless case (no git root) separately: verifies the directory is inside .claude/worktrees/, is not a git repo, and requires an explicit job_delete_force source if the directory has any files- Hook-managed worktrees check for symlinks in the stored worktree path before invoking the remove hook
- Error messages distinguish: "stored worktree path is a symlink", "a component of the stored worktree path is a symlink", "path could not be verified — its resolution changed while being checked"
Evidence
Path verifier (search for "assertDirChainReal: dir must be strictly inside base" or "Refusing to write under symlinked or non-directory path"). Rootless remove (search for "Removed agent worktree with no git root at:").
FileHistory Rewind: Atomic Restore with Symlink Safety #
New
What
The file-history rewind (checkpoint restore) function now uses low-level file descriptors with O_NOFOLLOW to safely read backup files and write destination files, detecting symlink injection, hard links, FIFO substitution, and identity changes during the restore.
Details
- Backup source is opened with
O_RDONLY | O_NOFOLLOW | O_NONBLOCK; ELOOP/EMLINK means the backup became a symlink — restore is refused - Destination is opened with
O_WRONLY | O_CREAT | O_NOFOLLOW | O_NONBLOCK - Checks
nlink > 1 and refuses to overwrite hard-linked files - Verifies
/proc/self/fd/<n> path matches the expected parent directory (Linux only) - Re-verifies
dev/ino identity after opening, before truncating and writing - Returns
{ filesChanged, skippedLinks } instead of just an array; skipped-links count is surfaced to the caller
Evidence
Restore implementation (search for "FileHistory: [Rewind] Refusing to delete" or "destination is hard-linked").
Session Fork: More Specific Error Messages #
New
What
When a session cannot be forked, the error now gives a specific reason rather than a generic refusal.
Details
- Persistence off: "Can't fork: session persistence is off, so the new session would have nothing to start from."
- Restricted flags: "Can't fork: this session was started with launch flags (safe or bare mode, a custom system prompt, a tool allowlist, or restricted settings)..."
- Nothing to fork yet: "Nothing to fork yet. Send a message first."
- Messages have also been shortened and made direct (no more parenthetical asides about worktrees or agent view)
Evidence
Fork error messages (search for "Can't fork: session persistence is off" or "Can't fork: this session was started with launch flags").
Skill Creation Context Tailored by Session Type #
New
What
Claude now receives session-appropriate instructions about skill creation rather than a single generic message, covering four cases depending on what tools the session has.
Details
- Sessions with
save_skill tool available: "Skill files on disk are a read-only cache: editing them does not change the user's saved skill. To create or update a skill, use the save_skill tool." - Sessions with skill-proposal capability: "propose it with the
[propose_skill] tool." - Sessions with skill-delivery capability: "write it as a
.skill file … and send it with the [deliver_skill] tool." - All other sessions: "You cannot create or modify skills in this session. … say you can't do that here and point the user to their claude.ai settings."
- Plugin skills are an exception in all cases: customise through the
cowork-plugin skill if available.
Evidence
Skill-saving system prompt (search for "# Saving skills" or "Skill files on disk in this session").
MCP OAuth: Revoke Replaced Tokens at Logout #
New
What
When an MCP server's OAuth tokens are replaced (e.g., during re-authentication or token refresh), the old access and refresh tokens are now explicitly revoked at the server's revocation_endpoint before they are discarded.
Details
- Discovers the revocation endpoint from OAuth server metadata
- Supports both
client_secret_basic and client_secret_post authentication methods - Revokes refresh token first, then access token
- Logs failures with
Failed to revoke refresh token: / Failed to revoke access token: but does not block the replacement
Evidence
Token revocation (search for "Failed to revoke replaced tokens:" or "No replaced tokens to revoke").
Context Over-Limit Warning Improved #
New
What
The message shown when the context window is exhausted now distinguishes between the auto-compaction window and the raw model limit, and always names the specific action to take.
Details
- Auto mode:
Context exceeds the N-token limit by M tokens — run /compact or /clear to continue. - Non-auto mode:
Context is M tokens past the N-token compaction window — run /compact to reduce usage. - If
DISABLE_COMPACT is set: suggests only /clear
Evidence
Context limit message (search for "Context exceeds the" or "Context is" combined with "token compaction window").
CCR Agent Proxy: Selective Relay Mode #
New
What
New environment variables give fine-grained control over which hosts the CCR agent proxy relays to, allowing direct dial for selected hosts while tunnelling everything else.
Details
CCR_AGENT_PROXY_RELAY_MODE — set to selective to only tunnel traffic to hosts in the include list; all others use direct networkingCCR_AGENT_PROXY_INCLUDE_HOSTS — comma-separated list of hosts that the selective relay tunnels; unlisted hosts use normal networkingCLAUDE_CODE_AGENT_PROXY_GH_SHIM — enable a GitHub CLI shim inside the agent proxy environmentCLAUDE_CODE_AGENT_PROXY_GIT_CONFIG — pass a git config string to the agent proxy environment- A startup reachability probe is logged as
[agent-proxy] startup reachability probe: ok
Evidence
Selective relay log messages (search for "[agent-proxy] selective relay:" or "CCR_AGENT_PROXY_RELAY_MODE=selective but include-host").