qwen-code/docs/developers
易良 99a3a08e17
feat(daemon): make serve new-file mode configurable (QWEN_SERVE_NEW_FILE_MODE) (#9364)
* feat(daemon): make serve new-file mode configurable (QWEN_SERVE_NEW_FILE_MODE)

qwen serve's atomic text writers created every NEW file at 0600
unconditionally, ignoring the daemon process umask with no way to opt
out (issue reporter runs the daemon under a systemd UMask=0002 drop-in
and every agent-created file diverged from the group-readable repo
convention).

Add a NewFileModePolicy ('owner' = 0600 default, 'system' = standard
0o666 & ~umask) on createWorkspaceFileSystemFactory, threaded through
writeTextAtomic / writeTextOverwrite / edit / editAtomic and the
same-host external tool-write route. resolveBridgeFsFactory reads
QWEN_SERVE_NEW_FILE_MODE ('owner' | '0600' | 'system',
case-insensitive); unrecognized values warn on stderr and keep the
fail-closed 0600 default.

Existing-file mode preservation is unchanged, binary uploads stay
0600, and the default behavior is bit-for-bit unchanged.

Closes #9250

* fix(serve): register the new-file-mode env access and harden the knob's docs and wiring

- process-env guard: register the whole-object process.env access in
  fs-factory.ts (the parseNewFileModePolicy default parameter) so the
  serve process.env guard suite passes — the PR-caused CI failure.
- resolveNewFileModeBits: read the umask lazily only when the 'system'
  policy consumes it; the default 'owner' path no longer issues two
  umask(2) syscalls per write.
- docs: state that the literal `0600` is an alias for `owner` (no other
  octal modes) in both tables; correct the binary-upload route to
  POST /file/upload; replace the phantom per-write mode-override clause
  with the factual statement that agents cannot pass one.
- test: pin the resolveBridgeFsFactory env seam — with newFileMode
  uninjected, the policy must come from process.env.QWEN_SERVE_NEW_FILE_MODE
  (regression-mutates to a hard-coded default are now caught).

* fix(serve): keep QWEN_SERVE_NEW_FILE_MODE out of project .env files

R2-1: the daemon boot path loads the primary workspace .env into
process.env before any fs factory is built, and the new-file-mode key was
not in PROJECT_ENV_HARDCODED_EXCLUSIONS — a project-controlled file could
flip the documented fail-closed 0600 posture to umask-derived modes
daemon-wide with no warning (system is a valid value), widening the
visibility of agent-created files on a multi-user host. Register it as a
process-scoped operator knob like the other daemon posture keys, with a
security test pinning the exclusion.

* test(serve): pin the fail-closed 0600 default through the resolveBridgeFsFactory seam

The env-wiring test only covered the 'system' half of the seam; the
unset-env default (owner -> 0600) had no coverage through the same
production path — a regression making the unset default resolve to
'system' would flip every agent-created new file to umask-derived
modes with no test failing (mutant verified surviving all 13 prior
tests; this mirror test fails it with 0o664 vs 0o600).

---------

Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com>
2026-08-18 03:42:35 +00:00
..
daemon feat(daemon): make serve new-file mode configurable (QWEN_SERVE_NEW_FILE_MODE) (#9364) 2026-08-18 03:42:35 +00:00
daemon-client-adapters docs(serve): Close multi-workspace hardening gaps (#7019) 2026-07-16 17:33:53 +00:00
daemon-ui fix(web-shell): stop rendering unrecognized daemon events in transcripts (#8812) 2026-08-10 00:51:57 +00:00
development feat(telemetry): Trace main agent invocations (#9107) 2026-08-14 02:50:22 +00:00
examples docs(serve): Close multi-workspace hardening gaps (#7019) 2026-07-16 17:33:53 +00:00
tools fix(core): Avoid replaying unsafe MCP tool calls (#8387) 2026-08-03 11:04:38 +00:00
_meta.ts docs(daemon): Refresh daemon docs in English (#5144) 2026-06-15 22:38:01 +08:00
architecture.md docs: refresh architecture overview (#8325) 2026-08-02 02:45:00 +00:00
channel-plugins.md docs(channels): Document loops and proactive delivery (#7628) 2026-07-26 07:32:18 +00:00
contributing.md revert: remove local PR verification gate (#7031) 2026-07-16 11:24:38 +00:00
qwen-serve-protocol.md feat(serve): Add workspace session live-state endpoint and catalog version (#9261) 2026-08-17 15:01:50 +00:00
roadmap.md docs: standardize GitHub Actions capitalization (#6367) 2026-07-06 06:55:07 +00:00
sdk-java.md fix(serve): Coordinate caller-supplied session IDs (#8415) 2026-08-09 07:31:30 +00:00
sdk-python.md doc[sdk-python] Expand Python SDK usage documentation (#3995) 2026-05-12 15:27:00 +08:00
sdk-typescript.md fix(serve): Coordinate caller-supplied session IDs (#8415) 2026-08-09 07:31:30 +00:00