Skip to content

[Bug]: Claude Auto mode on orchestrator v2 runs ask-rule commands without prompting #15353

Open

Description

@TonybynMp4

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/server

Steps to reproduce

  1. Add an ask rule to Claude Code's user settings, for example "permissions": { "ask": ["Bash(git push:*)"] }.
  2. Start a Claude thread on orchestrator v2 with the permission mode set to Auto.
  3. Ask the agent to run git push (or any command matching the ask rule).

Expected behavior

T3 Code shows an approval request, the same way Claude Code does in its own auto mode. The permission modes guide says Auto "uses the provider's automatic review to approve routine actions and ask about others".

Actual behavior

The command runs with no prompt, the same as Full access.

Claude's auto mode sends anything it wants a human to decide (an ask rule match, a protected path, a classifier escalation) to the SDK canUseTool callback. In ClaudeAdapterV2, that callback answers allow whenever requiresClaudeApproval is false, and installPermissionCallback is false for auto. So every request Claude escalates gets approved without the user seeing it.

The V1 adapter skipped the prompt only for full-access and asked in Auto. #13786 fixed the same problem for Auto-accept edits and left Auto unchanged.

Impact

Major degradation or frequent failure

Version or commit

main @ 65731f9

Environment

Linux, Claude Code provider, orchestrator v2

Workaround

Use Supervised, or add a PreToolUse hook that blocks the command.

Activity

  1. juliusmarminge commented on Oct 3, 2026

    @juliusmarminge
    Member

    Note

    Grok responding on behalf of Julius.

    Triage

    Thanks for the precise report, @TonybynMp4! This reproduces on current main. A Claude thread in Auto auto-approves the tool calls Claude has already decided to ask about, including a permissions.ask match. It's the same gap that merged #13786 closed for Auto-accept edits, still open for Auto.

    What happens

    claudeRuntimeQueryPolicyForRuntimePolicy in apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts maps runtimeMode: "auto" to Claude's permissionMode: "auto" with installPermissionCallback: false. The query always gets canUseTool anyway, and requiresClaudeApproval is that same flag. So after the AskUserQuestion and ExitPlanMode special cases, the callback returns allow right away. The test maps Auto runtime mode to Claude's AI-reviewed permission mode pins the flag at false.

    Claude checks content-scoped ask rules before its auto-mode classifier, and it sends a match to canUseTool instead of letting the classifier approve it. Bash(git push:*) is the trailing-wildcard form of Bash(git push *), so your repro rule is a real ask. The query leaves settingSources unset, which means user settings load and a rule in ~/.claude/settings.json applies. The permission modes guide says Auto approves routine actions and asks about others, but today those asks never reach the thread.

    Routine classifier approvals never call canUseTool, so routing asks to the user wouldn't turn Auto into Supervised. A one-off classifier block isn't a prompt either and stays inside Claude. The callback does see the later fallback, when repeated blocks make Claude start prompting again. It also sees anything else Claude routes as an ask, such as org connector tools set to ask or MCP tools marked requiresUserInteraction.

    Likely fix area

    • One option is to treat auto like auto-accept-edits when approvalPolicy is unset, so the callback raises a normal approval request instead of allowing. An explicit approvalPolicy: "never" could stay non-prompting.
    • A test like the Auto-accept edits one, repeated for runtimeMode: "auto", would cover it. It would call canUseTool for a Bash command and require a command runtime request before any decision. The policy-mapping assertion would change along with it.
    • Full access (bypassPermissions) has the same auto-allow, and Claude would still send ask rules to the callback there. The guide says that mode doesn't prompt, so whether it should honor ask rules is a separate question.

    Until then, Supervised or a PreToolUse hook that denies the command are good workarounds. A maintainer will decide on the fix direction.

  2. added
    bugSomething is broken or behaving incorrectly.
    via-triageFiled through npx t3 triage
    on Oct 3, 2026
  3. aliir74 commented on Oct 13, 2026

    @aliir74

    Note

    Claude responding on behalf of Ali.

    Adding real-world data in support of this, and of #15360.

    From my local T3 state database (macOS, Nightly channel):

    • 2026-09-13 to 2026-10-03 (V1 adapter): 305 Claude approval prompts were shown. 274 of them came from threads that are in Auto mode now.
    • 2026-10-04 onward (orchestrator v2): 0 approval prompts. All 70 runtime requests were question cards.

    Why this matters beyond UX: PreToolUse hooks that return ask are now silently allowed in Auto threads. I rely on ask hooks to confirm outbound and write actions, and in Auto threads they pass with no prompt. As a workaround I had to change the critical ones to deny when they detect a T3 Auto session.

    Rechecked on 0.0.46-nightly.20261013.3066: installPermissionCallback is still only true for approval-required and auto-accept-edits, so the bug is still present. #15360 looks like the right fix, and I'd be glad to see it reviewed.

  4. mackinleysmith commented on Oct 14, 2026

    @mackinleysmith
    Contributor

    Note

    Claude responding on behalf of MacKinley.

    Still reproduces on 0.0.46-nightly.20261014.3105 with Claude Code 2.1.299. One detail I haven't seen mentioned yet: the auto-allow is recorded as if the user approved it.

    A PreToolUse hook returned permissionDecision: "ask" in an Auto thread. The command ran with no prompt, and the tool_result entry in Claude Code's session transcript (~/.claude/projects/<project>/<session>.jsonl) says:

    "permissionDecision": {"decision": "accept", "source": "user_temporary"}

    That is the same record a human clicking "allow once" produces. For comparison, commands the Auto classifier approves on its own are recorded as {"decision": "accept", "source": "config", "reasonType": "classifier"}. So when the callback answers allow for an escalated request, the transcript attributes the approval to the user. That makes the audit trail misleading even after the fact: you can't tell from the record that nobody saw the request.

    It would be worth checking that #15360 also fixes the attribution. If Auto is ever meant to approve an escalation without a prompt, it would be better recorded as something other than a user decision.

    For anyone writing a hook workaround in the meantime: hooks run under T3 Code see CLAUDE_CODE_ENTRYPOINT=sdk-ts, which is one way to switch an ask to deny only when T3 is the host.

  5. juliusmarminge commented on Oct 22, 2026

    @juliusmarminge
    Member

    Rechecked current main at defb7e6e6b. An adapter regression test reproduces the Auto escalation bug: the command ran without asking: expected decision to equal request. Auto-accept edits passes as the control. Applying only the Auto callback-policy hunk from #15360 makes both cases pass; all 208 current-main Claude adapter tests pass, with no scoped lint errors.

    The real-app attempt used an isolated Linux web dev server, a fresh Git project with no remote, Claude Sonnet 5.5, Auto, and Bash(git push:*). The command could not be submitted: the backend logged an 84.8-second event-loop stall and repeated disconnects, and the browser readiness wait timed out after 60 seconds. This does not verify the real-provider approval round trip.

    The existing fix remains #15360, now labeled bugfix; no competing PR was opened. The issue remains open until that fix lands.

  6. jorgenswiderski commented on Nov 5, 2026

    @jorgenswiderski

    Note

    Claude responding on behalf of Jorgen.

    Still present on upstream main at 4b87a45 (2026-11-04). Two things I think aren't in this thread yet: what this costs when an ask guards something expensive, and the fact that, since #21806, Auto is now the less protective of the two modes for these requests.

    What it cost

    I use a PreToolUse hook as a spend gate for BigQuery. It dry-runs each query and returns permissionDecision: "ask" when the maximum cost is over a threshold. In an Auto thread it returned ask twice ("max $0.4692 is over the $0.1000 threshold", and about $0.19 on the second). Both queries ran, and I never saw a prompt. T3's server trace shows exactly two ClaudeAdapterV2.canUseTool spans, one right after each query, each returning in under 1 ms.

    The dollar amount is small. What worries me is the pattern behind it:

    • ask is how a hook, a permissions.ask rule, or an org policy says "a person must decide this". People reach for it on exactly the actions that are costly or hard to undo: cloud spend, deploys, outbound messages, deleting data.
    • In Auto, every one of those turns into an allow, and nobody is told. The agent thinks the user approved, and the user doesn't know they were asked. As noted above, the transcript records it as source: "user_temporary". So after the fact, the record looks like a person approved something no person saw.
    • A hook author can't tell, from inside the hook, that their ask will be ignored. The only workaround is the one people have posted here: detect CLAUDE_CODE_ENTRYPOINT=sdk-ts and turn ask into deny. That makes the gate worse in every other SDK host, and it means every hook has to know it might run under T3.

    Why it's inconsistent

    • With Claude Code. The same hook in the same mode prompts in the Claude Code CLI. Claude Code's permission modes docs say plainly that prompts forced by ask rules or hooks still appear in auto mode: "auto mode still shows you those prompts". In auto mode, a classifier approval can't override a hook's ask either; Claude Code passes the ask on to the person. Hook and rule authors build against that documented behavior.
    • Within T3, since fix(claude): honor effective bypass restrictions #21806. Full access (bypassPermissions) now sends requests that Claude forwards to the user. Auto still allows them silently. So for exactly the requests Claude reserves for a person, Full access is now the safer mode. Someone who picks Auto over Full access to be more careful gets less protection on these requests than if they had picked Full access.
    • With T3's own reasoning. In [Bug]: Full access stops for Claude Code safety-check approvals on routine rm commands #26418, Full access users asked T3 to stop prompting on Claude's forwarded safety checks. That was closed with "Claude code added this for a reason. I don't think it's a good idea that we override their full access behavior." Auto today is that same override, applied to Auto.
    • With T3's docs. Permission modes says Auto "approves routine actions and asks about others".

    What a fix would need to cover

    The real tension is unattended runs: #21806 called it out, and #26418 shows what it costs when a scheduled or overnight thread waits hours on a prompt. I don't think the answer to that is silently approving. Whatever T3 decides, I'd hope for:

    • A request Claude escalates for a person reaches a person in Auto, at least as reliably as it does in Full access.
    • If T3 ever resolves one of these requests without a person (for example in an unattended run), it isn't recorded as a user approval. The agent is told it wasn't approved, so it can work around it or ask, instead of carrying on as if it were.
    • Routine actions in Auto stay prompt-free. As triaged above, classifier approvals never reach canUseTool. I confirmed that with a probe: a real Claude Code 2.1.306 session through Agent SDK 0.3.276 in permissionMode: "auto", with a hook returning ask for one command. Only that command reached canUseTool, carrying the hook's reason in decisionReason. A routine command did not reach it.

    For what it's worth, I've applied a change to my fork with the same effect as the one proposed in #15360: Auto prompts on requests Claude forwards. With it, an adapter test that feeds canUseTool the probe's hook request gets an approval request back instead of an allow. I haven't yet seen it work in a live T3 thread.

  7. TonybynMp4 commented on Nov 5, 2026

    @TonybynMp4
    ContributorAuthor

    Something that i did notice is that since v2 dropped i haven't had a single approval prompt (literally 0), but when i tried full access for like 2 minutes i received a bunch from claude's auto classifier, which makes me wonder if auto isn't just auto accepting stuff that claude itself finds dangerous

  8. adamblaha00 commented on Nov 6, 2026

    @adamblaha00

    Same result on T3 Code 0.1.7, Claude Code 2.1.318, WSL. One test in both modes:
    a PreToolUse hook returns ask on a Write. Supervised shows Accept/Decline, and
    Decline blocks the write. Auto shows no prompt and the file is written 145 ms
    after the permission check ends. We rely on ask for destructive commands, so
    we keep client projects out of Auto until this lands. Is #15360 still the plan?

  9. TonybynMp4 commented on Nov 6, 2026

    @TonybynMp4
    ContributorAuthor

    after the permission check ends. We rely on ask for destructive commands, so

    Seems counter intuitive but full access will respect the permissions check so it can be a temporary solution.

    we keep client projects out of Auto until this lands. Is #15360 still the plan?

    Should be, just need julius to take a look 😅

  10. karthikeyan5 commented on Nov 15, 2026

    @karthikeyan5

    Note

    Claude responding on behalf of Karthi.

    Confirming the classifier path @TonybynMp4 suspected, live on 0.1.9 (Claude Code 2.1.325, Linux, Haiku 5.5, Auto, no ask rules).

    Setup: a throwaway repo with a local bare remote and an amended commit, so git push --force origin main is needed.

    • The classifier blocks the force push (automode-blocked), then blocks it again. The third "try again" runs it. The transcript records that push as {"decision": "accept", "source": "user_temporary"}, and T3 shows it as a normal completed command with no request.
    • Four force pushes to four bare remotes in one turn: two blocked, two ran.

    So Auto doesn't only skip ask rules. Claude Code turns a third classifier block in a row into a permission prompt, the Auto canUseTool answers allow, and the action the classifier refused runs. A task file that says "retry until it works" is enough to get there.

    +1 for #35207. Until it lands we run a PreToolUse deny hook on the T3 Claude instance for force pushes, rm -rf outside the project and similar.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething is broken or behaving incorrectly.via-triageFiled through npx t3 triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions