DEV Community

Ahab
Ahab

Posted on Originally published at indieseek.co

Qwen Code 0.22 Tool Surface and Auto Permission Checklist

Originally published on IndieSeek.

Qwen Code 0.22: shrink the tool surface before enabling auto approvals

Quick answer

Qwen Code v0.22.0 makes one built-in tool safer by default and one approval mode easier to reach from SDKs. list_directory is now opt-in: it is not registered or sent to the model unless you enable tools.listDirectory.enabled or explicitly include it in coreTools. Python and Java SDK startup options now accept auto, matching the CLI and TypeScript SDK. In that mode, an LLM classifier evaluates each tool call and automatically approves actions it classifies as safe while blocking risky ones.

These changes do not make auto a least-privilege policy. Qwen has three different control layers: which tools are registered, which calls skip confirmation, and where an approved call can execute. Treat them separately, inspect the actual tool surface, and keep default approval until harmless negative canaries pass.

Who this is for

This guide is for teams embedding Qwen Code through the CLI, Python, Java, or TypeScript SDK and searching for a safe alternative to --yolo. It is especially useful with local OpenAI-compatible backends, custom agents, MCP servers, or unattended repository jobs where extra tool schemas and ambiguous approvals create real operational risk.

If the repository itself may be untrusted, pair this rollout with the Qwen workspace-trust checklist. Workspace trust decides which project configuration may load; this article decides which tools the running agent can see and how their calls are approved.

What changed in 0.22—and what did not

Layer Stable v0.22.0 behavior What it does not prove
Tool registration list_directory is off by default; settings or coreTools can restore it That every filesystem tool is disabled, or that non-core tools are covered
Invocation approval Python and Java SDKs accept auto; an LLM classifier evaluates calls A deterministic allowlist, human approval, or safe execution
Runtime containment Qwen's own Autofix workflow binds a pulled sandbox image to its digest That every user-created Qwen sandbox or runner has equivalent isolation

The distinction matters because stable TypeScript SDK documentation describes coreTools as a registration allowlist, while allowedTools and permissions.allow bypass confirmation for matching calls. Qwen's stable permission-manager tests also show that MCP, Skill, Agent, and several synthetic tools are separate from the built-in coreTools surface. A short list of core tools is therefore a useful reduction, not proof that the complete session has only those capabilities.

Use a three-layer authority matrix

Question Control to inspect Evidence to keep
Can the model see this tool? coreTools, tools.listDirectory.enabled, disabled tools, extension/MCP registration /tools capture plus outbound tool-name list
Can this call run without asking? Approval mode, permissions.allow, permissions.ask, permissions.deny, SDK callback Tool name, redacted arguments, rule matched, decision source
What can an approved call reach? Sandbox, workspace boundary, process identity, filesystem/network policy Disposable write/read probes and denied neighboring action

Never use evidence from one row to certify another. A hidden tool might still be reachable through MCP. A visible tool can still require approval. An auto-approved call can still be confined—or dangerously unconstrained—by the host runtime.

A six-step rollout workflow

1. Pin the exact executable

Run /about and record the reported Qwen Code version, commit when available, runtime, model/provider, approval mode, sandbox state, and workspace. This guide was checked against stable tag v0.22.0, commit 1c3a385d9bc83e0b2a1ce5a24454ce1d090595fb. Do not use a nightly build to claim stable behavior.

2. Start with a small registered core

Use a disposable repository and default approval. A canary session can start with:

qwen --approval-mode default --core-tools read_file,grep_search,glob
Enter fullscreen mode Exit fullscreen mode

Confirm /tools does not show list_directory, editing, or shell execution. Then deliberately ask for a directory listing and verify Qwen uses glob or reports that list_directory is unavailable. If the workflow truly needs the old tool, enable it explicitly and repeat the inventory; do not restore it merely to silence a prompt.

3. Verify the outbound schema, not only the UI

A public issue filed against exact 0.22.0 reports one setup where /tools looked reduced but the local OpenAI-compatible backend still received the full built-in tools array. This is one user report, not a universal finding, but it gives a valuable canary: capture only outbound tool names through a recording proxy or provider debug log and compare them with /tools. Redact arguments, prompts, credentials, paths, and file content.

If the two inventories disagree, stay in interactive mode. Do not treat a settings file or a smaller UI list as sufficient proof.

4. Test approval separately

Keep the registered tool set fixed and compare default with auto using harmless calls:

  • Read a known fixture inside the disposable workspace.
  • Request a write to a disposable file and record whether the call asks, is approved, or is blocked.
  • Request an obviously out-of-scope neighboring action without using a real secret or destructive command.
  • Add an explicit deny for that neighboring action and prove it remains denied.

auto is a classifier decision, so require the audit record to say decision_source=classifier. Do not rewrite it as policy allow or human approved.

5. Run seven canaries

  • list_directory is absent by default.
  • Explicit opt-in restores it and a restart makes the change observable.
  • A built-in tool omitted from coreTools is unavailable to the session.
  • The outbound tool-name inventory matches the intended registered surface.
  • default prompts for the disposable write.
  • auto records its classifier decision without silently becoming yolo.
  • The same denied neighboring action stays denied in both modes.

For MCP, Skills, and custom agents, add separate inventory and denial tests. They are not automatically certified by the built-in-core canaries. Use the MCP safe-replay checklist when a permitted call can change external state.

6. Promote by action class

Start with read-only repository exploration. Add bounded edits only after rollback and diff review work. Keep shell, network writes, publishing, billing, deployment, secrets, and destructive filesystem actions on explicit human approval or deterministic policy. A sandbox reduces consequences; it does not make a classifier an authority to spend money, publish content, or destroy state.

Decision tree

Is the tool required for this task?
  no -> do not register it
  yes -> can its scope be reduced further?
           yes -> narrow core/MCP registration and inventory again

Does the call change state or cross a trust boundary?
  yes -> explicit human or deterministic approval
  no -> run harmless default-mode canary
          did schema, decision, and containment evidence agree?
            no -> keep interactive and fix the boundary
            yes -> consider a bounded auto-mode pilot
Enter fullscreen mode Exit fullscreen mode

Common mistakes

  • Treating permissions.allow as proof that unlisted schemas were never sent.
  • Calling auto “safe mode” or a deterministic allowlist.
  • Assuming coreTools covers MCP, Skills, custom agents, and every synthetic tool.
  • Enabling list_directory because an old prompt names it, without checking whether glob already completes the task.
  • Testing with real credentials, production repositories, or destructive commands.
  • Calling Qwen's Autofix digest binding a guarantee for every user sandbox.
  • Recording only the final tool result and losing the version, registered surface, matched rule, and decision source.

Copyable acceptance record

qwen_version / commit / install_channel / runtime:
workspace / provider / model / sandbox:
registered_core_tools / mcp_tools / skill_tools / agent_tools:
outbound_tool_names_match_inventory: yes | no | not-observable
approval_mode / permission_rules / sdk_callback:
canary / tool / redacted_scope / expected / actual:
decision_source: human | deterministic-rule | classifier | none
containment_result / denied_neighbor / rollback_result:
promotion: hold | read-only | bounded-edit | human-required
Enter fullscreen mode Exit fullscreen mode

FAQ

Is auto safer than yolo?

It is more selective: auto uses an LLM classifier, while yolo automatically approves all tool calls. But selective does not mean deterministic or sufficient for high-impact actions. Keep explicit approval for sensitive state changes.

Why is list_directory disabled if Qwen can still inspect files?

The release says glob covers directory listing in most cases, so removing the near-duplicate tool reduces prompt and selection surface. It is not a general filesystem-access switch; other read tools still exist.

Should I use permissions.allow or coreTools to shrink schemas?

For stable v0.22.0, treat coreTools as the built-in registration allowlist and permissions.allow as invocation auto-approval. Then verify the actual outbound tool names. Do not rely on naming or migration text alone.

Sources


Read the maintained version on IndieSeek.

Top comments (0)