mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-08-28 19:13:36 +00:00
* 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>
|
||
|---|---|---|
| .. | ||
| daemon | ||
| daemon-client-adapters | ||
| daemon-ui | ||
| development | ||
| examples | ||
| tools | ||
| _meta.ts | ||
| architecture.md | ||
| channel-plugins.md | ||
| contributing.md | ||
| qwen-serve-protocol.md | ||
| roadmap.md | ||
| sdk-java.md | ||
| sdk-python.md | ||
| sdk-typescript.md | ||