mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-11-07 06:19:43 -10:00
* feat(managed-agent): read the Harness credentials from one file The Hosted Harness and the control plane share a bearer token and a capability digest, which the reference distribution stored twice, in harness.env and server.env, so every rotation or hand edit had to change both files identically. QWEN_MANAGED_AGENT_HARNESS_CREDENTIALS_FILE now names the Harness's own environment file. The control plane reads QWEN_SERVER_TOKEN and QWEN_HOSTED_HARNESS_CAPABILITY_DIGEST from it into its configuration, never into its process environment, and refuses to start when the file is combined with a direct token or digest, or lacks either key. Preflight reports the file's permissions and points credential fixes at it. The bootstrap, templates, systemd instructions and guide store the credentials once. * fix(managed-agent): refuse credential lines the Harness reads differently The credentials parser accepted a subset of the environment-file grammar and silently mis-read the rest. A continuation, an escape, an unterminated quote, text after a closing quote or a `$` expansion gave the control plane a different value than systemd or a shell gave the Harness, while preflight passed. Such lines now fail startup, naming the file and line but never the content. The file is now read once and only while the Harness is enabled, and an unreadable file reports its exception type in the validation row. Preflight shares one secret-file permission policy between the config and credentials rows. The credentials row also fails an unreadable file and reports an unusable path instead of aborting, and the harness row fails the shipped placeholder token. Tests now pin the run order, values containing `=`, world-readable files, the file-aware 401 fix and the shipped harness.env.example keys. The systemd READMEs describe the warning as a warning. * fix(managed-agent): accept only credential lines both readers take literally Credential values in the Harness credentials file may now contain only letters, digits and ._:/+=-, and whitespace around `=` or a carriage return is refused: a shell runs `KEY = value` as a command and keeps a trailing \r, so the control plane and the Harness could hold different digests while every preflight row passed. When startup refuses the file, the harness row now skips its probe instead of sending whatever credentials are left bound, and the file is applied atomically. run() delegates to checks(args) so a test can pin the credentials row after the harness row.