Skip to content

Commit 0c0bc73

Browse files
grypezclaude
andcommitted
test(caprock): assert KernelSessionStruct accepts the session.create response
Guards the caprock RPC boundary against drifting from the daemon's `session.create` / `session.list` response shape. The struct is a strict `object()`, so an undeclared field makes `assert(result, KernelSessionStruct)` in `createKernelSession` throw — which silently breaks the SessionStart and PreToolUse hooks (native permission prompts, no TUI routing). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 2681e5e commit 0c0bc73

1 file changed

Lines changed: 36 additions & 0 deletions

File tree

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { is } from '@metamask/superstruct';
2+
import { describe, expect, it } from 'vitest';
3+
4+
import { KernelSessionStruct } from './structs.ts';
5+
6+
describe('KernelSessionStruct', () => {
7+
// These fixtures mirror the object the daemon returns from `session.create`
8+
// (and each entry of `session.list`) in
9+
// packages/kernel-node-runtime/src/daemon/rpc-socket-server.ts. The struct is
10+
// a strict `object()`, so it rejects any field it does not declare — if the
11+
// daemon adds a field to that response, extend both the struct and this
12+
// fixture. A prior omission of `lastActiveAt` made every `session.create`
13+
// response fail `assert(result, KernelSessionStruct)` in
14+
// `createKernelSession`, which broke the SessionStart and PreToolUse hooks.
15+
it.each([
16+
{
17+
shape: 'full response',
18+
response: {
19+
sessionId: 'alice',
20+
ocapUrl: 'ocap://kernel/session/alice',
21+
cwd: '/home/user/project',
22+
startedAt: '2026-07-01T00:00:00.000Z',
23+
lastActiveAt: '2026-07-01T00:05:00.000Z',
24+
},
25+
},
26+
{
27+
shape: 'minimal response (optional fields absent)',
28+
response: {
29+
sessionId: 'bob',
30+
ocapUrl: 'ocap://kernel/session/bob',
31+
},
32+
},
33+
])('accepts the daemon session.create $shape', ({ response }) => {
34+
expect(is(response, KernelSessionStruct)).toBe(true);
35+
});
36+
});

0 commit comments

Comments
 (0)