fix(#829): gate claudex and close branch coverage gaps
All checks were successful
ci/woodpecker/pr/ci Pipeline was successful
All checks were successful
ci/woodpecker/pr/ci Pipeline was successful
This commit is contained in:
@@ -244,6 +244,52 @@ describe('whole mutator-class lease gate', () => {
|
||||
}
|
||||
});
|
||||
|
||||
test('lease and tool validation failures remain fail-closed at the broker boundary', async () => {
|
||||
const { socket } = await startBroker();
|
||||
const sessionId = await register(socket);
|
||||
const baseRequest = {
|
||||
action: 'begin_verification',
|
||||
session_id: sessionId,
|
||||
runtime_generation: 1,
|
||||
runtime: 'claude',
|
||||
ttl_seconds: 300,
|
||||
binding: binding(),
|
||||
};
|
||||
|
||||
expect(await request(socket, { ...baseRequest, runtime: 'codex' })).toMatchObject({
|
||||
ok: false,
|
||||
code: 'INVALID_RUNTIME',
|
||||
});
|
||||
expect(
|
||||
await request(socket, { ...baseRequest, binding: { ...binding(), h_source: 'bad' } }),
|
||||
).toMatchObject({
|
||||
ok: false,
|
||||
code: 'INVALID_BINDING',
|
||||
});
|
||||
expect(await request(socket, { ...baseRequest, ttl_seconds: 0 })).toMatchObject({
|
||||
ok: false,
|
||||
code: 'INVALID_LEASE_TTL',
|
||||
});
|
||||
expect(
|
||||
await request(socket, {
|
||||
action: 'authorize_tool',
|
||||
session_id: sessionId,
|
||||
runtime_generation: 1,
|
||||
runtime: 'codex',
|
||||
tool_name: 'Read',
|
||||
}),
|
||||
).toMatchObject({ ok: false, code: 'INVALID_RUNTIME' });
|
||||
expect(
|
||||
await request(socket, {
|
||||
action: 'authorize_tool',
|
||||
session_id: sessionId,
|
||||
runtime_generation: 1,
|
||||
runtime: 'claude',
|
||||
tool_name: 'x'.repeat(257),
|
||||
}),
|
||||
).toMatchObject({ ok: false, code: 'INVALID_TOOL' });
|
||||
});
|
||||
|
||||
test('observer revocation and monotonic TTL expiry deny the next mutator', async () => {
|
||||
const { socket } = await startBroker();
|
||||
const sessionId = await register(socket);
|
||||
@@ -400,9 +446,7 @@ raise SystemExit(0 if len(session_id) == 64 and hook_present and denied else 1)
|
||||
const adapter = {
|
||||
harnessPreflight: () => {},
|
||||
composePrompt: () => '# composed Claude contract',
|
||||
// Pre-remediation Claudex uses this direct boundary and therefore bypasses registration.
|
||||
exec: run,
|
||||
// The remediated orchestration must select this shared register-before-exec boundary.
|
||||
// Claudex exposes only the shared register-before-exec boundary.
|
||||
execLeaseGated: (args: string[], env: NodeJS.ProcessEnv) =>
|
||||
run('python3', [launcherPath, '--runtime', 'claude', '--', 'claude', ...args], env),
|
||||
} as unknown as ClaudexHarnessAdapter;
|
||||
@@ -438,8 +482,8 @@ raise SystemExit(0 if len(session_id) == 64 and hook_present and denied else 1)
|
||||
});
|
||||
|
||||
expect(execution).toBeDefined();
|
||||
expect(execution!.status, execution!.stderr).toBe(0);
|
||||
expect(JSON.parse(execution!.stdout)).toEqual({
|
||||
expect(execution!.status, String(execution!.stderr)).toBe(0);
|
||||
expect(JSON.parse(String(execution!.stdout))).toEqual({
|
||||
session_id: expect.stringMatching(/^[a-f0-9]{64}$/),
|
||||
hook_present: true,
|
||||
denied: true,
|
||||
|
||||
Reference in New Issue
Block a user