/** * @license * Copyright 2026 Alibaba Group Holding Limited * SPDX-License-Identifier: Apache-2.0 */ import assert from 'node:assert/strict'; import { execFileSync } from 'node:child_process'; import { chmod, mkdtemp, mkdir, readdir, readFile, realpath, rm, stat, symlink, writeFile, } from 'node:fs/promises'; import os from 'node:os'; import path from 'node:path'; import test from 'node:test'; import { fileURLToPath } from 'node:url'; import { accountCanEnter, directoriesToEnter, generateSecrets, lookupServiceUser, renderApplicationYml, renderHarnessEnv, renderMysqlSetup, renderServerEnv, } from '../../packages/managed-agent-server/distribution/bin/qwen-managed-agent-bootstrap.mjs'; import { ADMIN_COMMANDS, DOCUMENTATION, createReferenceDistribution, shippedDocumentLinks, } from '../package-managed-agent-reference.mjs'; function mainSource(main) { return `packages/managed-agent-server/server/src/main/java/${main.replaceAll('.', '/')}.java`; } async function fixture(root) { const files = { 'package.json': JSON.stringify({ version: '1.2.3', engines: { node: '>=22.0.0' }, }), LICENSE: 'license\n', 'packages/managed-agent-server/pom.xml': ` qwen-managed-agent-parent 0.4.0-alpha 21 `, 'packages/managed-agent-server/server/target/qwen-managed-agent-server-0.4.0-alpha-exec.jar': 'server', 'packages/managed-agent-server/server/target/qwen-managed-agent-server-0.4.0-alpha-operator-recovery.jar': 'recovery', 'packages/managed-agent-server/server/src/main/resources/application.yml': "workspace-shell-enabled: '${QWEN_MANAGED_AGENT_WORKSPACE_SHELL_ENABLED:false}'\n", 'packages/managed-agent-server/distribution/config/application.example.yml': 'template\n', 'packages/managed-agent-server/distribution/systemd/qwen-managed-agent-server.service': '[Service]\nKillMode=process\n', 'packages/managed-agent-server/distribution/systemd/qwen-hosted-harness.service': 'ExecStart=qwen serve --profile hosted-harness --no-web\n', 'packages/managed-agent-server/distribution/systemd/harness.env.example': 'QWEN_SERVER_TOKEN=\n', 'packages/managed-agent-server/distribution/systemd/server.env.example': 'SPRING_DATASOURCE_URL=\n', 'packages/managed-agent-server/distribution/systemd/README.md': 'systemd\n', 'packages/managed-agent-server/distribution/systemd/README.zh-CN.md': 'systemd zh\n', 'packages/managed-agent-server/distribution/bin/qwen-managed-agent-bootstrap': '#!/usr/bin/env sh\n', 'packages/managed-agent-server/distribution/bin/qwen-managed-agent-bootstrap.mjs': 'export {};\n', 'packages/managed-agent-server/distribution/bin/qwen-managed-agent-upgrade': '#!/usr/bin/env sh\nupgrade\n', 'packages/managed-agent-server/distribution/bin/qwen-managed-agent-upgrade.mjs': 'export {};\n', 'packages/managed-agent-server/contracts/src/main/resources/openapi/managed-agent-public-api.openapi.json': JSON.stringify({ info: { version: '1.46.0' } }), 'packages/managed-agent-server/persistence/src/main/resources/db/managed-schema/V1__baseline.sql': 'select 1;', 'packages/managed-agent-server/src/main/java/db/migration/V9__latest.java': 'class Latest {}', 'packages/cli/src/serve/capabilities.ts': "export const SERVE_PROTOCOL_VERSION = 'v1' as const;\n", 'packages/cli/src/serve/managed-runtime-broker-client.ts': 'export const MANAGED_RUNTIME_BROKER_PROTOCOL_VERSION = 2 as const;\n', 'packages/cli/src/serve/hosted-harness-contract.ts': "const profiles = (\n process.env[HOSTED_LIFECYCLE_V2_PROFILES_ENV] ?? 'hosted-workspace-shell/1'\n).split(',');\n", 'docs/users/managed-agent-reference-deployment.md': 'deploy\n', 'docs/users/managed-agent-reference-deployment.zh-CN.md': '部署\n', 'docs/users/hosted-workspace-recovery.md': 'recover\n', 'docs/users/hosted-workspace-recovery.zh-CN.md': '恢复\n', 'docs/users/managed-agent-configuration-reference.md': '[中文](managed-agent-configuration-reference.zh-CN.md) [guide](managed-agent-reference-deployment.md#upgrade) [site](https://example.com/a.md) [design](../design/x.md)\n', 'docs/users/managed-agent-configuration-reference.zh-CN.md': '配置\n', 'packages/managed-agent-server/README.md': 'server reference, [configuration](../../docs/users/managed-agent-configuration-reference.md)\n', }; for (const [, main] of ADMIN_COMMANDS) { files[mainSource(main)] = 'class Main { public static void main(String[] args) {} }\n'; } for (const [relative, contents] of Object.entries(files)) { const file = path.join(root, relative); await mkdir(path.dirname(file), { recursive: true }); await writeFile(file, contents); } } test('packages an independently verifiable reference distribution', async () => { const temporary = await mkdtemp(path.join(os.tmpdir(), 'qwen-reference-')); try { const root = path.join(temporary, 'repo'); const output = path.join(temporary, 'release'); const secondOutput = path.join(temporary, 'release-second'); const extracted = path.join(temporary, 'extracted'); await fixture(root); const result = await createReferenceDistribution({ repoRoot: root, outputDirectory: output, version: '0.1.0-alpha.1', sourceRevision: 'a'.repeat(40), }); assert.equal(result.manifest.source.revision, 'a'.repeat(40)); assert.equal(result.manifest.compatibility.qwenCodeVersion, '1.2.3'); assert.equal(result.manifest.compatibility.serveProtocolVersion, 'v1'); assert.equal( result.manifest.compatibility.managedRuntimeBrokerProtocolVersion, 2, ); assert.deepEqual(result.manifest.compatibility.databaseSchema, { migrationTool: 'Flyway', minimumMigrationVersion: '1', latestMigrationVersion: '9', }); assert.deepEqual( result.manifest.components.map(({ name }) => name), ['qwen-managed-agent-server', 'qwen-managed-agent-operator-recovery'], ); assert.deepEqual(result.manifest.defaults, { publicShellEnabled: false, v2CapabilityAdvertisementEnabled: true, }); await mkdir(extracted); execFileSync('tar', ['-xzf', result.archive, '-C', extracted]); const bundle = path.join( extracted, 'qwen-managed-agent-reference-0.1.0-alpha.1', ); execFileSync('sha256sum', ['--check', 'SHA256SUMS'], { cwd: bundle, stdio: 'pipe', }); const launcher = await readFile( path.join(bundle, 'bin/qwen-managed-agent-server'), 'utf8', ); assert.match(launcher, /lib\/qwen-managed-agent-server-0\.4\.0-alpha\.jar/); assert.match(launcher, /config\/application\.yml/); assert.match(launcher, /SPRING_CONFIG_ADDITIONAL_LOCATION/); assert.doesNotMatch(launcher, /set --/); assert.equal( await readFile( path.join(bundle, 'config/application.example.yml'), 'utf8', ), 'template\n', ); assert.equal( await readFile( path.join(bundle, 'systemd/qwen-managed-agent-server.service'), 'utf8', ), '[Service]\nKillMode=process\n', ); assert.match( await readFile( path.join(bundle, 'systemd/qwen-hosted-harness.service'), 'utf8', ), /--profile hosted-harness/, ); assert.equal( await readFile( path.join(bundle, 'bin/qwen-managed-agent-bootstrap'), 'utf8', ), '#!/usr/bin/env sh\n', ); const upgrade = path.join(bundle, 'bin/qwen-managed-agent-upgrade'); assert.equal( await readFile(upgrade, 'utf8'), '#!/usr/bin/env sh\nupgrade\n', ); assert.equal((await stat(upgrade)).mode & 0o777, 0o755); // Links to the other shipped documents name them as the archive does. for (const [page, contents] of [ [ 'docs/configuration.md', '[中文](configuration.zh-CN.md) [guide](deployment.md#upgrade) [site](https://example.com/a.md) [design](../design/x.md)\n', ], ['docs/configuration.zh-CN.md', '配置\n'], [ 'docs/server-reference.md', 'server reference, [configuration](configuration.md)\n', ], ]) { assert.equal(await readFile(path.join(bundle, page), 'utf8'), contents); } assert.equal( result.manifest.documentation.configuration, 'docs/configuration.md', ); assert.equal( result.manifest.documentation.configurationChinese, 'docs/configuration.zh-CN.md', ); for (const module of [ 'qwen-managed-agent-bootstrap.mjs', 'qwen-managed-agent-upgrade.mjs', ]) { assert.equal( await readFile(path.join(bundle, 'bin', module), 'utf8'), 'export {};\n', ); } execFileSync('sha256sum', ['--check', 'SHA256SUMS.txt'], { cwd: output, stdio: 'pipe', }); const second = await createReferenceDistribution({ repoRoot: root, outputDirectory: secondOutput, version: '0.1.0-alpha.1', sourceRevision: 'a'.repeat(40), }); assert.deepEqual( await readFile(second.archive), await readFile(result.archive), ); } finally { await rm(temporary, { recursive: true, force: true }); } }); test('launchers load the distribution config only when it exists', async () => { const temporary = await mkdtemp(path.join(os.tmpdir(), 'qwen-reference-')); try { const root = path.join(temporary, 'repo'); const output = path.join(temporary, 'release'); const extracted = path.join(temporary, 'extracted'); const fakeBin = path.join(temporary, 'bin'); await fixture(root); const result = await createReferenceDistribution({ repoRoot: root, outputDirectory: output, version: '0.1.0-alpha.1', sourceRevision: 'a'.repeat(40), }); await mkdir(extracted); execFileSync('tar', ['-xzf', result.archive, '-C', extracted]); const bundle = path.join( extracted, 'qwen-managed-agent-reference-0.1.0-alpha.1', ); await mkdir(fakeBin); const java = path.join(fakeBin, 'java'); await writeFile( java, '#!/bin/sh\nprintf "ENV=%s\\n" "${SPRING_CONFIG_ADDITIONAL_LOCATION:-}"\n' + 'printf "ARG=%s\\n" "$@"\n', ); await chmod(java, 0o755); const baseEnv = { ...process.env }; delete baseEnv.SPRING_CONFIG_ADDITIONAL_LOCATION; const env = { ...baseEnv, PATH: `${fakeBin}:${process.env.PATH}` }; const launcherPath = path.join(bundle, 'bin/qwen-managed-agent-server'); const recoveryPath = path.join( bundle, 'bin/qwen-managed-agent-operator-recovery', ); const run = (script, args, overrides = {}) => execFileSync('sh', [script, ...args], { env: { ...env, ...overrides }, encoding: 'utf8', }); const withoutConfig = run(launcherPath, ['--spring.profiles.active=test']); assert.ok(withoutConfig.includes('ENV=\n')); assert.ok(withoutConfig.includes('ARG=--spring.profiles.active=test')); assert.ok( !withoutConfig.includes('ARG=--spring.config.additional-location'), ); const config = path.join(bundle, 'config/application.yml'); await writeFile(config, 'qwen: {}\n'); const withConfig = run(launcherPath, ['--spring.profiles.active=test']); assert.ok(withConfig.includes(`ENV=file:${config}`)); assert.ok(withConfig.includes('ARG=--spring.profiles.active=test')); assert.ok(!withConfig.includes('ARG=--spring.config.additional-location')); const operator = run(launcherPath, [], { SPRING_CONFIG_ADDITIONAL_LOCATION: '/tmp/operator.yml', }); assert.ok(operator.includes('ENV=/tmp/operator.yml')); // One server jar runs every maintenance entry point. const admin = path.join(bundle, 'bin/qwen-managed-agent-admin'); const registration = run(admin, [ 'storage-registration', 'inspect', 't', 's', ]); assert.ok(registration.includes(`ENV=file:${config}`)); assert.deepEqual( registration.split('\n').filter((line) => line.startsWith('ARG=')), [ 'ARG=-Dloader.main=com.alibaba.qwen.code.managedagent.maintenance.WorkspaceStorageRegistrationMain', 'ARG=-cp', `ARG=${bundle}/lib/qwen-managed-agent-server-0.4.0-alpha.jar`, 'ARG=org.springframework.boot.loader.launch.PropertiesLauncher', 'ARG=inspect', 'ARG=t', 'ARG=s', ], ); for (const [name, main] of ADMIN_COMMANDS) { assert.ok( run(admin, [name]).includes(`ARG=-Dloader.main=${main}\n`), name, ); } const help = run(admin, []); for (const [name, , summary] of ADMIN_COMMANDS) { assert.match( help, new RegExp(`^ ${name} +${summary.replace('.', '\\.')}$`, 'm'), ); } assert.ok(!help.includes('ARG='), 'help runs no Java'); assert.throws( () => run(admin, ['no-such-command'], {}), (error) => error.status === 2 && String(error.stderr).includes('unknown command: no-such-command'), ); const recovery = run(recoveryPath, ['inspect', 'binding-1', '7']); assert.ok(recovery.includes(`ENV=file:${config}`)); assert.ok(recovery.includes('ARG=-jar')); assert.ok(recovery.includes('ARG=inspect')); assert.ok(recovery.includes('ARG=binding-1')); assert.ok(recovery.includes('ARG=7')); assert.ok(!recovery.includes('ARG=--spring.config.additional-location')); } finally { await rm(temporary, { recursive: true, force: true }); } }); test('refuses an admin command whose entry point is gone', async () => { const temporary = await mkdtemp(path.join(os.tmpdir(), 'qwen-reference-')); try { const root = path.join(temporary, 'repo'); await fixture(root); const [name, main] = ADMIN_COMMANDS[0]; const source = path.join(root, mainSource(main)); await writeFile(source, 'class Main {}\n'); const build = () => createReferenceDistribution({ repoRoot: root, outputDirectory: path.join(temporary, 'release'), version: '0.1.0-alpha.1', sourceRevision: 'a'.repeat(40), }); await assert.rejects( build, new RegExp(`${name}: ${main} has no main method`), ); await rm(source); await assert.rejects( build, new RegExp(`${name} names a missing class ${main}`), ); } finally { await rm(temporary, { recursive: true, force: true }); } }); test('a shipped document links to another by its name in the archive', () => { const documentation = [ ['docs/users/guide.md', 'docs/deployment.md'], ['docs/users/guide.zh-CN.md', 'docs/deployment.zh-CN.md'], ['packages/server/README.md', 'docs/server-reference.md'], ['LICENSE', 'LICENSE'], ]; const links = (text, source) => shippedDocumentLinks(text, source, documentation); assert.equal( links( '[中文](guide.zh-CN.md#top) and [it](./guide.zh-CN.md) [server](../../packages/server/README.md)', 'docs/users/guide.md', ), '[中文](deployment.zh-CN.md#top) and [it](deployment.zh-CN.md) [server](server-reference.md)', ); assert.equal( links( '[guide](../../docs/users/guide.md#upgrade)', 'packages/server/README.md', ), '[guide](deployment.md#upgrade)', ); // LICENSE ships too, one level up from the documents. assert.equal( links('[license](../../LICENSE)', 'packages/server/README.md'), '[license](../LICENSE)', ); // An unshipped file, a URL, an anchor and an absolute path stay as // written, even an absolute path that would join to a shipped one. const kept = '[notes](notes/unshipped.md) [web](https://example.com/guide.zh-CN.md) [here](#top) [root](/guide.zh-CN.md)'; assert.equal(links(kept, 'docs/users/guide.md'), kept); }); test('the shipped documents reach each other by their archive names', async () => { const root = fileURLToPath(new URL('../../', import.meta.url)); const shipped = new Map(DOCUMENTATION); const pattern = /\]\(([^()\s#]+)(#[^()\s]*)?\)/g; const rewritten = {}; for (const [source, destination] of DOCUMENTATION) { if (!source.endsWith('.md')) { continue; } const text = await readFile(path.join(root, source), 'utf8'); const after = shippedDocumentLinks(text, source); rewritten[destination] = after; const before = [...text.matchAll(pattern)]; const now = [...after.matchAll(pattern)]; assert.equal(now.length, before.length, destination); before.forEach(([, target], index) => { const named = shipped.get( path.posix.normalize( path.posix.join(path.posix.dirname(source), target), ), ); if (named !== undefined) { const resolved = path.posix.join( path.posix.dirname(destination), now[index][1], ); assert.equal(resolved, named, `${destination}: ${target}`); } }); assert.doesNotMatch( after, /\]\([^)]*(managed-agent-configuration-reference|managed-agent-reference-deployment)/, destination, ); } assert.match( rewritten['docs/configuration.md'], /\]\(configuration\.zh-CN\.md\)/, ); assert.match(rewritten['docs/configuration.md'], /\]\(deployment\.md\)/); assert.match( rewritten['docs/configuration.zh-CN.md'], /\]\(deployment\.zh-CN\.md\)/, ); assert.match(rewritten['docs/deployment.md'], /\]\(configuration\.md\)/); assert.match( rewritten['docs/deployment.zh-CN.md'], /\]\(configuration\.zh-CN\.md\)/, ); assert.match( rewritten['docs/server-reference.md'], /\]\(configuration\.md\)/, ); }); test('maps every admin command to an entry point in the server', async () => { const root = fileURLToPath(new URL('../../', import.meta.url)); const names = ADMIN_COMMANDS.map(([name]) => name); assert.equal(new Set(names).size, names.length); for (const [name, main] of ADMIN_COMMANDS) { assert.match(name, /^[a-z]+(-[a-z]+)*$/); assert.match( await readFile(path.join(root, mainSource(main)), 'utf8'), /public static void main\(String/, name, ); } // And the other way: a new entry point needs a command too. The server // application is the one main the admin launcher does not run. const sources = path.join( root, 'packages/managed-agent-server/server/src/main/java', ); const mains = []; for (const file of await readdir(sources, { recursive: true })) { if ( file.endsWith('.java') && /public static void main\(String/.test( await readFile(path.join(sources, file), 'utf8'), ) ) { mains.push(file.slice(0, -'.java'.length).replaceAll(path.sep, '.')); } } assert.deepEqual( mains .filter( (main) => main !== 'com.alibaba.qwen.code.managedagent.ManagedAgentServerApplication', ) .sort(), ADMIN_COMMANDS.map(([, main]) => main).sort(), ); }); test('ships systemd units with the documented kill modes', async () => { const directory = new URL( '../../packages/managed-agent-server/distribution/systemd/', import.meta.url, ); const server = await readFile( new URL('qwen-managed-agent-server.service', directory), 'utf8', ); const harness = await readFile( new URL('qwen-hosted-harness.service', directory), 'utf8', ); assert.match(server, /^KillMode=process$/m); // A JVM stopped by SIGTERM exits 143; without this the stopped unit fails. assert.match(server, /^SuccessExitStatus=143$/m); assert.match(server, /^StateDirectory=qwen-managed-agent$/m); assert.match( server, /^EnvironmentFile=\/etc\/qwen-managed-agent\/server\.env$/m, ); assert.match( server, /^ExecStart=\/opt\/qwen-managed-agent\/bin\/qwen-managed-agent-server$/m, ); assert.match(harness, /^KillMode=mixed$/m); assert.match(harness, /^StateDirectory=qwen-managed-agent$/m); assert.match(harness, /--profile hosted-harness/); assert.match(harness, /--no-web/); // The Broker token reaches the Harness through harness.env, never argv. assert.doesNotMatch(harness, /BROKER/); assert.match( harness, /^EnvironmentFile=\/etc\/qwen-managed-agent\/harness\.env$/m, ); assert.match( harness, /^ExecStart=\/usr\/local\/bin\/qwen serve --profile hosted-harness --hostname 127\.0\.0\.1 --port 4170 --no-web$/m, ); assert.ok(server.endsWith('\n')); assert.ok(harness.endsWith('\n')); assert.doesNotMatch(server, /\t/); assert.doesNotMatch(harness, /\t/); }); test('bootstrap renders matching credentials and a 32-byte key', () => { const secrets = generateSecrets('reference-test'); assert.match(secrets.digest, /^sha256:[0-9a-f]{64}$/); assert.equal(Buffer.from(secrets.credentialKey, 'base64').length, 32); const harness = renderHarnessEnv(secrets); assert.ok(harness.includes(secrets.token)); // The control plane refuses a `;` comment, which a shell stops reading the file at. assert.doesNotMatch(harness, /^\s*;/m); assert.ok( harness .split('\n') .includes(`QWEN_MANAGED_RUNTIME_BROKER_TOKEN=${secrets.brokerToken}`), ); assert.match( harness, /^QWEN_MANAGED_RUNTIME_BROKER_URL=http:\/\/127\.0\.0\.1:4182$/m, ); const paths = { databasePassword: secrets.databasePassword, applicationConfigPath: '/tmp/application.yml', harnessEnvPath: '/tmp/harness.env', }; const server = renderServerEnv(paths); assertReadsHarnessCredentials(server, secrets, '/tmp/harness.env'); assertDerivesSessionStoreWiring(server); assert.ok( server .split('\n') .includes(`SPRING_DATASOURCE_PASSWORD=${secrets.databasePassword}`), ); assert.doesNotMatch(server, /SERVICE_USER/); assert.match( renderServerEnv({ ...paths, serviceUser: 'qwen-managed-agent' }), /^QWEN_MANAGED_AGENT_SERVICE_USER=qwen-managed-agent$/m, ); assert.match( renderApplicationYml(secrets), /credential-key-id: 'reference-test'/, ); }); test('bootstrap writes the MySQL setup for the generated password', () => { const secrets = generateSecrets(); assert.match(secrets.databasePassword, /^[0-9a-f]{64}$/); const sql = renderMysqlSetup(secrets); const statements = sql.split('\n').filter((line) => !line.startsWith('--')); assert.deepEqual(statements, [ 'CREATE DATABASE qwen_managed_agent CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;', `CREATE USER 'qwen'@'localhost' IDENTIFIED BY '${secrets.databasePassword}';`, `CREATE USER 'qwen'@'127.0.0.1' IDENTIFIED BY '${secrets.databasePassword}';`, "GRANT ALL ON qwen_managed_agent.* TO 'qwen'@'localhost';", "GRANT ALL ON qwen_managed_agent.* TO 'qwen'@'127.0.0.1';", "GRANT SELECT ON performance_schema.user_variables_by_thread TO 'qwen'@'localhost';", "GRANT SELECT ON performance_schema.user_variables_by_thread TO 'qwen'@'127.0.0.1';", '', ]); }); test('bootstrap resolves the service account before changing owners', () => { const ids = { '-u': [990], '-g': [985], '-G': [985, 4] }; const lookup = (flag) => ids[flag]; assert.deepEqual( lookupServiceUser('qwen-managed-agent', { lookup, uid: 0 }), { uid: 990, gid: 985, groups: [985, 4] }, ); // The name is written unquoted into server.env. for (const name of ['', 'Qwen', '-x', 'a b', 'a;b', 'x'.repeat(33)]) { assert.match( lookupServiceUser(name, { lookup, uid: 0 }).error, /must be a user name/, ); } assert.match( lookupServiceUser('qwen-managed-agent', { lookup, uid: 1000 }).error, /run the bootstrap as root/, ); assert.match( lookupServiceUser('missing', { lookup: () => { throw new Error('no such user'); }, uid: 0, }).error, /User missing does not exist/, ); }); test('bootstrap checks directory entry the way the kernel does', () => { const account = { uid: 990, gid: 985, groups: [985, 4] }; // The owner bits alone apply to the owner, even when others may enter. assert.equal( accountCanEnter({ uid: 990, gid: 0, mode: 0o055 }, account), false, ); assert.equal( accountCanEnter({ uid: 990, gid: 0, mode: 0o700 }, account), true, ); assert.equal(accountCanEnter({ uid: 0, gid: 4, mode: 0o750 }, account), true); assert.equal( accountCanEnter({ uid: 0, gid: 4, mode: 0o705 }, account), false, ); assert.equal(accountCanEnter({ uid: 0, gid: 0, mode: 0o755 }, account), true); assert.equal( accountCanEnter({ uid: 0, gid: 0, mode: 0o750 }, account), false, ); }); test('bootstrap follows symbolic links to the directories the account enters', async () => { const temporary = await realpath( await mkdtemp(path.join(os.tmpdir(), 'qwen-bootstrap-links-')), ); try { const target = path.join(temporary, 'private', 'config'); await mkdir(target, { recursive: true }); await mkdir(path.join(temporary, 'etc')); const absolute = path.join(temporary, 'etc', 'qwen-managed-agent'); await symlink(target, absolute); const relative = path.join(temporary, 'etc', 'relative'); await symlink(path.join('..', 'private', 'config'), relative); for (const link of [absolute, relative]) { const entered = await directoriesToEnter(link); // The directory holding the link, and one that only the target names. assert.ok(entered.includes(path.join(temporary, 'etc')), link); assert.ok(entered.includes(path.join(temporary, 'private')), link); assert.equal(entered.at(-1), target, link); } await symlink('loop-b', path.join(temporary, 'loop-a')); await symlink('loop-a', path.join(temporary, 'loop-b')); await assert.rejects( directoriesToEnter(path.join(temporary, 'loop-a')), /Too many symbolic links/, ); } finally { await rm(temporary, { recursive: true, force: true }); } }); test('bootstrap writes private files without printing secrets', async () => { const temporary = await mkdtemp(path.join(os.tmpdir(), 'qwen-bootstrap-')); try { const directory = path.join(temporary, 'config'); const script = fileURLToPath( new URL( '../../packages/managed-agent-server/distribution/bin/' + 'qwen-managed-agent-bootstrap.mjs', import.meta.url, ), ); const output = execFileSync( process.execPath, [script, '--directory', directory], { encoding: 'utf8' }, ); const harness = await readFile(path.join(directory, 'harness.env'), 'utf8'); const server = await readFile(path.join(directory, 'server.env'), 'utf8'); const application = await readFile( path.join(directory, 'application.yml'), 'utf8', ); const token = harness.match(/^QWEN_SERVER_TOKEN=([0-9a-f]{64})$/m)[1]; const digest = harness.match( /^QWEN_HOSTED_HARNESS_CAPABILITY_DIGEST=(sha256:[0-9a-f]{64})$/m, )[1]; const brokerToken = harness.match( /^QWEN_MANAGED_RUNTIME_BROKER_TOKEN=([0-9a-f]{64})$/m, )[1]; assertReadsHarnessCredentials( server, { token, digest, brokerToken }, path.join(directory, 'harness.env'), ); assert.match(application, /credential-key: '[A-Za-z0-9+/=]{44}'/); const sql = await readFile(path.join(directory, 'mysql-setup.sql'), 'utf8'); const password = server.match( /^SPRING_DATASOURCE_PASSWORD=([0-9a-f]{64})$/m, )[1]; assert.ok(sql.includes(`IDENTIFIED BY '${password}';`)); for (const name of [ 'harness.env', 'server.env', 'application.yml', 'mysql-setup.sql', ]) { assert.equal( (await stat(path.join(directory, name))).mode & 0o777, 0o600, ); } for (const secret of [token, digest, brokerToken, password]) { assert.ok(!output.includes(secret)); } assert.throws( () => execFileSync(process.execPath, [script, '--directory', directory], { stdio: 'pipe', }), (error) => error.status === 1, ); execFileSync( process.execPath, [script, '--directory', directory, '--force'], { encoding: 'utf8' }, ); } finally { await rm(temporary, { recursive: true, force: true }); } }); test( 'bootstrap gives the service account its files', { skip: process.getuid?.() !== 0 && 'needs root to change owners' }, async () => { const temporary = await mkdtemp( path.join(os.tmpdir(), 'qwen-bootstrap-owner-'), ); try { const script = fileURLToPath( new URL( '../../packages/managed-agent-server/distribution/bin/' + 'qwen-managed-agent-bootstrap.mjs', import.meta.url, ), ); const user = 'nobody'; const ids = (flag) => execFileSync('id', [flag, user], { encoding: 'utf8' }) .trim() .split(/\s+/) .map(Number); const [uid] = ids('-u'); const [gid] = ids('-g'); const directory = path.join(temporary, 'config'); const run = (target = directory) => execFileSync( process.execPath, [script, '--directory', target, '--service-user', user], { encoding: 'utf8', stdio: 'pipe' }, ); // mkdtemp's 0700 parent keeps the account out, so nothing is written. assert.throws(run, (error) => String(error.stderr).includes(`${user} cannot enter ${temporary}`), ); await chmod(temporary, 0o755); await rm(directory, { recursive: true, force: true }); run(); const owners = { '.': [0, gid, 0o750], 'harness.env': [uid, gid, 0o600], 'application.yml': [uid, gid, 0o600], 'server.env': [0, gid, 0o640], 'mysql-setup.sql': [0, 0, 0o600], }; for (const [name, expected] of Object.entries(owners)) { const info = await stat(path.join(directory, name)); assert.deepEqual( [info.uid, info.gid, info.mode & 0o777], expected, name, ); } assert.match( await readFile(path.join(directory, 'server.env'), 'utf8'), /^QWEN_MANAGED_AGENT_SERVICE_USER=nobody$/m, ); // A 0700 directory reached only through a symbolic link keeps the // account out too. const hidden = path.join(temporary, 'private'); await mkdir(path.join(hidden, 'config'), { recursive: true }); await chmod(hidden, 0o700); const linked = path.join(temporary, 'linked'); await symlink(path.join(hidden, 'config'), linked); assert.throws( () => run(linked), (error) => String(error.stderr).includes(`${user} cannot enter ${hidden}`), ); assert.deepEqual(await readdir(path.join(hidden, 'config')), []); } finally { await rm(temporary, { recursive: true, force: true }); } }, ); test('bootstrap runs through a symlinked entry point', async () => { const temporary = await mkdtemp( path.join(os.tmpdir(), 'qwen-bootstrap-link-'), ); try { const script = fileURLToPath( new URL( '../../packages/managed-agent-server/distribution/bin/' + 'qwen-managed-agent-bootstrap.mjs', import.meta.url, ), ); const link = path.join(temporary, 'bootstrap-link.mjs'); await symlink(script, link); const directory = path.join(temporary, 'config'); execFileSync(process.execPath, [link, '--directory', directory], { encoding: 'utf8', }); const harness = await readFile(path.join(directory, 'harness.env'), 'utf8'); assert.match(harness, /QWEN_SERVER_TOKEN=[0-9a-f]{64}/); } finally { await rm(temporary, { recursive: true, force: true }); } }); test('bootstrap quotes the configuration path for shell sourcing', async () => { const temporary = await mkdtemp( path.join(os.tmpdir(), 'qwen-bootstrap-path-'), ); try { const script = fileURLToPath( new URL( '../../packages/managed-agent-server/distribution/bin/' + 'qwen-managed-agent-bootstrap.mjs', import.meta.url, ), ); const directory = path.join(temporary, 'config-$PR14634'); execFileSync(process.execPath, [script, '--directory', directory], { encoding: 'utf8', }); const value = execFileSync( 'sh', [ '-c', 'set -a; . "$1"; printf %s "$SPRING_CONFIG_ADDITIONAL_LOCATION"', 'sh', path.join(directory, 'server.env'), ], { encoding: 'utf8' }, ); assert.equal(value, `file:${path.join(directory, 'application.yml')}`); } finally { await rm(temporary, { recursive: true, force: true }); } }); test('bootstrap rejects a configuration path it cannot quote', async () => { const temporary = await mkdtemp( path.join(os.tmpdir(), 'qwen-bootstrap-quote-'), ); try { const script = fileURLToPath( new URL( '../../packages/managed-agent-server/distribution/bin/' + 'qwen-managed-agent-bootstrap.mjs', import.meta.url, ), ); const directory = path.join(temporary, "config-'"); assert.throws( () => execFileSync(process.execPath, [script, '--directory', directory], { stdio: 'pipe', }), (error) => error.status === 1, ); await assert.rejects(readFile(path.join(directory, 'harness.env'))); } finally { await rm(temporary, { recursive: true, force: true }); } }); test('bootstrap rejects a configuration path the location list splits on', async () => { const temporary = await mkdtemp( path.join(os.tmpdir(), 'qwen-bootstrap-comma-'), ); try { const script = fileURLToPath( new URL( '../../packages/managed-agent-server/distribution/bin/' + 'qwen-managed-agent-bootstrap.mjs', import.meta.url, ), ); const directory = path.join(temporary, 'config,one'); assert.throws( () => execFileSync(process.execPath, [script, '--directory', directory], { stdio: 'pipe', }), (error) => error.status === 1, ); await assert.rejects(readFile(path.join(directory, 'harness.env'))); } finally { await rm(temporary, { recursive: true, force: true }); } }); test('bootstrap refuses to run while another bootstrap holds the lock', async () => { const temporary = await mkdtemp( path.join(os.tmpdir(), 'qwen-bootstrap-lock-'), ); try { const script = fileURLToPath( new URL( '../../packages/managed-agent-server/distribution/bin/' + 'qwen-managed-agent-bootstrap.mjs', import.meta.url, ), ); const directory = path.join(temporary, 'config'); await mkdir(directory, { recursive: true }); await writeFile(path.join(directory, '.bootstrap.lock'), '', { mode: 0o600, }); assert.throws( () => execFileSync(process.execPath, [script, '--directory', directory], { stdio: 'pipe', }), (error) => error.status === 1, ); await assert.rejects(readFile(path.join(directory, 'harness.env'))); } finally { await rm(temporary, { recursive: true, force: true }); } }); test('leaves the Session Store wiring to the server defaults in the env template', async () => { const template = await readFile( new URL( '../../packages/managed-agent-server/distribution/systemd/server.env.example', import.meta.url, ), 'utf8', ); assert.match(template, /^QWEN_MANAGED_AGENT_HARNESS_ENABLED=true$/m); assertDerivesSessionStoreWiring(template); assert.doesNotMatch( template, /^QWEN_MANAGED_AGENT_(HARNESS_TOKEN|CAPABILITY_DIGEST)=/m, ); assert.doesNotMatch(template, /RUNTIME_BROKER_TOKEN/); assert.match( template, /^QWEN_MANAGED_AGENT_HARNESS_CREDENTIALS_FILE=\/etc\/qwen-managed-agent\/harness\.env$/m, ); }); // The server derives the store switch, URL and workspace ID; an explicit // workspace ID would conflict with the local-process Broker's derived one. function assertDerivesSessionStoreWiring(env) { assert.doesNotMatch(env, /^QWEN_MANAGED_AGENT_SESSION_STORE_/m); assert.doesNotMatch(env, /^QWEN_MANAGED_AGENT_WORKSPACE_ID=/m); assert.match( env, /^QWEN_MANAGED_AGENT_WORKSPACE_CWD=\/srv\/qwen-workspace$/m, ); } // harness.env is the one copy of the shared credentials; server.env names it. function assertReadsHarnessCredentials( server, { token, digest, brokerToken }, harnessEnv, ) { assert.ok(!server.includes(token)); assert.ok(!server.includes(digest)); assert.ok(!server.includes(brokerToken)); assert.doesNotMatch( server, /^QWEN_MANAGED_AGENT_(HARNESS_TOKEN|CAPABILITY_DIGEST|RUNTIME_BROKER_TOKEN)=/m, ); assert.ok( server .split('\n') .includes(`QWEN_MANAGED_AGENT_HARNESS_CREDENTIALS_FILE='${harnessEnv}'`), ); } test('ships the Harness credential keys the control plane reads', async () => { const template = await readFile( new URL( '../../packages/managed-agent-server/distribution/systemd/harness.env.example', import.meta.url, ), 'utf8', ); // The control plane matches these keys exactly, from the start of a line, // and accepts only these characters in their values. assert.match(template, /^QWEN_SERVER_TOKEN=[A-Za-z0-9._:/+=-]+$/m); assert.match( template, /^QWEN_HOSTED_HARNESS_CAPABILITY_DIGEST=sha256:[A-Za-z0-9._:/+=-]+$/m, ); // It refuses a `;` comment, which a shell stops reading the file at. assert.doesNotMatch(template, /^\s*;/m); // The tool path's pair ships commented, for the operator to enable together. assert.match( template, /^# QWEN_MANAGED_RUNTIME_BROKER_URL=http:\/\/127\.0\.0\.1:4182$/m, ); assert.match( template, /^# QWEN_MANAGED_RUNTIME_BROKER_TOKEN=[A-Za-z0-9._:/+=-]+$/m, ); assert.doesNotMatch(template, /^#? *QWEN_HOSTED_HARNESS_BROKER_ARGS=/m); }); test('rejects a stable distribution version', async () => { await assert.rejects( createReferenceDistribution({ repoRoot: '.', outputDirectory: '.', version: '1.0.0', sourceRevision: 'a'.repeat(40), }), /experimental SemVer/, ); }); test('rejects a numeric prerelease identifier with a leading zero', async () => { await assert.rejects( createReferenceDistribution({ repoRoot: '.', outputDirectory: '.', version: '1.0.0-01', sourceRevision: 'a'.repeat(40), }), /experimental SemVer/, ); }); test('rejects stale or ambiguous safety defaults', async (context) => { const cases = [ { name: 'commented public Shell default', file: 'packages/managed-agent-server/server/src/main/resources/application.yml', contents: "# workspace-shell-enabled: '${QWEN_MANAGED_AGENT_WORKSPACE_SHELL_ENABLED:false}'\nworkspace-shell-enabled: '${QWEN_MANAGED_AGENT_WORKSPACE_SHELL_ENABLED:true}'\n", error: /Public Shell must default to false/, }, { name: 'commented lifecycle v2 default', file: 'packages/cli/src/serve/hosted-harness-contract.ts', contents: "/*\nprocess.env[HOSTED_LIFECYCLE_V2_PROFILES_ENV] ?? 'hosted-workspace-shell/1'\n*/\nconst profiles = (\n process.env[HOSTED_LIFECYCLE_V2_PROFILES_ENV] ?? ''\n).split(',');\n", error: /Hosted lifecycle v2 profiles must default to canonical Shell only/, }, { name: 'duplicate public Shell default', file: 'packages/managed-agent-server/server/src/main/resources/application.yml', contents: "workspace-shell-enabled: '${QWEN_MANAGED_AGENT_WORKSPACE_SHELL_ENABLED:false}'\nworkspace-shell-enabled: '${QWEN_MANAGED_AGENT_WORKSPACE_SHELL_ENABLED:false}'\n", error: /Cannot uniquely read public Shell default/, }, ]; for (const candidate of cases) { await context.test(candidate.name, async () => { const temporary = await mkdtemp( path.join(os.tmpdir(), 'qwen-reference-'), ); try { const root = path.join(temporary, 'repo'); await fixture(root); await writeFile(path.join(root, candidate.file), candidate.contents); await assert.rejects( createReferenceDistribution({ repoRoot: root, outputDirectory: path.join(temporary, 'release'), version: '0.1.0-alpha.1', sourceRevision: 'a'.repeat(40), }), candidate.error, ); } finally { await rm(temporary, { recursive: true, force: true }); } }); } }); test('publishes verified draft assets behind an exact tag', async () => { const workflow = await readFile( new URL( '../../.github/workflows/release-managed-agent-reference.yml', import.meta.url, ), 'utf8', ); const draft = workflow.indexOf('draft:true'); const upload = workflow.indexOf('gh release upload'); const assetVerification = workflow.indexOf('actual_names='); const digestVerification = workflow.indexOf('remote_digest='); const digestMismatch = workflow.indexOf('Uploaded digest mismatch'); const tag = workflow.indexOf('git/refs'); const publish = workflow.indexOf('-F draft=false'); assert.ok(draft >= 0); assert.ok(draft < upload); assert.ok(upload < assetVerification); assert.ok(assetVerification < digestVerification); assert.ok(digestVerification < digestMismatch); assert.ok(digestMismatch < tag); assert.ok(assetVerification < tag); assert.ok(tag < publish); assert.match(workflow, /Accept: application\/octet-stream/); assert.match(workflow, /remote_digest.*!=.*local_digest/); assert.match(workflow, /scripts\/contract-version-utils\.js/); assert.match(workflow, /scripts\/flyway-migration-utils\.js/); assert.match(workflow, /grep -x 'managed-agent-reference-v\.\*'/); assert.match(workflow, /previous_tag_name:\$previous/); });