mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-11-07 06:19:43 -10:00
* feat(managed-agent): give the Hosted Harness its Broker through the environment
The Hosted Harness reached the Runtime Broker only through command-line
options, so the shipped unit expanded the Broker token into argv, where
any local user can read it, and the token was stored again in
server.env for the control plane. A busy Harness port also moved the
Harness to another port that the control plane could not reach.
harness.env now carries QWEN_MANAGED_RUNTIME_BROKER_URL and
QWEN_MANAGED_RUNTIME_BROKER_TOKEN, which qwen serve already reads and
deletes from its environment, and the unit no longer passes Broker
arguments. Every secret gate lists the token too: core's child and
${VAR} denylist, the ACP scrub list, the channel worker environment and
the control plane's Runtime worker filter. The Hosted Harness profile
fails on a busy port instead of moving.
The Harness credentials file may carry the Broker token for the control
plane, refusing a second direct copy and binding nothing on a conflict;
both Broker lines follow the strict credential rules. Preflight adds a
broker-url row that compares the file's URL with the Broker's address
and warns when the file has none, and the broker row's fix names the
file only when startup read it. The bootstrap, templates, systemd unit
and guides keep the token in harness.env only and tell upgraded hosts
to replace QWEN_HOSTED_HARNESS_BROKER_ARGS.
* fix(managed-agent): check the Harness Broker URL against the actual listener
The broker-url preflight row matched loopback addresses by class, so a
Broker bound to 127.0.0.1 passed a file URL on 127.0.0.2. It failed any
URL that differed from the bind address, although a proxy or TLS front
end may forward it. And it ignored the scheme once a port was given, so
https to the plain-HTTP Broker passed.
The row now passes only a direct http URL: the Broker's port, and a host
that resolves to the bound address itself or, for a wildcard bind, to an
address of this machine. https to that same listener fails, since the
embedded Broker serves plain HTTP. Any other URL warns that a proxy may
forward it, which preflight cannot verify, so it no longer fails --check.
* fix(managed-agent): hold the Harness Broker URL to the Harness's own rules
- broker-url first applies the rules managed-runtime-broker-url.ts applies
at Harness startup (an http or https origin, plain http only on loopback),
reads the host of a registry authority such as an underscore name, and
names the direct loopback URL, or the TLS-terminating proxy for a
non-loopback bind, in its fix.
- A broker check fails a non-loopback bind without
runtime-broker.allow-non-loopback, which the Broker refuses at startup.
- The Harness credentials file requires the Broker URL and token together,
refuses a key containing whitespace such as `export KEY=value` (systemd
ignores it, a shell assigns it), and lets the URL bracket an IPv6 literal.
- qwen serve warns when --managed-runtime-broker-token is on the command
line; serve tests cover the environment fallback, its removal and flag
precedence.
- The upgrade runbook names the server.env token to delete, the server
README lists the Broker prefix among the stripped ones, and the bootstrap
test checks stdout for every generated secret.
* fix(managed-agent): read the Harness Broker URL the way the Harness parses it
The broker-url preflight row predicted the Harness with java.net.URI and a
hand-written loopback check, which disagree with Node's WHATWG URL parser in
both directions. It failed http://127.1:4182, http:/127.0.0.1:4182 and
http://127.0.0.1:4182/./, which the Harness takes as its loopback origin, and
passed http://::1:4182, http://127.0.0.08:4182 and port 99999, which the
Harness refuses before it starts.
- HarnessBrokerUrl follows the URL Standard for the part of an http(s) URL a
credentials-file value can reach: the scheme, the slashes after it, the
IPv4, IPv6 and ASCII-domain host parsers, the port and the path's dot
segments. An xn-- label needs IDNA, so the row warns that it cannot read
that URL instead of failing.
- managed-runtime-broker-url.fixtures.json records the Harness's verdict for
each spelling; the CLI test holds the Harness to it and HarnessBrokerUrlTest
holds preflight to it.
- The fix's direct URL is built from the address the bind resolves to, so a
::ffff:127.0.0.1 bind yields http://127.0.0.1:4182.
- Docs: the upgrade backs up server.env and harness.env and a rollback
restores them; the guide names the row's no-URL warning; the operator pages
allow [ and ] in the URL key; the server README states the URL/token pairing
rule.
* fix(managed-agent): keep the Broker pair across a daemon update restart
A daemon self-update replaces `qwen serve` through execve, which keeps
the PID, so systemd never hands the replacement the Broker pair from
harness.env again, and serve has already removed the pair from its own
environment. Hand the update restarter the resolved pair and add it to
the replacement's environment only, beside the server token.
Also from the same review round:
- preflight decides the plain-http, path and ends-in-a-number refusals
for a host with an xn-- label without IDNA, and leaves only an https
URL to such a host unclassified;
- the Java fixture loop allows only the two documented approximations, a
scheme or path read before the host and an xn-- host read without
IDNA; the shared fixture gains cases for both;
- the CLI fixture loop fails on a verdict it does not know instead of
passing on any throw;
- the broker-url row brackets an IPv6 Broker address;
- the credentials file refuses an empty Broker URL or token, which the
Harness takes as set and then refuses to start with;
- the deployment guide no longer says a wildcard Broker bind is reached
through a proxy.
* fix(managed-agent): warn on an IPv6 URL for an IPv4 wildcard Broker bind
The JDK binds 0.0.0.0 to IPv4 alone under -Djava.net.preferIPv4Stack=true,
so a Harness given http://[::1]:P cannot reach a Broker bound there, while
the broker-url row passed it as served. Preflight cannot see the server's
JVM options, which may come from an environment it does not share, so a
wildcard bind now serves only addresses of its own family, and an IPv6 URL
to the IPv4 wildcard warns and names the IPv4 loopback URL. An https URL
there still fails. The JDK binds :: only on a dual-stack socket, so the
IPv6 wildcard keeps serving IPv4 too.
* fix(managed-agent): warn on an https Broker URL across address families
When the Broker binds the IPv4 wildcard and the URL names an IPv6
address, the Broker's own socket takes it only from a dual-stack JVM.
Under -Djava.net.preferIPv4Stack=true another listener, such as a TLS
proxy, may hold that address and forward to the Broker, so preflight
cannot tell an https URL there apart from a working deployment. It now
warns for both schemes and fails https only for an address the Broker's
plain-HTTP socket takes in either mode.
---------
Co-authored-by: 易良 <[email protected]>