Qwen Code’s June 20 Safety Fixes Are About Consent and Boundaries

Qwen Code’s June 20 Safety Fixes Are About Consent and Boundaries

The most important Qwen Code work on June 20 was not a model upgrade. It was a trio of small safety fixes about consent, path boundaries, and ignore-file semantics. That sounds painfully specific because it is. It is also exactly where local coding agents earn or lose trust.

Shortly after v0.18.4 shipped, Qwen Code merged fixes for three seam-level problems: Plan Mode now requires explicit opt-in instead of treating ordinary planning language as permission to switch modes; shell directory validation now uses real workspace-boundary checks instead of prefix matching; and .gitignore/.qwenignore parsing now distinguishes parent traversal from legitimate project files whose names start with two dots. None of this will trend on Hacker News. All of it belongs in an agent-runtime review checklist.

“Plan this” should not rewrite the execution contract

PR #5433, merged June 20 at 09:53 UTC, changes Qwen Code’s Plan Mode behavior so the assistant keeps planning in the current mode unless the user explicitly asks for Plan Mode, has already enabled it, or confirms the switch. The patch is modest — 51 additions, 21 deletions, six files changed — but the product implication is larger than the diff.

The issue behind it, #5428, came from a Windows user running Qwen Code v0.18.3 with model qwen3.6-27b, Node.js v22.22.2, on win32 x64. The complaint was refreshingly direct: “I am not a Plan mode guy and I hate switching between modes.” The expected behavior was equally clear: “No plan mode attempt. Just plan in whatever mode it is running.” In other words, the user was not objecting to planning. They were objecting to the runtime interpreting a normal instruction as consent to change modes.

That distinction matters. “Plan this migration” is ordinary language in a coding session. It should not silently change the agent’s safety boundary. If a user has chosen an approval mode — especially an AUTO or YOLO-style mode where the runtime contract is already explicit — the model should not be able to infer a different mode because a prompt contains the word “plan.” Modes are policy. Policy changes require explicit consent.

The fix’s test plan captures the right behavior: ask Qwen Code to plan or investigate while in a non-plan approval mode, and it should produce a plan or continue read-only investigation in the current mode instead of calling enter_plan_mode merely because the task involves planning. Explicit /plan, approval-mode toggles, or direct user requests still work. That is the right split: preserve the feature, remove the surprise.

Prefix checks are not security boundaries

The second fix is even more familiar to anyone who has reviewed filesystem code. PR #5454, merged at 10:51 UTC with 25 additions and six deletions, replaces shell directory validation with WorkspaceContext.isPathWithinWorkspace. It also adds a regression test for sibling-prefix workspaces such as /tmp/project and /tmp/project-other.

Issue #5453 explains the bug in one line: the shell tool validated explicit directory values with params.directory!.startsWith(wsDir). That means /tmp/project-other passed when /tmp/project was the registered workspace. It starts with the same string. It is not inside the same directory.

In an ordinary CLI, this is a bug. In a coding agent, it is a safety-boundary failure. The issue called the directory parameter a “non-overridable shell safety gate before auto/YOLO execution.” That phrasing is doing real work. If the runtime uses the directory field to decide where shell execution is allowed, then a string-prefix bug can move an agent outside its intended workspace before any model reasoning, approval UI, or sandbox marketing has a chance to help.

The practitioner takeaway is blunt: audit every path-boundary check in your agent stack. Not just shell directories. File reads, file writes, patch application, artifact export, extension installation, cache directories, MCP server paths, logs, temporary files, and workspace discovery all need normalized, segment-aware containment checks. String vibes are not enough. Windows paths, symlinks, case sensitivity, encoded separators, and sibling prefixes are not edge cases when the product’s promise is “the agent will operate only here.”

Ignore files are part of the policy surface

The third fix, PR #5458, landed within the same hour. It changes .gitignore and .qwenignore parsing to use the shared path-boundary helper and adds regressions for project files whose names start with ... The issue, #5457, is the mirror image of the workspace bug: both parsers used relativePath.startsWith('..') to detect paths outside the project root, which also matched valid in-project filenames like ..secret.log.

The concrete failure is easy to miss and easy to regret. If .qwenignore contained ..secret.log, then parser.isIgnored('..secret.log') returned false because the file was treated as outside the root before ignore rules ran. The traversal guard accidentally bypassed the ignore rule for a valid local file.

That sounds like a naming oddity until the file is a backup secret, generated log, internal data export, model trace, or proprietary artifact a team intentionally excluded. Ignore files are not just developer convenience. For agents, they are part of the repo’s instruction and policy surface: what not to inspect, upload, mutate, summarize, or hand back to a model. If an agent bypasses ignore semantics because a helper confuses “starts with two dots” with “parent traversal,” the runtime has turned a filename edge case into a policy leak.

This is where agent safety starts looking less like AI theory and more like systems engineering. The discourse tends to focus on whether the model will refuse dangerous instructions. Useful question. In day-to-day coding agents, the failures often arrive through path joins, mode names, ignore globs, URL schemes, environment variables, and timeout defaults. A model can be aligned and still be hosted inside a runtime that makes the wrong operation easy.

What teams should actually test

If you are evaluating Qwen Code or any competing local coding agent, this patch stack gives you a practical test plan. Ask the agent to “plan” while it is in a non-plan mode and verify that it does not silently change the execution contract. Try sibling-prefix directories like /tmp/project and /tmp/project-other. Create ignored files named with leading dots, including names that look suspicious but are valid. Test Windows drive letters, UNC paths, symlinks, case-insensitive filesystems, encoded separators, and workspace roots with overlapping prefixes. Then do the same through every surface: CLI, daemon, Web Shell, extension manager, MCP tools, and any background workflow runner.

Benchmarks will not catch this. A coding benchmark rewards patch generation. It usually does not ask whether startsWith was used as a security boundary. It does not verify that ignore rules survive odd filenames. It does not check whether a mode switch respected consent. But those are the failures that determine whether engineers keep using an agent after the novelty wears off.

The caveat is packaging. These fixes landed after the v0.18.4 release tag, so readers should treat them as June 20 main-branch safety fixes and verify the next stable or nightly build before assuming they are present in an installed package. That caveat does not weaken the story. It sharpens it. Qwen Code shipped a major runtime release, then immediately patched trust-boundary behavior where users and maintainers found real seams.

The editorial read: this is the unsexy work serious agent projects have to do. Model safety gets the keynote slides. Runtime safety is explicit mode consent, segment-aware path checks, and ignore-file semantics that do not fall over when a filename begins with two dots. If those are wrong, your local coding agent is just a confident shell script with better branding. Qwen Code caught and fixed three of them quickly. Good. Now everyone else should grep their own runtime.

Sources: Qwen Code PR #5433, issue #5428, PR #5454, issue #5453, PR #5458, issue #5457.