Commit graph

12 commits

Author SHA1 Message Date
Shaojin Wen
e7fe14ee83
docs(managed-agent): generate the server configuration reference from its metadata (#15939)
* docs(managed-agent): generate the server configuration reference from its metadata

The server has about 180 settings, 84 of them mapped to QWEN_MANAGED_AGENT_*
variables, and no list of them with their variables, defaults and limits:
operators read a 2000-line developer README for them.

- The server module runs spring-boot-configuration-processor once more,
  over ManagedAgentProperties only (the two Druid beans share a prefix,
  which the processor refuses), and writes the configuration metadata.
  The compiled classes are unchanged. runtime-broker.ssh is marked
  @NestedConfigurationProperty, and STRICT_HARNESS_KEYS @Getter(NONE), so
  the metadata lists the one and not the other.
- configuration-descriptions.json holds an English and a Chinese
  description for each setting and section.
- scripts/generate-managed-agent-configuration-reference.mjs writes
  docs/users/managed-agent-configuration-reference{,.zh-CN}.md from the
  metadata, the packaged application.yml (variables and defaults), the
  ${qwen.managed-agent.*} placeholders in the main sources (settings read
  outside the properties class) and the descriptions. --check fails on a
  setting without a description, a description of no setting, or a stale
  page; the reference workflow runs it after the Java build.
- The archive ships the pages as docs/configuration{,.zh-CN}.md, and the
  deployment guide and the README link them.

* fix(managed-agent): link the shipped documents by their archive names

The archive renames each document it ships, so a link written against
the repository, such as the configuration reference's language switch or
the guide's link to it, named a file the archive does not have. The
packager now points every link between shipped documents at the
document's name in the archive and leaves every other link as written.

* build(managed-agent): take the configuration processor's version from the BOM

spring-boot.version is defined nowhere in this build, so the processor
path's <version> only resolved because the compiler plugin falls back to
dependency management. Say so by naming no version.

* test(managed-agent): name no tracked Markdown in a link fixture

classify-profile.test.mjs requires every Markdown file a test names to be
in TEST_READ_MARKDOWN, and the kept-link fixture's docs/runtime-broker.md
matched packages/managed-agent-server/docs/runtime-broker.md, which no
test reads. The fixture only needs a link to a file the archive does not
ship, so it names one that does not exist.
2026-10-31 03:23:30 +08:00
jinye
f3af3dd857
refactor(managed-agent): Split server into Maven modules (#15871)
* refactor(managed-agent): split server into Maven modules

Separate contracts, orchestration, persistence, adapters, assembly, and verification while retaining the existing service delivery model. Move tests and build consumers together and document local evidence and pending CI acceptance.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* refactor(managed-agent): reduce configuration and SDK boilerplate

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* refactor(managed-agent): narrow contracts and simplify test scaffolding

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(managed-agent): repair verification after module migration

Resolve shared fixtures and worker paths from the Maven module root, update CI packaging assertions, and align existing test fixtures with the extracted contracts. Restore restricted Workspace constructors and remove redundant test visibility changes without altering inherited MySQL coverage.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* test(managed-agent): align remaining Harness and OSS fixtures

Preserve SDK refusal messages and register the managed OSS adapter at fixture injection points. Keep the existing retry and client shutdown assertions intact.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* style(managed-agent): order Hosted cleanup Harness imports

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* test(managed-agent): fix recovery smoke fixture and import order

Supply the required transcript coverage in the recovery browser fixture and wait for history before testing a complete handoff. Preserve its existing safety and submission assertions. Order the cleanup coordinator test imports for Checkstyle.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-10-30 14:56:35 +00:00
Shaojin Wen
477c216a2c
feat(managed-agent): add a phased upgrade command to the reference distribution (#15792)
* feat(managed-agent): add a phased upgrade command to the reference distribution

bin/qwen-managed-agent-upgrade runs a systemd upgrade as check, stop,
backup, install, start and verify. Each phase reads the units, their
environment and the installed release again, and refuses unless the
previous phase left them as it expects, so an interrupted upgrade resumes
at the phase that failed. Stopping ingress, installing Qwen Code and
editing environment or unit files stay manual; check prints where they
fall.

check compares the Flyway scripts in both server jars, so a release that
rewrote its baseline in place fails before anything stops. backup dumps
MySQL through a temporary option file and archives the Runtime state and
configuration; install refuses a backup the control plane has run past,
keeps each release under <distribution>-releases and switches a link.

The preflight database row now warns on an older schema, which the first
start migrates, and validates a schema at the manifest's version as the
server does. The control-plane unit counts exit status 143 as success.

* fix(managed-agent): address the first review of the upgrade command

Environment files:
- Read EnvironmentFile values with systemd's own grammar, ported from
  parse_env_file_internal() in env-file.c. Inside double quotes only \",
  \\, \`, \$ and backslash-newline are escapes. Outside quotes a backslash
  escapes any character. Quotes concatenate and may span lines. A
  password such as "p\w" therefore reaches mysqldump as the service
  receives it. 1579 random files read back through systemd-run on
  systemd 257 show no difference.

Runtime state:
- Resolve the Runtime state directory instead of assuming that
  QWEN_MANAGED_AGENT_RUNTIME_STATE_DIRECTORY sets it. A new
  runtime-state row names every source that can override that variable:
  the launcher's configuration files, JAVA_OPTS and its siblings,
  SPRING_APPLICATION_JSON, the relaxed-binding name, the unit's
  arguments, and profile or import locations. backup then refuses until
  --runtime-state names the directory.
- With no directory configured, backup archives none and says so.

Backup and rollback:
- Archive configuration that lives in the release by its path there, in
  release-config.tar, so the rollback restores it into the previous
  release rather than through the distribution link.
- Record the dumped database, where install leaves the previous release,
  the distribution path and both units in backup.json, and refuse
  install when the datasource or the releases directory changed.
- Write the mysqldump option file in a temporary directory outside the
  backup.
- Key the guide's rollback on backup.json fields, and skip the archives
  a backup does not hold.

Phases:
- Let stop run once the release is installed, so a start that never got
  healthy can be stopped.
- check takes the later phases' options. backup-tools resolves the given
  client, reports a skip, and fails when backup would refuse. The plan
  repeats the non-default options.
- Bound each health probe at 5 seconds and by --timeout. Tell a failed
  unit apart from a slow one, which keeps running and is pointed at
  verify or stop.

install:
- Reuse an existing release directory only when its SHA256SUMS is the
  new distribution's.
- Remove a partial copy on any failure.
- Move the directory back when the link rename fails. When a crash
  leaves the distribution path missing beside an .upgrade link, report
  that state with the mv -T that finishes the install.

check rows:
- Match Flyway's names: V, U and R prefixes, and a .sql suffix in any
  case.
- A changed repeatable script is a WARN, and a jar with no scripts is
  unreadable rather than unchanged.
- Reject a releases directory inside the new distribution.
- Report an unreadable new manifest as a row instead of throwing.

Tests and packaging:
- Wire ManagedSchema.validate through schemaCheck(Connection, String),
  and test it on a Flyway-migrated H2 database.
- Require both launcher modules in the archive.
- Add tests for each change: the upgrade command now has 34 tests.

* fix(managed-agent): count configuration imports as Runtime state sources

A configuration file can bring in the Runtime state directory without
naming it: spring.config.import loads another file, and
spring.profiles.active, include or group load profile files. The
runtime-state row now reads each configuration file's keys, by YAML
indentation or as properties keys, and names such a file as a source
it cannot read. backup then refuses until --runtime-state names the
directory. Before this, check passed and backup archived no Runtime
state for a deployment that set the directory only in an imported
file.

The same keys now count in JAVA_OPTS and its siblings, in
SPRING_APPLICATION_JSON, in the unit's arguments, and in
SPRING_PROFILES_INCLUDE.

--runtime-state none declares a deployment that keeps no Runtime
state, for one that uses such a source anyway.

The default configuration file is read through the distribution path
the unit names rather than its real path, so the row names the path the
operator knows.

* fix(managed-agent): resolve the Runtime state directory as the server does

Runtime state:
- check and backup no longer read configuration text to guess where the
  server keeps its Runtime state. A new main class in the server jar,
  ResolvedConfiguration, prepares Spring's environment the way
  SpringApplication does before it creates a context, binds the server's
  properties, and prints the state directory, its origin, the auth mode
  and the trusted actor header. It starts no context, logs nothing and
  opens no connection.
- The command runs this release's jar through systemd-run the way the
  control-plane unit runs the server: its account, working directory,
  environment files and Environment= assignments, the java on its PATH,
  and the launcher's config/application.yml default when
  SPRING_CONFIG_ADDITIONAL_LOCATION is unset or empty. Default locations,
  imports, profiles, flow mappings, merge keys, SPRING_CONFIG_NAME, JVM
  options and relaxed names therefore count as they do in the server.
- A configuration the jar cannot resolve, and ExecStart arguments, which
  systemctl prints unquoted, still need --runtime-state.
- Remove the line-by-line configuration reader.
- The admin launcher runs the same class as resolved-configuration, for
  the manual procedure on other layouts.

Phases:
- stop reads the unit's cgroup in the unified hierarchy or in systemd's
  own on cgroup v1, and refuses when it cannot read it instead of
  counting no workers. It explains a control plane that a JVM exit
  status of 143 left failed.
- install, run again once the release is installed, points at start
  instead of asking for another backup.
- Environment= assignments reach systemd-run through a 0600 file instead
  of its command line.
- verify bounds every request by --timeout, polls past 5xx answers and
  dropped connections, gives its single health probe the whole budget,
  takes the auth mode from the resolved configuration, and reads
  Sessions as --actor through the trusted actor header.

check rows:
- The database row fails a new versioned script that does not sort after
  the newest one the installed database ran, which Flyway refuses.
- An undecodable database name in SPRING_DATASOURCE_URL makes the URL
  unreadable instead of throwing.

Tests and docs:
- ResolvedConfigurationTest drives Spring's own preparation. The upgrade
  tests pin the systemd-run invocation, both cgroup layouts, the Harness
  unit in the archive and the new verify behavior. The packaging test
  pins SuccessExitStatus=143.
- Update the guide's stop, backup, install and verify sections, the
  rollback's mysql lines and the manual procedure's scope, and the design
  documents.

* fix(managed-agent): fail a verify read whose body breaks off

A success status followed by a body that times out, breaks off or does
not parse is a failed read. api() reported it as an empty answer, so
verify passed a Session read that never received its Items, and took a
listing cut short for a tenant without Sessions. The row now fails, and
the events poll treats such a body like a dropped connection and polls
again. An error status still reports its status when its body cannot be
read.

The auth-mode test compares the resolver's jar with the real path the
command resolves, so it passes where the temporary directory is a
symlink, as on macOS.
2026-10-29 08:44:24 +00:00
Shaojin Wen
6ef3eaa2f2
feat(managed-agent): add an admin launcher for the maintenance entry points (#15772)
* feat(managed-agent): add an admin launcher for the maintenance entry points

The server has twelve offline maintenance entry points, but the reference
distribution only shipped a launcher for operator recovery. The docs ran
the rest from a module build, sometimes through a classified jar the
distribution does not ship.

bin/qwen-managed-agent-admin <command> now runs each entry point by a
short name from the server jar, through PropertiesLauncher, since every
classified jar is the same application with another main class. It lists
its commands without starting Java, exits 2 on an unknown command, and
loads config/application.yml as the other launchers do. Packaging fails
when a mapped class is missing or has no main method.

The deployment guide gains a maintenance-commands section that names the
W1_JDBC_* and K2_JDBC_* credentials the commands read. The server and K2
READMEs show the distribution form first, and the K2 module-build commands
use the plain server jar.

* docs(managed-agent): name the admin commands that read the Spring datasource

operator-recovery and resident-retirement start the server's Spring
configuration and take its datasource, so they read SPRING_DATASOURCE_*
and the other control-plane settings, not W1_JDBC_* or K2_JDBC_*. The
deployment guide and the design said every database command read its
own credentials; they now name the two exceptions, say to run them with
server.env loaded, and note that csi-protection opens no database.

The config template's list of launchers that default
SPRING_CONFIG_ADDITIONAL_LOCATION now includes the admin launcher, which
shares the server launcher's preamble instead of a copy of it. A test
now also fails when a class with a main method has no admin command.
2026-10-28 20:15:54 +08:00
易良
a6ed0518df
feat(managed-agent): support opt-in same-context Java embedding (#15718)
Some checks failed
Qwen Code CI / Classify PR (push) Waiting to run
Qwen Code CI / Test (ubuntu-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / Lint & Static (ubuntu-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / web-shell E2E Smoke (ubuntu-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / Test (macos-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / Test (windows-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / Integration Tests (no-AK, No Sandbox) (push) Blocked by required conditions
Qwen Code CI / Integration Tests (CLI, No Sandbox) (push) Blocked by required conditions
E2E Tests / Build for E2E (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:docker - shard 1/1 (push) Blocked by required conditions
E2E Tests / E2E Test (Linux) - sandbox:none - shard 1/1 (push) Blocked by required conditions
E2E Tests / E2E Test - macOS - shard 1/2 (push) Blocked by required conditions
E2E Tests / E2E Test - macOS - shard 2/2 (push) Blocked by required conditions
E2E Tests / E2E Interactive - OpenTUI renderer (bun) (push) Blocked by required conditions
E2E Tests / channel-plugin E2E (nightly) (push) Blocked by required conditions
E2E Tests / cron-interactive E2E (nightly) (push) Blocked by required conditions
E2E Tests / web-shell Browser Regression (push) Waiting to run
Managed Agent gate / Select the Managed Agent tier (push) Waiting to run
Managed Agent gate / SDK Java () (push) Blocked by required conditions
Managed Agent gate / Managed Agent gate (push) Blocked by required conditions
SDK Java Flyway Open PRs / Re-check open PRs against main (push) Waiting to run
verify Maven repo producer / Save verify Maven repo (push) Has been cancelled
* feat(managed-agent): support opt-in same-context Java embedding

* fix(managed-agent): isolate embedded callback filter

* test(managed-agent): qualify fixture clock

* fix(managed-agent): preserve executable maintenance artifacts

* test(managed-agent): finish the by-name bean migration at test injection points

This PR moves managed-agent infrastructure to name-only beans
(@Bean(defaultCandidate = false) plus @Qualifier("managed*") at the
production consumer sites). The migration stopped short of the test
fixtures, which left two classes of breakage:

- ApplicationContextRunner slices registered unnamed JdbcTemplate,
  Clock, ObjectMapper, DataSource and PlatformTransactionManager beans
  that no longer match the production qualifier, so the context failed
  to load (EventTransportConfigurationTest,
  RuntimeRetentionConfigurationTest,
  ToolPublicationStorageConfigurationTest,
  ToolPublicationAsyncVerificationTest, EventTransportBrokerGate).
- Full-application suites autowired JdbcTemplate by type and silently
  got Spring Boot's plain auto-configured template instead of the
  schema-aware ManagedSchemaJdbcTemplate, which H2 rejects against the
  VARBINARY identity columns as "Values of types BINARY VARYING and
  CHARACTER VARYING are not comparable".

Apply the pattern the PR already establishes in
ManagedArtifactApiIntegrationTest (registerBean("managedAgentClock", ..))
and StandaloneDataSourceConfigurationTest (@Qualifier on the injection
point): name the fixture beans, qualify the injection points. Test-only;
no production code changes.

The 18 suites named by SDK Java (fast) go from Tests run: 583,
Failures: 25, Errors: 79 to Failures: 1, Errors: 0. The remaining
failure is acceptsClientBuiltCensusAfterTheDefinitionIsCommitted, which
needs packages/core/dist and fails identically before this change.
mvn checkstyle:check reports 0 violations.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Patrol-Run: qwen-pr-closeout/jmvr7204nyh

* test(managed-agent): qualify the last three plain-JdbcTemplate test injections

The by-name bean migration landed at fourteen injection points but left
three full-application suites still binding Spring Boot's plain
auto-configured jdbcTemplate instead of the schema-aware
ManagedSchemaJdbcTemplate. H2 rejects the resulting String-to-VARBINARY
comparisons, so SDK Java (fast) kept reporting Tests run: 5805,
Failures: 1, Errors: 3 across ManagedApprovalSelectionTest,
SurfaceAdmissionAcceptanceTest and WorkspaceSessionRetentionTest.

Apply the identical @Qualifier("managedJdbcTemplate") pattern at those
three field sites, plus the retention fixture's @Bean ManagedAgentStore
parameter: that suite's CI stack runs through
ManagedAgentStore.syncLifecycleClaim, and the store is built from that
parameter, so qualifying the field alone would not have cleared it.
Test-only; no production code changes.

Local managed-agent-server reactor on this change:
WorkspaceSessionRetentionTest 23/1/1 -> 23/0/0, the BINARY VARYING
signature drops from 7 occurrences to 1, and checkstyle reports 0
violations.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Patrol-Run: qwen-pr-closeout/jmvrdhhf0yo

* test(managed-agent): inject the broker gate's clock by its bean name

ExecutionConfiguration now registers managedAgentClock and
managedAgentExecutor with defaultCandidate = false so an embedding
context's own Clock/ExecutorService neither shadows nor is shadowed by
the control plane's, and every consumer resolves them by qualifier.
EventTransportBrokerGate still injected Clock by type, so the RocketMQ
lane failed to build the test instance: "No qualifying bean of type
'java.time.Clock' available". Qualify the field the same way the
production consumers and the gate's own startup() helper already do.

The other fields keep by-type injection: Boot's auto-configured
JdbcTemplate and ObjectMapper are default candidates, and this test
runs the whole application on H2.

* build(managed-agent): keep the packaging IT out of the failsafe selection

ManagedAgentPackagingIT reads the jars the package phase wrote and
needs managed.artifact.version, so the pom runs it from the dedicated
surefire artifact-packaging execution at integration-test with both
supplied. Its *IT name also matched failsafe's default includes, which
ran it a second time without the jars' version or the property:
standaloneArtifactsIncludeConfigurationWhileLibraryDoesNot opened
target/qwen-managed-agent-server-null.jar and
retirementLauncherLoadsFromExecutableJar could not load
org.springframework.boot.loader.launch.PropertiesLauncher from it.
Exclude it from failsafe next to the existing Hosted*IT exclusion; the
surefire execution stays the single, property-bearing run.

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-10-28 17:43:31 +08:00
jinye
a98615bedb
feat(managed-agent): Enable unified Shell session lifecycle (#15330) 2026-10-23 11:05:46 +00:00
jinye
f0a47611ab
refactor(managed-agent): Remove pre-release compatibility paths (#15263)
* refactor(managed-agent): Simplify first-release contracts

Remove unreleased compatibility paths across the managed runtime, Java control plane and WebShell. Keep one fresh V1 baseline and document that schema versions stay at V1 until the first formal release.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* test(managed-agent): Align remaining tool fixture with current contract

Restore schema rationale comments while retaining the V1 baseline.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(managed-agent): Align CSI proof with current checkpoint encoding

Require the three current nullable checkpoint fields in the native proof, keep malformed and missing fields rejected, and synchronize retained fixture bytes and digest chains. Update tests that still expected retired pre-release state and replay compatibility.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-10-23 02:09:21 +00:00
Shaojin Wen
40871f7d27
feat(managed-agent): bootstrap the shared deployment credentials (#14634)
* feat(managed-agent): ship a configuration template in the reference distribution

The reference archive carried no application.yml, so the Runtime credential
key ring — which cannot be expressed through QWEN_MANAGED_AGENT_* variables
because relaxed binding normalises map keys — forced every rotating deployment
to create a file and pass --spring.config.additional-location by hand.

Ship config/application.example.yml and have both launchers load
config/application.yml from the bundle root when it exists, leaving an
operator-supplied SPRING_CONFIG_ADDITIONAL_LOCATION in effect.

* feat(managed-agent): add a read-only --check preflight

The reference distribution listed its prerequisites in prose, but the server
evaluated them only at startup or on the first Turn: MySQL grants, the
credential key ring, auth/bind combinations, Harness reachability, broker
credentials, directories and ports.

Intercept --check before Spring starts and report each input as
PASS/WARN/FAIL/SKIP, exiting 1 on any failure. The command binds the same
configuration as the server, probes /capabilities, and compares the Flyway
version with the release manifest when one is present.

* feat(managed-agent): ship systemd units for the single-host topology

The server reference required a supervisor that leaves Runtime workers running
across a Broker restart, but the reference distribution shipped no unit that
did so.

Add control-plane and Hosted Harness units, environment templates, and an
install guide. The control-plane unit uses KillMode=process and StateDirectory;
the Harness uses KillMode=mixed. Include the templates in the archive and
guard their required directives with a structural test.

* feat(managed-agent): bootstrap the shared deployment credentials

Every deployment had to mint a Harness token, a capability digest, a broker
token and a 32-byte credential key, then keep the token and digest identical
across two files and the key ring in a third.

Add bin/qwen-managed-agent-bootstrap, which generates all four values and
writes harness.env, server.env and application.yml with mode 0600, refuses to
overwrite without --force, and prints paths only. Ship it in the archive.

* fix(managed-agent): pass the distribution config through the environment

The shared launcher injected --spring.config.additional-location before the
operator's arguments, so the operator-recovery entry, which dispatches on
args[0] and the exact argument count, could no longer run inspect, prepare or
complete.

Export SPRING_CONFIG_ADDITIONAL_LOCATION instead and leave the argument vector
untouched for both launchers. Also make the template's active key pair use the
mapped placeholders, so a copied example still honours the documented
environment override.

* docs(managed-agent): match the preflight design to the launcher fix

The preflight design still said the launcher adds a command-line config option.
The launcher now exports SPRING_CONFIG_ADDITIONAL_LOCATION, so update both
language versions.

* test(managed-agent): isolate the launcher test from an ambient config variable

The test spread process.env, so a machine that already exported
SPRING_CONFIG_ADDITIONAL_LOCATION changed the launcher's behaviour and failed
the new assertions. Remove the variable from the base environment; the
explicit operator-override case still sets it.

* fix(managed-agent): align the preflight with startup validation

The preflight could report PASS for a database without the performance_schema
grant, ignored command-line overrides, dropped earlier external YAML files
when several were listed, and could not find the release manifest in the
repackaged executable JAR. It also hand-copied auth and Workspace tool-path
rules that disagreed with the startup validators.

Delegate auth to BrokerSecurity, mirror the Workspace tool-path admission,
fail on a missing grant, load command-line arguments and every external YAML
with unique property sources, and resolve the manifest from the outer JAR.

* fix(managed-agent): reject the static provisioner for Workspace files

validateWorkspaceFiles refuses Workspace files on the static provisioner, but tool-path reported only WARN. Make it FAIL and keep the not-evaluated warning for other provisioners.

* fix(managed-agent): close the remaining preflight review gaps

Resolve relative class-path entries before locating the manifest, bind the full
server and spring.mvc properties before the auth guard, and require durable
local-process execution plus verified recovery for a Workspace creation root.

* fix(managed-agent): wire the Harness Broker flags and keep EnvironmentFile semantics

Expose QWEN_HOSTED_HARNESS_BROKER_ARGS in the Harness unit so the tool path can
pass the Broker URL and token, and run the preflight through systemd-run so it
reads the same EnvironmentFile as the service.

* fix(managed-agent): harden the bootstrap entry point and writes

Resolve symlinked entry points before running main, quote the configuration
path for shell sourcing and reject paths that cannot be quoted, and hold an
exclusive lock across the existence check and the three writes.

* fix(managed-agent): run the startup validation in the preflight

The preflight bound ManagedAgentProperties with Binder, which never runs
the @PostConstruct startup validation. Configurations that the server
rejects at startup -- an approval timeout below the ten-second floor, an
unknown bound-session isolation class, SSH enabled without Workspace
files -- printed PASS and exited 0.

ManagedAgentProperties now exposes the validation as a callable method
and the preflight reports its verdict as a `validation` row.

* fix(ci): keep the systemd READMEs on the full profile

The packaging test names distribution/systemd/README.md and its Chinese
counterpart, so classify-profile.test.mjs requires them in
TEST_READ_MARKDOWN. Without the entry the helper battery failed with both
files listed as unregistered lightweight Markdown, reddening Lint &
Static for the systemd stack.

* fix(managed-agent): boot the systemd template and authenticate the preflight

The shipped server.env.example enabled the Hosted Harness without the
Managed Session Store, which startup refuses, so following the README
restart-looped. The template now enables the store and sets its base URL
and the Runtime workspace ID.

The preflight probed /capabilities without the Harness token, so --check
printed FAIL 401 against a healthy authenticated Harness. It now sends the
configured bearer token and reports a rejected token separately from an
unreachable Harness.

The README installs application.yml as 0600 owned by the service account
instead of 0640 root:group: the control plane reads it as that account and
the preflight rejects group-readable secret files. It also documents the
ProtectHome constraint on the CLI location and the port-advance case.

* fix(managed-agent): close the systemd review gaps

The Harness unit expands QWEN_HOSTED_HARNESS_BROKER_ARGS into argv, so the
broker token is readable through /proc/<pid>/cmdline. Say so in the env
template and the unit comment, and keep that path to single-tenant hosts.

KillMode=process means `systemctl stop` signals only the main process: the
unit reports inactive while Runtime workers keep the state directory and
Workspace. Document the symptom and the reap command in both READMEs and
the deployment guide.

Derive the archive's required systemd entries from systemdFiles, so a
dropped env template or Chinese README fails packaging instead of only
breaking install step 3.

* fix(managed-agent): point the generated store at the server and reject commas

The bootstrap generator's server.env still omitted the Managed Session
Store, so the generated deployment failed the preflight's validation row.
It now emits the store enablement, its base URL and the Runtime workspace
ID.

The store URL is this Java control plane's listener, not the Harness: the
template and the generator now use http://127.0.0.1:8080, matching the
server reference. The systemd READMEs name both variables so a Harness
port change does not leave the store behind.

A comma in --directory splits SPRING_CONFIG_ADDITIONAL_LOCATION into two
locations; the guard now rejects it with the quote and newline cases, and
tests pin the generator's store lines and the 8080 value.
2026-10-19 12:11:21 +00:00
Shaojin Wen
c64163bcea
feat(managed-agent): ship systemd units for the single-host topology (#14633)
* feat(managed-agent): ship a configuration template in the reference distribution

The reference archive carried no application.yml, so the Runtime credential
key ring — which cannot be expressed through QWEN_MANAGED_AGENT_* variables
because relaxed binding normalises map keys — forced every rotating deployment
to create a file and pass --spring.config.additional-location by hand.

Ship config/application.example.yml and have both launchers load
config/application.yml from the bundle root when it exists, leaving an
operator-supplied SPRING_CONFIG_ADDITIONAL_LOCATION in effect.

* feat(managed-agent): add a read-only --check preflight

The reference distribution listed its prerequisites in prose, but the server
evaluated them only at startup or on the first Turn: MySQL grants, the
credential key ring, auth/bind combinations, Harness reachability, broker
credentials, directories and ports.

Intercept --check before Spring starts and report each input as
PASS/WARN/FAIL/SKIP, exiting 1 on any failure. The command binds the same
configuration as the server, probes /capabilities, and compares the Flyway
version with the release manifest when one is present.

* feat(managed-agent): ship systemd units for the single-host topology

The server reference required a supervisor that leaves Runtime workers running
across a Broker restart, but the reference distribution shipped no unit that
did so.

Add control-plane and Hosted Harness units, environment templates, and an
install guide. The control-plane unit uses KillMode=process and StateDirectory;
the Harness uses KillMode=mixed. Include the templates in the archive and
guard their required directives with a structural test.

* fix(managed-agent): pass the distribution config through the environment

The shared launcher injected --spring.config.additional-location before the
operator's arguments, so the operator-recovery entry, which dispatches on
args[0] and the exact argument count, could no longer run inspect, prepare or
complete.

Export SPRING_CONFIG_ADDITIONAL_LOCATION instead and leave the argument vector
untouched for both launchers. Also make the template's active key pair use the
mapped placeholders, so a copied example still honours the documented
environment override.

* docs(managed-agent): match the preflight design to the launcher fix

The preflight design still said the launcher adds a command-line config option.
The launcher now exports SPRING_CONFIG_ADDITIONAL_LOCATION, so update both
language versions.

* test(managed-agent): isolate the launcher test from an ambient config variable

The test spread process.env, so a machine that already exported
SPRING_CONFIG_ADDITIONAL_LOCATION changed the launcher's behaviour and failed
the new assertions. Remove the variable from the base environment; the
explicit operator-override case still sets it.

* fix(managed-agent): align the preflight with startup validation

The preflight could report PASS for a database without the performance_schema
grant, ignored command-line overrides, dropped earlier external YAML files
when several were listed, and could not find the release manifest in the
repackaged executable JAR. It also hand-copied auth and Workspace tool-path
rules that disagreed with the startup validators.

Delegate auth to BrokerSecurity, mirror the Workspace tool-path admission,
fail on a missing grant, load command-line arguments and every external YAML
with unique property sources, and resolve the manifest from the outer JAR.

* fix(managed-agent): reject the static provisioner for Workspace files

validateWorkspaceFiles refuses Workspace files on the static provisioner, but tool-path reported only WARN. Make it FAIL and keep the not-evaluated warning for other provisioners.

* fix(managed-agent): close the remaining preflight review gaps

Resolve relative class-path entries before locating the manifest, bind the full
server and spring.mvc properties before the auth guard, and require durable
local-process execution plus verified recovery for a Workspace creation root.

* fix(managed-agent): wire the Harness Broker flags and keep EnvironmentFile semantics

Expose QWEN_HOSTED_HARNESS_BROKER_ARGS in the Harness unit so the tool path can
pass the Broker URL and token, and run the preflight through systemd-run so it
reads the same EnvironmentFile as the service.

* fix(managed-agent): run the startup validation in the preflight

The preflight bound ManagedAgentProperties with Binder, which never runs
the @PostConstruct startup validation. Configurations that the server
rejects at startup -- an approval timeout below the ten-second floor, an
unknown bound-session isolation class, SSH enabled without Workspace
files -- printed PASS and exited 0.

ManagedAgentProperties now exposes the validation as a callable method
and the preflight reports its verdict as a `validation` row.

* fix(ci): keep the systemd READMEs on the full profile

The packaging test names distribution/systemd/README.md and its Chinese
counterpart, so classify-profile.test.mjs requires them in
TEST_READ_MARKDOWN. Without the entry the helper battery failed with both
files listed as unregistered lightweight Markdown, reddening Lint &
Static for the systemd stack.

* fix(managed-agent): boot the systemd template and authenticate the preflight

The shipped server.env.example enabled the Hosted Harness without the
Managed Session Store, which startup refuses, so following the README
restart-looped. The template now enables the store and sets its base URL
and the Runtime workspace ID.

The preflight probed /capabilities without the Harness token, so --check
printed FAIL 401 against a healthy authenticated Harness. It now sends the
configured bearer token and reports a rejected token separately from an
unreachable Harness.

The README installs application.yml as 0600 owned by the service account
instead of 0640 root:group: the control plane reads it as that account and
the preflight rejects group-readable secret files. It also documents the
ProtectHome constraint on the CLI location and the port-advance case.
2026-10-19 09:20:16 +00:00
Shaojin Wen
2cba716faf
feat(managed-agent): ship a configuration template in the reference distribution (#14631)
Some checks are pending
Qwen Code CI / Classify PR (push) Waiting to run
Qwen Code CI / Test (ubuntu-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / Lint & Static (ubuntu-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / web-shell E2E Smoke (ubuntu-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / Test (macos-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / Test (windows-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / Integration Tests (no-AK, No Sandbox) (push) Blocked by required conditions
Qwen Code CI / Integration Tests (CLI, No Sandbox) (push) Blocked by required conditions
E2E Tests / Build for E2E (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:docker - shard 1/1 (push) Blocked by required conditions
E2E Tests / E2E Test (Linux) - sandbox:none - shard 1/1 (push) Blocked by required conditions
E2E Tests / E2E Test - macOS - shard 1/2 (push) Blocked by required conditions
E2E Tests / E2E Test - macOS - shard 2/2 (push) Blocked by required conditions
E2E Tests / E2E Interactive - OpenTUI renderer (bun) (push) Blocked by required conditions
E2E Tests / channel-plugin E2E (nightly) (push) Blocked by required conditions
E2E Tests / cron-interactive E2E (nightly) (push) Blocked by required conditions
E2E Tests / web-shell Browser Regression (push) Waiting to run
Managed Agent gate / Select the Managed Agent tier (push) Waiting to run
Managed Agent gate / SDK Java () (push) Blocked by required conditions
Managed Agent gate / Managed Agent gate (push) Blocked by required conditions
SDK Java Contract Open PRs / Re-check open PRs against main (push) Waiting to run
Verify Landlock helper / Native Windows settings and streams (push) Waiting to run
Verify Landlock helper / arm64 (push) Waiting to run
Verify Landlock helper / x64 (push) Waiting to run
Verify Landlock helper / Native Linux CLI boundary (push) Waiting to run
verify Maven repo producer / Save verify Maven repo (push) Waiting to run
* feat(managed-agent): ship a configuration template in the reference distribution

The reference archive carried no application.yml, so the Runtime credential
key ring — which cannot be expressed through QWEN_MANAGED_AGENT_* variables
because relaxed binding normalises map keys — forced every rotating deployment
to create a file and pass --spring.config.additional-location by hand.

Ship config/application.example.yml and have both launchers load
config/application.yml from the bundle root when it exists, leaving an
operator-supplied SPRING_CONFIG_ADDITIONAL_LOCATION in effect.

* fix(managed-agent): pass the distribution config through the environment

The shared launcher injected --spring.config.additional-location before the
operator's arguments, so the operator-recovery entry, which dispatches on
args[0] and the exact argument count, could no longer run inspect, prepare or
complete.

Export SPRING_CONFIG_ADDITIONAL_LOCATION instead and leave the argument vector
untouched for both launchers. Also make the template's active key pair use the
mapped placeholders, so a copied example still honours the documented
environment override.

* test(managed-agent): isolate the launcher test from an ambient config variable

The test spread process.env, so a machine that already exported
SPRING_CONFIG_ADDITIONAL_LOCATION changed the launcher's behaviour and failed
the new assertions. Remove the variable from the base environment; the
explicit operator-override case still sets it.
2026-10-19 03:39:00 +00:00
jinye
28415ddff3
refactor(managed-agent): Consolidate server and broker sources (#14277)
* refactor(managed-agent): Consolidate server and broker sources

Move the combined Java application beside sdk-java and remove the standalone Runtime Broker artifact. Update build, development, packaging and CI references while preserving Java package identities, runtime protocols and schema resources.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* docs(managed-agent): Preserve historical evidence and verification guidance

Restore commit-pinned H3 probe inputs and align the Java verification environment contract with the consolidated server layout.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(ci): Run hosted Broker tests under Bash

Keep Maven property arguments intact on Windows and stop before Broker tests when the SDK install fails. Exercise both successful and failed SDK installation in the workflow regression tests.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(ci): Quote the hosted Broker shell value

Follow the repository yamllint single-quote rule without changing the parsed workflow configuration.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-10-16 00:28:58 +00:00
易良
a750166bec
feat(managed-agent): publish an experimental reference distribution (#14176)
* feat(managed-agent): publish reference distribution

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(ci): support GNU tar in reference packager

* fix(managed-agent): satisfy checksum regex lint

* fix(ci): close reference release gates

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: qwen-code-dev-bot <qwen-code-dev@service.alibaba.com>
Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com>
2026-10-15 05:04:29 +00:00