Skip to content

Commit 7ebdb6d

Browse files
committed
test: state one invocation the same way everywhere
Every test that needed an invocation record built its own copy of the opening fact: eight near-identical constructors plus a dozen inline literals, all restating defaults nothing asserts on. Fold them onto the one fixture, which now merges configuration field by field so a test states only the setting it is about, and writes failureClass where the read model looks for it. Drop the cases that only restate a schema — protocol literal, enum member, empty lineage, each empty legacy field — and keep the ones that carry a rule: which routes may name a connection, which roots exist, that a continuation names its boundary, that a malformed opening fails the whole decode. Generated-by: Claude Code
1 parent 450ff3f commit 7ebdb6d

24 files changed

Lines changed: 169 additions & 595 deletions

packages/core/src/__tests__/runtime-invocation-opened.test.ts

Lines changed: 30 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -94,79 +94,30 @@ describe('invocation_opened content contract', () => {
9494
assert.equal(runtimeEventHasModelVisibleContent(event), false);
9595
});
9696

97-
test('accepts the unknown route provenance without connection identity', () => {
98-
const fact = decodeRuntimeInvocationOpened(
99-
opening({
100-
route: {
101-
provenance: 'unknown',
102-
backendKind: 'ai-sdk',
103-
llmConnectionSlug: 'legacy',
104-
modelId: 'legacy-model',
105-
},
106-
}),
107-
);
108-
assert.equal(fact.route.provenance, 'unknown');
109-
});
110-
111-
test('rejects an unknown route that still carries a connection identity', () => {
112-
assert.throws(() =>
113-
decodeRuntimeInvocationOpened(
114-
opening({
115-
route: {
116-
provenance: 'unknown',
117-
backendKind: 'ai-sdk',
118-
llmConnectionSlug: 'legacy',
119-
modelId: 'legacy-model',
120-
llmConnectionId: 'conn-1',
121-
} as never,
122-
}),
123-
),
124-
);
125-
});
126-
127-
test('rejects a runtime route with no connection identity', () => {
128-
assert.throws(() =>
129-
decodeRuntimeInvocationOpened(
130-
opening({
131-
route: {
132-
provenance: 'runtime',
133-
backendKind: 'ai-sdk',
134-
llmConnectionSlug: 'anthropic',
135-
modelId: 'claude-x',
136-
} as never,
137-
}),
138-
),
139-
);
140-
});
141-
142-
test('rejects an unversioned or misversioned protocol', () => {
143-
assert.throws(() => decodeRuntimeInvocationOpened(opening({ protocol: 'v2' as never })));
144-
const { protocol: _protocol, ...withoutProtocol } = opening();
145-
assert.throws(() => decodeRuntimeInvocationOpened(withoutProtocol));
146-
});
147-
148-
test('rejects an unknown extra field anywhere in the closed shape', () => {
149-
assert.throws(() =>
150-
decodeRuntimeInvocationOpened({ ...opening(), runComposition: {} } as never),
97+
test('binds connection identity to where the route came from, both ways', () => {
98+
const unknownRoute = {
99+
provenance: 'unknown',
100+
backendKind: 'ai-sdk',
101+
llmConnectionSlug: 'legacy',
102+
modelId: 'legacy-model',
103+
} as const;
104+
assert.equal(
105+
decodeRuntimeInvocationOpened(opening({ route: unknownRoute })).route.provenance,
106+
'unknown',
151107
);
152108
assert.throws(() =>
153109
decodeRuntimeInvocationOpened(
154-
opening({
155-
configuration: { ...opening().configuration, sessionMode: 'agent' } as never,
156-
}),
110+
opening({ route: { ...unknownRoute, llmConnectionId: 'conn-1' } as never }),
157111
),
158112
);
159-
});
160-
161-
test('rejects a root authority that mixes two roots', () => {
162113
assert.throws(() =>
163114
decodeRuntimeInvocationOpened(
164-
opening({ root: { kind: 'goal', goalId: 'g1', scheduledTaskId: 's1' } as never }),
115+
opening({ route: { ...unknownRoute, provenance: 'runtime' } as never }),
165116
),
166117
);
167118
});
168119

169-
test('accepts every root authority the runtime can open', () => {
120+
test('accepts every root authority the runtime can open, and no mixture of them', () => {
170121
for (const root of [
171122
{ kind: 'user' },
172123
{ kind: 'context_compact' },
@@ -177,49 +128,42 @@ describe('invocation_opened content contract', () => {
177128
] as const) {
178129
assert.equal(decodeRuntimeInvocationOpened(opening({ root })).root.kind, root.kind);
179130
}
131+
assert.throws(() =>
132+
decodeRuntimeInvocationOpened(
133+
opening({ root: { kind: 'goal', goalId: 'g1', scheduledTaskId: 's1' } as never }),
134+
),
135+
);
180136
});
181137

182-
test('carries the continuation source identity when the invocation continues one', () => {
138+
test('carries a continuation source only with the boundary position it resumes from', () => {
139+
const source = {
140+
kind: 'continuation',
141+
sourceInvocationId: 'inv-0',
142+
sourceRunId: 'inv-0',
143+
sourceTurnId: 'turn-0',
144+
} as const;
183145
const fact = decodeRuntimeInvocationOpened(
184146
opening({
185147
source: {
186-
kind: 'continuation',
187-
sourceInvocationId: 'inv-0',
188-
sourceRunId: 'inv-0',
189-
sourceTurnId: 'turn-0',
148+
...source,
190149
sourceRuntimeEventHighWater: 7,
191150
claimId: 'claim-1',
192151
boundaryDigest: DIGEST,
193152
},
194153
}),
195154
);
196155
assert.equal(fact.source.kind, 'continuation');
156+
assert.throws(() => decodeRuntimeInvocationOpened(opening({ source: source as never })));
197157
});
198158

199-
test('rejects a continuation source missing its boundary position', () => {
159+
test('rejects anything the closed shape does not name', () => {
200160
assert.throws(() =>
201-
decodeRuntimeInvocationOpened(
202-
opening({
203-
source: {
204-
kind: 'continuation',
205-
sourceInvocationId: 'inv-0',
206-
sourceRunId: 'inv-0',
207-
sourceTurnId: 'turn-0',
208-
} as never,
209-
}),
210-
),
161+
decodeRuntimeInvocationOpened({ ...opening(), runComposition: {} } as never),
211162
);
212-
});
213-
214-
test('rejects an empty lineage object rather than storing a meaningless key', () => {
215-
assert.throws(() => decodeRuntimeInvocationOpened(opening({ lineage: {} })));
216-
});
217-
218-
test('rejects an invalid enum member in configuration', () => {
219163
assert.throws(() =>
220164
decodeRuntimeInvocationOpened(
221165
opening({
222-
configuration: { ...opening().configuration, toolMode: 'telepathy' } as never,
166+
configuration: { ...opening().configuration, sessionMode: 'agent' } as never,
223167
}),
224168
),
225169
);

packages/runtime/src/__tests__/agent-graph-timeline.test.ts

Lines changed: 14 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import {
3131
readAgentGraphTimelinePage,
3232
} from '../agent-graph-timeline.js';
3333
import { readCommittedAgentGraphProjection } from '../stream-graph-projection.js';
34+
import { testInvocationRecord } from './invocation-fixture.js';
3435

3536
describe('agent graph replay timeline', () => {
3637
test('reconstructs control, child records, parent completion, and supervisor wake chronologically', async () => {
@@ -570,57 +571,27 @@ function runInvocation(input: {
570571
status?: 'completed' | 'failed' | 'aborted';
571572
wake?: { wakeId: string; attemptId: string };
572573
}): RuntimeInvocationRecord {
573-
const identity = {
574+
return testInvocationRecord({
574575
sessionId: input.sessionId,
575576
invocationId: `invocation-${input.runId}`,
576577
runId: input.runId,
577578
turnId: input.turnId,
578-
};
579-
return {
580-
...identity,
581579
openedAt: input.createdAt,
582-
opening: {
583-
kind: 'invocation_opened',
584-
protocol: 'invocation_opened_v1',
585-
route: {
586-
provenance: 'runtime',
587-
backendKind: 'ai-sdk',
588-
llmConnectionId: 'deepseek-connection',
589-
llmConnectionSlug: 'deepseek',
590-
modelId: 'deepseek-chat',
591-
},
592-
configuration: {
593-
cwd: '/workspace',
594-
permissionMode: 'explore',
595-
collaborationMode: 'agent',
596-
orchestrationMode: 'default',
597-
orchestrationSource: 'session',
598-
toolMode: 'direct',
599-
},
600-
root: input.wake
601-
? {
602-
kind: 'agent_graph_supervisor_wake',
603-
wakeId: input.wake.wakeId,
604-
attemptId: input.wake.attemptId,
605-
}
606-
: { kind: 'user' },
607-
source: { kind: 'fresh' },
608-
},
609-
...(input.completedAt !== undefined
580+
...(input.wake
610581
? {
611-
terminalEvent: {
612-
...identity,
613-
id: `${input.runId}-terminal`,
614-
ts: input.completedAt,
615-
partial: false,
616-
role: 'system',
617-
author: 'system',
618-
status: input.status ?? 'completed',
619-
actions: { endInvocation: true },
620-
} satisfies RuntimeEvent,
582+
opening: {
583+
root: {
584+
kind: 'agent_graph_supervisor_wake',
585+
wakeId: input.wake.wakeId,
586+
attemptId: input.wake.attemptId,
587+
},
588+
},
621589
}
622590
: {}),
623-
};
591+
...(input.completedAt !== undefined
592+
? { closedAt: input.completedAt, outcome: input.status ?? 'completed' }
593+
: {}),
594+
});
624595
}
625596

626597
function runtimeEvent(

packages/runtime/src/__tests__/agent-run-inspect.test.ts

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import {
2828
runtimeInvocationsFromSessionEvents,
2929
} from '@maka/core/runtime-invocation';
3030
import { inspectAgentRunReadModel } from '../agent-run-inspect.js';
31+
import { testInvocationOpening } from './invocation-fixture.js';
3132

3233
const sessionId = 'session-1';
3334
const invocationId = 'inv-1';
@@ -243,27 +244,9 @@ class MemoryAgentRunStore implements AgentRunStore, RuntimeEventStore {
243244
}
244245

245246
function makeOpening(): RuntimeEventInvocationOpenedContent {
246-
return {
247-
kind: 'invocation_opened',
248-
protocol: 'invocation_opened_v1',
249-
route: {
250-
provenance: 'runtime',
251-
backendKind: 'fake',
252-
llmConnectionId: 'fake-connection',
253-
llmConnectionSlug: 'fake',
254-
modelId: 'fake-model',
255-
},
256-
configuration: {
257-
cwd: '/tmp/cwd',
258-
permissionMode: 'ask',
259-
collaborationMode: 'agent',
260-
orchestrationMode: 'default',
261-
orchestrationSource: 'session',
262-
toolMode: 'direct',
263-
},
264-
root: { kind: 'user' },
265-
source: { kind: 'fresh' },
266-
};
247+
return testInvocationOpening({
248+
configuration: { cwd: '/tmp/cwd' },
249+
});
267250
}
268251

269252
/** The invocation a run is named by, for the cases whose ledger is unreadable. */

packages/runtime/src/__tests__/agent-run-recovery.test.ts

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import assert from 'node:assert/strict';
2121
import { describe, test } from 'node:test';
2222
import type { RuntimeInvocationRecord } from '@maka/core/runtime-invocation';
2323
import { classifyAgentRunRecovery } from '../agent-run-recovery.js';
24+
import { testInvocationOpening } from './invocation-fixture.js';
2425

2526
describe('AgentRun startup recovery', () => {
2627
test('fails a graph supervisor permission handoff once its live waiter is lost', () => {
@@ -30,27 +31,17 @@ describe('AgentRun startup recovery', () => {
3031
runId: 'run-1',
3132
turnId: 'turn-1',
3233
openedAt: 1,
33-
opening: {
34-
kind: 'invocation_opened',
35-
protocol: 'invocation_opened_v1',
34+
opening: testInvocationOpening({
3635
route: {
3736
provenance: 'runtime',
3837
backendKind: 'fake',
3938
llmConnectionId: 'fake-connection',
4039
llmConnectionSlug: 'fake',
4140
modelId: 'fake-model',
4241
},
43-
configuration: {
44-
cwd: '/tmp/workspace',
45-
permissionMode: 'ask',
46-
collaborationMode: 'agent',
47-
orchestrationMode: 'default',
48-
orchestrationSource: 'session',
49-
toolMode: 'direct',
50-
},
42+
configuration: { cwd: '/tmp/workspace' },
5143
root: { kind: 'agent_graph_supervisor_wake', wakeId: 'wake-1', attemptId: 'attempt-1' },
52-
source: { kind: 'fresh' },
53-
},
44+
}),
5445
};
5546

5647
const decision = classifyAgentRunRecovery(invocation, [

packages/runtime/src/__tests__/ai-sdk-backend.test.ts

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ import type { OpenAiResponsesSemanticBaseline } from '../openai-responses-contin
9595
import type { OpenAiResponsesTransportState } from '../openai-responses-websocket.js';
9696
import { getAIModel } from '../model-factory.js';
9797
import { waitFor as pollFor } from '@maka/core/test-only/async-primitives';
98+
import { testInvocationOpening } from './invocation-fixture.js';
9899

99100
describe('AiSdkBackend ApplyPatch routing', () => {
100101
test('advertises apply_patch only to supported native OpenAI models', async () => {
@@ -16071,9 +16072,7 @@ function priorModelInvocation(input: {
1607116072
return {
1607216073
...identity,
1607316074
openedAt: 1,
16074-
opening: {
16075-
kind: 'invocation_opened',
16076-
protocol: 'invocation_opened_v1',
16075+
opening: testInvocationOpening({
1607716076
route: {
1607816077
provenance: 'runtime',
1607916078
backendKind: 'ai-sdk',
@@ -16082,17 +16081,9 @@ function priorModelInvocation(input: {
1608216081
modelId: input.modelId,
1608316082
providerStateIdentity: input.providerStateIdentity ?? `sha256:${'1'.repeat(64)}`,
1608416083
},
16085-
configuration: {
16086-
cwd: '/tmp/maka',
16087-
permissionMode: 'ask',
16088-
collaborationMode: 'agent',
16089-
orchestrationMode: 'default',
16090-
orchestrationSource: 'session',
16091-
toolMode: 'direct',
16092-
},
16084+
configuration: { cwd: '/tmp/maka' },
1609316085
root: input.root ?? { kind: 'user' },
16094-
source: { kind: 'fresh' },
16095-
},
16086+
}),
1609616087
terminalEvent: {
1609716088
id: `${identity.runId}-terminal`,
1609816089
...identity,

packages/runtime/src/__tests__/computer-use-provider-protocol.test.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import { backfillRuntimeEventsFromStoredMessages } from '../runtime-event-backfi
4242
import { createDurableTurnHarness } from './durable-turn-harness.js';
4343
import { createTestAiSdkBackend } from './execution-boundary-test-helpers.js';
4444
import { latestObservationIn } from './observation-text-reader.js';
45+
import { testInvocationOpening } from './invocation-fixture.js';
4546

4647
const servers: Array<{ close(): Promise<void> }> = [];
4748
const PROVIDER_STATE_IDENTITY = `sha256:${'1'.repeat(64)}` as const;
@@ -1604,9 +1605,7 @@ function sourceInvocation(input: {
16041605
return {
16051606
...identity,
16061607
openedAt: input.openedAt,
1607-
opening: {
1608-
kind: 'invocation_opened',
1609-
protocol: 'invocation_opened_v1',
1608+
opening: testInvocationOpening({
16101609
route: {
16111610
provenance: 'runtime',
16121611
backendKind: 'ai-sdk',
@@ -1623,9 +1622,7 @@ function sourceInvocation(input: {
16231622
orchestrationSource: 'session',
16241623
toolMode: 'direct',
16251624
},
1626-
root: { kind: 'user' },
1627-
source: { kind: 'fresh' },
1628-
},
1625+
}),
16291626
terminalEvent: {
16301627
...identity,
16311628
id: `${input.runId}-terminal`,

0 commit comments

Comments
 (0)