test(#829): bind runtime launch to broker identity
This commit is contained in:
@@ -22,6 +22,7 @@ interface BrokerPaths {
|
||||
const frameworkRoot = new URL('../../framework/', import.meta.url).pathname;
|
||||
const daemonPath = join(frameworkRoot, 'tools/lease-broker/daemon.py');
|
||||
const gatePath = join(frameworkRoot, 'tools/lease-broker/mutator-gate.py');
|
||||
const launcherPath = join(frameworkRoot, 'tools/lease-broker/launch-runtime.py');
|
||||
const claudeSettingsPath = join(frameworkRoot, 'runtime/claude/settings.json');
|
||||
const piExtensionPath = join(frameworkRoot, 'runtime/pi/mosaic-extension.ts');
|
||||
const children: ChildProcess[] = [];
|
||||
@@ -288,6 +289,51 @@ describe('whole mutator-class lease gate', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('runtime launcher anchors broker identity before exec and fails closed without broker', async () => {
|
||||
const { socket } = await startBroker();
|
||||
const probe = [
|
||||
'import json,os,socket',
|
||||
's=socket.socket(socket.AF_UNIX,socket.SOCK_STREAM)',
|
||||
"s.connect(os.environ['MOSAIC_LEASE_BROKER_SOCKET'])",
|
||||
"request={'action':'authorize_tool','session_id':os.environ['MOSAIC_LEASE_SESSION_ID'],'runtime_generation':int(os.environ['MOSAIC_RUNTIME_GENERATION']),'runtime':'claude','tool_name':'Read'}",
|
||||
"s.sendall((json.dumps(request)+'\\n').encode())",
|
||||
's.shutdown(socket.SHUT_WR)',
|
||||
"print(json.dumps({'session_id':os.environ['MOSAIC_LEASE_SESSION_ID'],'reply':json.loads(s.recv(65536))}))",
|
||||
].join(';');
|
||||
const launched = spawnSync(
|
||||
'python3',
|
||||
[launcherPath, '--runtime', 'claude', '--', 'python3', '-c', probe],
|
||||
{
|
||||
encoding: 'utf8',
|
||||
env: {
|
||||
...process.env,
|
||||
MOSAIC_LEASE_BROKER_SOCKET: socket,
|
||||
MOSAIC_RUNTIME_GENERATION: '1',
|
||||
},
|
||||
},
|
||||
);
|
||||
expect(launched.status, launched.stderr).toBe(0);
|
||||
expect(JSON.parse(launched.stdout)).toMatchObject({
|
||||
session_id: expect.stringMatching(/^[a-f0-9]{64}$/),
|
||||
reply: { ok: true, decision: 'allow' },
|
||||
});
|
||||
|
||||
const unavailable = spawnSync(
|
||||
'python3',
|
||||
[launcherPath, '--runtime', 'claude', '--', 'python3', '-c', "print('EXECUTED')"],
|
||||
{
|
||||
encoding: 'utf8',
|
||||
env: {
|
||||
...process.env,
|
||||
MOSAIC_LEASE_BROKER_SOCKET: join(tmpdir(), 'missing-mosaic-broker.sock'),
|
||||
MOSAIC_RUNTIME_GENERATION: '1',
|
||||
},
|
||||
},
|
||||
);
|
||||
expect(unavailable.status).not.toBe(0);
|
||||
expect(unavailable.stdout).not.toContain('EXECUTED');
|
||||
});
|
||||
|
||||
test('Claude and Pi runtime adapters consult the broker for every tool class', async () => {
|
||||
const { socket } = await startBroker();
|
||||
const sessionId = await register(socket);
|
||||
|
||||
Reference in New Issue
Block a user