Files
stack/packages/bus/tests/process.test.mjs
T
jason.woltjeandClaude Opus 5.5 38828a2cb3 feat(bus): the bus and the broker core (row 37, S2, rocko)
Rocko's round 2 candidate, approved by Darkwing (#1519 comment 26757).
build.patch 40d7e838, manifest 61519059, 24 files under packages/bus,
schema v3b (179ffe35, lead decision 60). Integration gate in a git
worktree of 942dca9e (S1 in the tree) plus the patch: bus 43/43 and
business 60/60 on Node 24 and 26, every package test and every
scripts/test-*.sh green, test-task 98/98 with the live-provider cases.
Rulings from lead decisions 62 and 63: the human proof is cooperative in
slice 1, and a self-raised cross-role decision routes to the human.
Single-use gated approvals follow in row 43.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 17:15:53 -05:00

194 lines
8.1 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import { fork } from 'node:child_process';
import { mkdtempSync, rmSync, existsSync, writeFileSync, mkdirSync, readFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { once } from 'node:events';
import { Client } from '../src/client.mjs';
const businesses = {
demo: {
id: 'demo',
human: 'jason',
arbiters: { technical: 'cto', delivery: 'cto' },
roles: { cto: { authority: { withinRole: ['message.send'], crossRole: [] } } },
},
};
function launch(t) {
const child = fork(new URL('../src/process.mjs', import.meta.url), [], {
stdio: ['ignore', 'pipe', 'pipe', 'ipc'],
});
let logs = '';
child.stdout.on('data', (b) => (logs += b));
child.stderr.on('data', (b) => (logs += b));
t.after(() => {
if (child.exitCode === null) child.kill('SIGKILL');
});
return { child, logs: () => logs };
}
async function boot(child, config) {
const reply = Promise.race([
once(child, 'message'),
once(child, 'exit').then(() => {
throw Error('exited-before-reply');
}),
]);
child.send({ op: 'boot', config });
return (await reply)[0];
}
test('broker process binds trusted launches, offers reader capabilities, refuses human mutation, closes cleanly', async (t) => {
const root = mkdtempSync(join(tmpdir(), 'bus-process-'));
t.after(() => rmSync(root, { recursive: true, force: true }));
const { child } = launch(t);
const ready = await boot(child, {
dataRoot: root,
businesses,
launches: [{ business: 'demo', role: 'cto', run: 'r1', harness: 'pi', pid: process.pid, startTime: '1' }],
readers: ['demo'],
});
assert.equal(ready.ok, true);
const agent = new Client({ path: ready.path, cap: ready.launches[0].cap });
await agent.call('role.claim');
const reader = new Client({ path: ready.path, cap: ready.readers[0].cap });
assert.equal((await reader.call('agents'))[0].holder_run, 'r1');
await assert.rejects(reader.call('launch.revoke'), /read-only/);
await assert.rejects(
new Client({
path: ready.path,
human: { business: 'demo', pid: process.pid, startTime: '1', nonce: 'f'.repeat(64) },
}).call('launch.revoke'),
/human-required/,
);
const exit = once(child, 'exit');
child.send({ op: 'close' });
assert.equal((await exit)[0], 0);
assert.equal(existsSync(join(root, 'bus/writer.lock')), false);
});
test('startup token refusal returns safe code without value or partial listening broker', async (t) => {
const root = mkdtempSync(join(tmpdir(), 'bus-boot-'));
t.after(() => rmSync(root, { recursive: true, force: true }));
const data = join(root, 'data');
mkdirSync(data);
const secret = 'fixture-token-never-in-db-948723';
const file = join(root, 'secret');
writeFileSync(file, secret, { mode: 0o644 });
const config = structuredClone(businesses);
config.demo.roles.cto.credentials = { gitea: { file, rotateBy: '2099-01-01' } };
const { child, logs } = launch(t);
const exit = once(child, 'exit');
const ready = await boot(child, { dataRoot: data, businesses: config, launches: [], readers: [] });
assert.equal(ready.ok, false);
assert.equal(ready.error, 'credential-file');
assert.equal((await exit)[0], 2);
assert.ok(!logs().includes(secret));
assert.equal(existsSync(join(data, 'bus/broker.sock')), false);
});
test('loaded fixture token is absent from socket replies and SQLite, including refusal evidence', async (t) => {
const root = mkdtempSync(join(tmpdir(), 'bus-secret-'));
t.after(() => rmSync(root, { recursive: true, force: true }));
const data = join(root, 'data');
mkdirSync(data);
const token = 'fixture-opaque-token-e9c39140';
const file = join(root, 'token');
writeFileSync(file, token, { mode: 0o600 });
const config = structuredClone(businesses);
config.demo.roles.cto.credentials = { gitea: { file, rotateBy: '2099-01-01' } };
const { child, logs } = launch(t);
const ready = await boot(child, {
dataRoot: data,
businesses: config,
launches: [{ business: 'demo', role: 'cto', run: 'r2', harness: 'pi', pid: process.pid, startTime: '1' }],
});
assert.equal(ready.ok, true);
const c = new Client({ path: ready.path, cap: ready.launches[0].cap });
await c.call('role.claim');
await assert.rejects(c.call('message.send', { to: 'cto', body: token }), /credential-leak/);
const exit = once(child, 'exit');
child.send({ op: 'close' });
await exit;
assert.ok(!readFileSync(join(data, 'bus/bus.sqlite')).includes(Buffer.from(token)));
assert.ok(!logs().includes(token));
});
test('killed broker leaves an explicit stale lock; another process cannot silently reclaim it', async (t) => {
const root = mkdtempSync(join(tmpdir(), 'bus-crash-'));
t.after(() => rmSync(root, { recursive: true, force: true }));
const first = launch(t);
const config = { dataRoot: root, businesses, launches: [] };
assert.equal((await boot(first.child, config)).ok, true);
const killed = once(first.child, 'exit');
first.child.kill('SIGKILL');
await killed;
assert.equal(existsSync(join(root, 'bus/writer.lock')), true);
const second = launch(t),
ended = once(second.child, 'exit');
const refusal = await boot(second.child, config);
assert.equal(refusal.ok, false);
assert.equal((await ended)[0], 2);
assert.equal(existsSync(join(root, 'bus/writer.lock')), true);
});
test('trusted host registers later launches; socket clients never have a registration verb', async (t) => {
const root = mkdtempSync(join(tmpdir(), 'bus-add-'));
t.after(() => rmSync(root, { recursive: true, force: true }));
const { child } = launch(t);
const ready = await boot(child, { dataRoot: root, businesses, launches: [] });
assert.equal(ready.ok, true);
const message = once(child, 'message');
child.send({
op: 'bindLaunch',
record: { business: 'demo', role: 'cto', run: 'later', harness: 'pi', pid: process.pid, startTime: '1' },
});
const bound = (await message)[0];
assert.equal(bound.ok, true);
const c = new Client({ path: ready.path, cap: bound.launch.cap });
await c.call('role.claim');
await assert.rejects(c.call('bindLaunch', { role: 'cto' }), /unknown-verb/);
const exit = once(child, 'exit');
child.send({ op: 'close' });
assert.equal((await exit)[0], 0);
});
test('runtime excludes declared project roots even when host supplies no repoRoots', async (t) => {
const root = mkdtempSync(join(tmpdir(), 'bus-project-token-'));
t.after(() => rmSync(root, { recursive: true, force: true }));
const data = join(root, 'data');
mkdirSync(data);
const project = join(root, 'project');
mkdirSync(project);
const file = join(project, 'token');
writeFileSync(file, 'fixture-do-not-load-from-project', { mode: 0o600 });
const config = structuredClone(businesses);
config.demo.projects = { stack: { root: project } };
config.demo.roles.cto.credentials = { gitea: { file, rotateBy: '2099-01-01' } };
const { child } = launch(t),
exit = once(child, 'exit');
const result = await boot(child, { dataRoot: data, businesses: config });
assert.equal(result.ok, false);
assert.equal(result.error, 'credential-location');
assert.equal((await exit)[0], 2);
});
test('a refused launch binding leaves the broker and existing capabilities alive; bad protocol stops it', async (t) => {
const root = mkdtempSync(join(tmpdir(), 'bus-bind-refusal-'));
t.after(() => rmSync(root, { recursive: true, force: true }));
const { child } = launch(t);
const record = {
business: 'demo',
role: 'cto',
run: 'one',
harness: 'pi',
pid: process.pid,
startTime: '1',
};
const ready = await boot(child, { dataRoot: root, businesses, launches: [record] });
assert.equal(ready.ok, true);
const client = new Client({ path: ready.path, cap: ready.launches[0].cap });
await client.call('role.claim');
const reply = once(child, 'message');
child.send({ op: 'bindLaunch', record });
assert.deepEqual((await reply)[0], { ok: false, error: 'duplicate-run' });
assert.equal((await client.call('agents'))[0].holder_run, 'one');
const bad = once(child, 'message'),
exit = once(child, 'exit');
child.send({ op: 'not-a-protocol-verb' });
assert.equal((await bad)[0].ok, false);
assert.equal((await exit)[0], 2);
});