@linzumi/cli 1.0.111 → 1.0.113

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,288 @@
1
+ // Spec: kandan/plans/2026-07-10-compute-nodes-rescript-commander-zero-ts-program.md
2
+ // (M3 cluster 10, commander core) +
3
+ // plans/2026-07-11-runner-generation-overlap-zero-downtime-updates.md
4
+ // (the ported surface's own spec, CLI half #2981).
5
+ // Relationship: Builds the TS-side PARITY ORACLE for the generation-overlap
6
+ // slice of the ReScript commander port, the sibling of
7
+ // build-pipeline-parity-oracle.mjs (cluster 9) and
8
+ // build-session-registry-parity-oracle.mjs (cluster 6). The oracle bundles
9
+ // the REAL TS generation-overlap module (src/generationOverlap.ts) - env
10
+ // flag/readers, join-hello envelope, the supervisor<->child IPC codec, the
11
+ // per-process overlap runtime, the dispatch gate's held-control queues,
12
+ // and the cursor-persistence freeze - behind the cluster 1/2 one-shot
13
+ // BATCH driver (a JSON array of cases on stdin, a JSON array of results on
14
+ // stdout).
15
+ //
16
+ // Byte parity: envelopes, parsed/built IPC frames, and every scripted
17
+ // trace entry are returned VERBATIM (the TS objects' own key order rides
18
+ // JSON.stringify), so the ReScript side must reproduce field presence AND
19
+ // insertion order exactly - the hello and IPC payloads are frozen wire
20
+ // bytes. Determinism: nothing here reads env, clocks, or process.send -
21
+ // env dicts are scripted per case, the runtime's send seam is injected,
22
+ // and runtime/gate/freeze flows are driven by scripted op arrays.
23
+ //
24
+ // SECRETS: the oracle only ever sees the conformance suite's synthetic
25
+ // payloads. The output is a local test artifact (.differential/ is
26
+ // gitignored, never published) and stays unminified for debuggability.
27
+ import { mkdir } from 'node:fs/promises';
28
+ import { dirname, join } from 'node:path';
29
+ import { fileURLToPath } from 'node:url';
30
+ import { build } from 'esbuild';
31
+
32
+ const packageRoot = dirname(dirname(fileURLToPath(import.meta.url)));
33
+
34
+ const driverSource = `
35
+ import {
36
+ buildGenerationIpcMessage,
37
+ createGenerationDispatchGate,
38
+ createGenerationOverlapRuntime,
39
+ defaultGenerationStillbornWindowMs,
40
+ generationEpochEnvKey,
41
+ generationHandoffPidEnvKey,
42
+ generationHelloEnvelope,
43
+ generationOverlapFlagEnvKey,
44
+ generationStillbornWindowEnvKey,
45
+ isGenerationOverlapEnabled,
46
+ parseGenerationIpcMessage,
47
+ readGenerationEpoch,
48
+ readGenerationHandoffPid,
49
+ resolveGenerationStillbornWindowMs,
50
+ withGenerationCursorFreeze,
51
+ } from './src/generationOverlap';
52
+
53
+ // Scripted runtime flow: hooks/log/send all trace-recording, ops drive the
54
+ // REAL createGenerationOverlapRuntime.
55
+ function runRuntimeCase(caseInput) {
56
+ const trace = [];
57
+ let sendOk = true;
58
+ const runtime = createGenerationOverlapRuntime({
59
+ env: caseInput.env,
60
+ log: (event, fields) => trace.push({ t: 'log', event, fields }),
61
+ send: (message) => {
62
+ trace.push({ t: 'send', message, ok: sendOk });
63
+ return sendOk;
64
+ },
65
+ });
66
+ if (runtime === undefined) {
67
+ return { created: false, trace };
68
+ }
69
+ if (caseInput.installHooks !== false) {
70
+ runtime.hooks.onOverlapDrain = (incomingEpoch) =>
71
+ trace.push({ t: 'hook.overlapDrain', incomingEpoch });
72
+ runtime.hooks.onOverlapAbort = () => trace.push({ t: 'hook.overlapAbort' });
73
+ runtime.hooks.onPinsReleased = (released) =>
74
+ trace.push({ t: 'hook.pinsReleased', released });
75
+ runtime.hooks.onPromote = () => trace.push({ t: 'hook.promote' });
76
+ }
77
+ for (const op of caseInput.ops ?? []) {
78
+ if (op.op === 'ipc') runtime.handleIpcMessage(op.value);
79
+ else if (op.op === 'beginDrain') runtime.beginOutgoingDrain(op.threadIds);
80
+ else if (op.op === 'send') {
81
+ const message = parseGenerationIpcMessage(op.message);
82
+ if (message === undefined) trace.push({ t: 'sendSkipped' });
83
+ else runtime.sendToSupervisor(message);
84
+ } else if (op.op === 'sendResult') sendOk = op.ok === true;
85
+ else if (op.op === 'pinOutgoing') runtime.outgoingPins.pin(op.threadId);
86
+ else if (op.op === 'releaseOutgoing')
87
+ trace.push({
88
+ t: 'released',
89
+ threadId: op.threadId,
90
+ released: runtime.outgoingPins.release(op.threadId),
91
+ });
92
+ else if (op.op === 'seams') {
93
+ runtime.requestUpdateDrain('parity-trigger');
94
+ trace.push({
95
+ t: 'seams',
96
+ cancel: runtime.cancelUpdateDrain('parity-reason'),
97
+ promote: runtime.promoteRunnerLock(),
98
+ });
99
+ } else if (op.op === 'query')
100
+ trace.push({
101
+ t: 'query',
102
+ epoch: runtime.epoch,
103
+ handoffFromPid: runtime.handoffFromPid ?? null,
104
+ outgoingDrainActive: runtime.outgoingDrainActive(),
105
+ pinsKnown: runtime.pinsKnown(),
106
+ role: runtime.currentRole() ?? null,
107
+ outgoingPins: runtime.outgoingPins.snapshot(),
108
+ incomingPins: runtime.incomingPins.snapshot(),
109
+ });
110
+ }
111
+ return { created: true, trace };
112
+ }
113
+
114
+ // Scripted gate flow: controls are plain JSON envelopes; the extractors
115
+ // mirror the runner wiring (threadIdOf / controlTypeOf injected).
116
+ function runGateCase(caseInput) {
117
+ const trace = [];
118
+ const runtime = createGenerationOverlapRuntime({
119
+ env: caseInput.env,
120
+ log: (event, fields) => trace.push({ t: 'log', event, fields }),
121
+ send: () => true,
122
+ });
123
+ if (runtime === undefined) {
124
+ return { created: false, trace };
125
+ }
126
+ const gate = createGenerationDispatchGate({
127
+ runtime,
128
+ threadIdOf: (control) =>
129
+ typeof control.threadId === 'string' ? control.threadId : undefined,
130
+ controlTypeOf: (control) =>
131
+ typeof control.type === 'string' ? control.type : '',
132
+ dispatch: (control, ack) => {
133
+ trace.push({
134
+ t: 'dispatched',
135
+ id: control.id ?? null,
136
+ threadId: typeof control.threadId === 'string' ? control.threadId : null,
137
+ });
138
+ ack();
139
+ },
140
+ log: (event, fields) => trace.push({ t: 'log', event, fields }),
141
+ });
142
+ for (const op of caseInput.ops ?? []) {
143
+ if (op.op === 'control') {
144
+ const control = op.control;
145
+ gate.dispatch(control, () =>
146
+ trace.push({ t: 'ack', id: control.id ?? null })
147
+ );
148
+ } else if (op.op === 'ipc') runtime.handleIpcMessage(op.value);
149
+ else if (op.op === 'beginDrain') runtime.beginOutgoingDrain(op.threadIds);
150
+ else if (op.op === 'dispatchUnpinned')
151
+ trace.push({ t: 'dispatchUnpinned', count: gate.dispatchUnpinned() });
152
+ else if (op.op === 'redispatch')
153
+ trace.push({ t: 'redispatch', count: gate.redispatchDeferredToIncoming() });
154
+ else if (op.op === 'held') {
155
+ const counts = gate.heldCounts();
156
+ trace.push({
157
+ t: 'held',
158
+ deferredToIncoming: counts.deferredToIncoming,
159
+ deferredPinned: counts.deferredPinned,
160
+ });
161
+ }
162
+ }
163
+ return { created: true, trace };
164
+ }
165
+
166
+ // Scripted cursor-freeze flow: the underlying store is trace-recording;
167
+ // ops toggle the frozen predicate and drive the wrapped store.
168
+ function runFreezeCase(caseInput) {
169
+ const trace = [];
170
+ let frozen = false;
171
+ const store = {
172
+ initial: (topic) => (caseInput.initialValues ?? {})[topic],
173
+ onAdvance: (topic, seq) => trace.push({ t: 'store.onAdvance', topic, seq }),
174
+ reset:
175
+ caseInput.hasReset === false
176
+ ? undefined
177
+ : (topic, seq) => trace.push({ t: 'store.reset', topic, seq }),
178
+ flush: () => trace.push({ t: 'store.flush' }),
179
+ epoch: () =>
180
+ typeof caseInput.storeEpoch === 'string' ? caseInput.storeEpoch : undefined,
181
+ adoptEpoch: (epoch) => {
182
+ trace.push({ t: 'store.adoptEpoch', epoch });
183
+ return caseInput.adoptResult === true;
184
+ },
185
+ };
186
+ const wrapped = withGenerationCursorFreeze(store, () => frozen);
187
+ for (const op of caseInput.ops ?? []) {
188
+ if (op.op === 'setFrozen') frozen = op.value === true;
189
+ else if (op.op === 'initial')
190
+ trace.push({ t: 'initial', topic: op.topic, value: wrapped.initial(op.topic) ?? null });
191
+ else if (op.op === 'advance') wrapped.onAdvance(op.topic, op.seq);
192
+ else if (op.op === 'reset') {
193
+ if (wrapped.reset === undefined) trace.push({ t: 'resetUnavailable' });
194
+ else wrapped.reset(op.topic, op.seq);
195
+ } else if (op.op === 'flush') wrapped.flush();
196
+ else if (op.op === 'epoch')
197
+ trace.push({ t: 'epoch', value: wrapped.epoch() ?? null });
198
+ else if (op.op === 'adoptEpoch')
199
+ trace.push({ t: 'adoptEpoch', result: wrapped.adoptEpoch(op.epoch) });
200
+ }
201
+ return { trace };
202
+ }
203
+
204
+ function runCase(input) {
205
+ switch (input.kind) {
206
+ case 'constants':
207
+ return {
208
+ flagKey: generationOverlapFlagEnvKey,
209
+ epochKey: generationEpochEnvKey,
210
+ handoffPidKey: generationHandoffPidEnvKey,
211
+ stillbornWindowKey: generationStillbornWindowEnvKey,
212
+ defaultStillbornWindowMs: defaultGenerationStillbornWindowMs,
213
+ };
214
+ case 'envRead': {
215
+ if (input.which === 'enabled') return isGenerationOverlapEnabled(input.env);
216
+ if (input.which === 'epoch') return readGenerationEpoch(input.env) ?? null;
217
+ if (input.which === 'handoffPid')
218
+ return readGenerationHandoffPid(input.env) ?? null;
219
+ return resolveGenerationStillbornWindowMs(input.env);
220
+ }
221
+ case 'helloEnvelope':
222
+ return generationHelloEnvelope(input.env);
223
+ case 'parseIpc': {
224
+ const parsed = parseGenerationIpcMessage(input.value);
225
+ return parsed === undefined ? null : parsed;
226
+ }
227
+ case 'buildIpc': {
228
+ const parsed = parseGenerationIpcMessage(input.message);
229
+ return parsed === undefined ? { unparsable: true } : buildGenerationIpcMessage(parsed);
230
+ }
231
+ case 'runtimeRun':
232
+ return runRuntimeCase(input);
233
+ case 'gateRun':
234
+ return runGateCase(input);
235
+ case 'freezeRun':
236
+ return runFreezeCase(input);
237
+ default:
238
+ return { error: 'unknown case kind ' + String(input.kind) };
239
+ }
240
+ }
241
+
242
+ async function runBatch() {
243
+ const chunks = [];
244
+ for await (const chunk of process.stdin) chunks.push(chunk);
245
+ const cases = JSON.parse(Buffer.concat(chunks).toString('utf8'));
246
+ const results = [];
247
+ for (const testCase of cases) {
248
+ results.push(runCase(testCase));
249
+ }
250
+ process.stdout.write(JSON.stringify(results), () => {
251
+ process.exit(0);
252
+ });
253
+ }
254
+
255
+ runBatch().then(
256
+ () => {},
257
+ (error) => {
258
+ process.stderr.write(String(error && error.stack ? error.stack : error) + '\\n');
259
+ process.exit(1);
260
+ }
261
+ );
262
+ `;
263
+
264
+ const outDir = join(packageRoot, '.differential');
265
+ const outPath = join(outDir, 'core-generation-overlap-parity-oracle.mjs');
266
+
267
+ await mkdir(outDir, { recursive: true });
268
+
269
+ await build({
270
+ stdin: {
271
+ contents: driverSource,
272
+ resolveDir: packageRoot,
273
+ sourcefile: 'core-generation-overlap-parity-driver.ts',
274
+ loader: 'ts',
275
+ },
276
+ bundle: true,
277
+ platform: 'node',
278
+ target: 'node20',
279
+ format: 'esm',
280
+ outfile: outPath,
281
+ minify: false,
282
+ sourcemap: false,
283
+ legalComments: 'none',
284
+ logLevel: 'silent',
285
+ external: ['ws', 'undici', 'blessed', '@anthropic-ai/claude-agent-sdk'],
286
+ });
287
+
288
+ process.stdout.write(outPath + '\n');
@@ -0,0 +1,361 @@
1
+ // Spec: kandan/plans/2026-07-10-compute-nodes-rescript-commander-zero-ts-program.md
2
+ // (M3 cluster 10, runner core).
3
+ // Relationship: Builds the TS-side PARITY ORACLE for the pipeline
4
+ // INTEGRATION module of the ReScript commander port, the sibling of
5
+ // build-pipeline-parity-oracle.mjs (cluster 9) and
6
+ // build-queue-parity-oracle.mjs (cluster 5). The oracle bundles the REAL
7
+ // TS pipeline integration module (src/pipeline/integration.ts - the
8
+ // per-session loop + outbox lifecycle, the outbox entry builders, and the
9
+ // completion-snapshot resolution helpers) plus the real phoenix push-error
10
+ // factory and the turnTrace per-thread traceparent registry, behind the
11
+ // cluster 1/2 one-shot BATCH driver (a JSON array of cases on stdin, a
12
+ // JSON array of results on stdout).
13
+ //
14
+ // Byte parity: builder results and snapshot-helper outputs are returned
15
+ // VERBATIM (the TS object literals' own key order rides JSON.stringify),
16
+ // and scripted SESSION runs return their full event trace - pushes with
17
+ // complete payloads, acks/failures, snapshot resolutions, terminal
18
+ // callbacks, log events, flushes, metrics counters, close - so the
19
+ // ReScript side must reproduce field presence AND insertion order exactly.
20
+ // Determinism: hosts are fully scripted (push outcomes, snapshot outcomes,
21
+ // wire contexts, envelope shapes, recovered turns, runtime metadata);
22
+ // retry cadences are configured to millisecond-scale delays so the traces
23
+ // pin the LOGGED delay values while real time stays tiny; the stats
24
+ // interval is disabled (0) in session runs; traces capture only
25
+ // deterministic metric counters (never wall-clock ages).
26
+ //
27
+ // SECRETS: the oracle only ever sees the conformance suite's synthetic
28
+ // payloads. The output is a local test artifact (.differential/ is
29
+ // gitignored, never published) and stays unminified for debuggability.
30
+ import { mkdir } from 'node:fs/promises';
31
+ import { dirname, join } from 'node:path';
32
+ import { fileURLToPath } from 'node:url';
33
+ import { build } from 'esbuild';
34
+
35
+ const packageRoot = dirname(dirname(fileURLToPath(import.meta.url)));
36
+
37
+ const driverSource = `
38
+ import {
39
+ createSessionPipeline,
40
+ createSessionPipelineBuilders,
41
+ defaultOutboxMaxInFlightPushes,
42
+ isConnectionLostPushError,
43
+ isConnectionWaitPushError,
44
+ mergeSnapshotItems,
45
+ preReduceSnapshotItems,
46
+ rawSnapshotItemsForTurn,
47
+ } from './src/pipeline/integration';
48
+ import { outboxEntryKinds } from './src/pipeline/contracts';
49
+ import { phoenixPushErrors } from './src/phoenix';
50
+ import {
51
+ rememberTurnTraceparent,
52
+ __resetTurnTraceparentsForTest,
53
+ } from './src/turnTrace';
54
+
55
+ function sleep(ms) {
56
+ return new Promise((resolve) => {
57
+ setTimeout(resolve, ms);
58
+ });
59
+ }
60
+
61
+ // The scripted row-command envelope shared with the ReScript conformance
62
+ // side (both implement this exact shape over the same case JSON, so the
63
+ // seam itself is identical while the builder's spread/override semantics
64
+ // around it are what the comparison pins).
65
+ function scriptedEnvelope(caseInput) {
66
+ return (eventType, sessionId, sourceMessageSeq, extraMetadata) => ({
67
+ ...(caseInput.envelopeBase ?? {}),
68
+ type: eventType,
69
+ thread: sessionId,
70
+ ...(sourceMessageSeq === undefined ? {} : { envelope_seq: sourceMessageSeq }),
71
+ ...(extraMetadata === undefined ? {} : { local_runner_metadata: extraMetadata }),
72
+ });
73
+ }
74
+
75
+ function wireOf(spec) {
76
+ return {
77
+ workspaceSlug: spec.workspaceSlug,
78
+ channelSlug: spec.channelSlug,
79
+ kandanThreadId: spec.threadId ?? undefined,
80
+ codexThreadId: spec.harnessSessionId ?? undefined,
81
+ rootSeq: spec.rootSeq ?? undefined,
82
+ ...(spec.leaseEpoch === undefined ? {} : { leaseEpoch: spec.leaseEpoch }),
83
+ };
84
+ }
85
+
86
+ function seedTraceparents(caseInput) {
87
+ __resetTurnTraceparentsForTest();
88
+ for (const entry of caseInput.traceparents ?? []) {
89
+ rememberTurnTraceparent(entry.threadId, entry.traceparent);
90
+ }
91
+ }
92
+
93
+ function runBuildersCase(caseInput) {
94
+ seedTraceparents(caseInput);
95
+ const recovered = new Set(caseInput.recoveredTurns ?? []);
96
+ const wires = (caseInput.wires ?? []).map(wireOf);
97
+ let wireIndex = 0;
98
+ const builders = createSessionPipelineBuilders({
99
+ instanceId: caseInput.instanceId ?? 'instance-parity',
100
+ wire: () => wires[wireIndex],
101
+ runnerPayload: scriptedEnvelope(caseInput),
102
+ isRecoveredTurn: (turnId) => recovered.has(turnId),
103
+ });
104
+ const context = {
105
+ remember: () => {},
106
+ recall: () => undefined,
107
+ };
108
+ return {
109
+ results: (caseInput.calls ?? []).map((call) => {
110
+ wireIndex = call.wireIndex ?? 0;
111
+ const builder = builders[call.kind];
112
+ if (builder === undefined) {
113
+ return { missingBuilder: true };
114
+ }
115
+ return builder.build(call.data ?? {}, context);
116
+ }),
117
+ };
118
+ }
119
+
120
+ function scriptedFailure(spec) {
121
+ switch (spec.factory) {
122
+ case 'socketClosed':
123
+ return phoenixPushErrors.socketClosed();
124
+ case 'reconnectFailed':
125
+ return phoenixPushErrors.reconnectFailed();
126
+ case 'socketNotOpen':
127
+ return phoenixPushErrors.socketNotOpen();
128
+ case 'clientClosedWait':
129
+ return phoenixPushErrors.clientClosed('wait_for_connection');
130
+ case 'clientClosedReply':
131
+ return phoenixPushErrors.clientClosed('reply');
132
+ case 'notConnected':
133
+ return phoenixPushErrors.notConnected();
134
+ case 'connectionWaitTimeout':
135
+ return phoenixPushErrors.connectionWaitTimeout(spec.timeoutMs ?? 5, spec.event ?? 'evt');
136
+ case 'replyTimeout':
137
+ return phoenixPushErrors.replyTimeout(spec.timeoutMs ?? 5, spec.event ?? 'evt');
138
+ default:
139
+ return new Error(spec.message ?? 'scripted push failure');
140
+ }
141
+ }
142
+
143
+ function runClassifierCase(caseInput) {
144
+ const failure = scriptedFailure(caseInput.failure ?? {});
145
+ return {
146
+ lost: isConnectionLostPushError(failure),
147
+ wait: isConnectionWaitPushError(failure),
148
+ message: failure.message,
149
+ };
150
+ }
151
+
152
+ async function runSessionCase(caseInput) {
153
+ seedTraceparents(caseInput);
154
+ const trace = [];
155
+ const recovered = new Set(caseInput.recoveredTurns ?? []);
156
+ const wires = (caseInput.wires ?? []).map(wireOf);
157
+ let wireIndex = 0;
158
+ const turnSeqs = new Map();
159
+ const retryAttempts = new Map();
160
+ const resumeAttempts = new Map();
161
+ const ladders = new Map();
162
+ const runtimeMetadata = new Map();
163
+ for (const entry of caseInput.runtimeMetadata ?? []) {
164
+ runtimeMetadata.set(entry.seq, entry.metadata);
165
+ }
166
+ const pushScript = [...(caseInput.pushScript ?? [])];
167
+ const snapshotScript = new Map();
168
+ for (const entry of caseInput.snapshotScript ?? []) {
169
+ const queue = snapshotScript.get(entry.turnId) ?? [];
170
+ queue.push(entry);
171
+ snapshotScript.set(entry.turnId, queue);
172
+ }
173
+
174
+ const pipeline = createSessionPipeline({
175
+ instanceId: caseInput.instanceId ?? 'instance-parity',
176
+ threadKey: caseInput.threadKey ?? 'thread-parity',
177
+ persistDir: undefined,
178
+ push: async (event, payload, _timeoutMs, onSent) => {
179
+ trace.push({ t: 'push', event, payload });
180
+ onSent?.();
181
+ const step = pushScript.shift() ?? { kind: 'ack' };
182
+ if (step.delayMs !== undefined) {
183
+ await sleep(step.delayMs);
184
+ }
185
+ if (step.kind === 'ack') {
186
+ trace.push({ t: 'ack' });
187
+ return step.reply ?? { ok: true };
188
+ }
189
+ trace.push({ t: 'pushFail', mode: step.mode ?? 'plain' });
190
+ if (step.mode === 'wait') {
191
+ throw phoenixPushErrors.connectionWaitTimeout(5, event);
192
+ }
193
+ if (step.mode === 'lost') {
194
+ throw phoenixPushErrors.socketClosed();
195
+ }
196
+ throw new Error(step.message ?? 'scripted push failure');
197
+ },
198
+ wire: () => wires[wireIndex],
199
+ runnerPayload: scriptedEnvelope(caseInput),
200
+ runtimeMetadataForSourceSeq: (seq) =>
201
+ seq === undefined ? undefined : runtimeMetadata.get(seq),
202
+ sourceSeqForTurn: (turnId) => turnSeqs.get(turnId),
203
+ autoRetryAttemptsForSeq: (seq) => retryAttempts.get(seq) ?? 0,
204
+ midStreamResumeAttemptAtMsForSeq: (seq) => resumeAttempts.get(seq),
205
+ ladderHistoryForSeq: (seq, fate) => ladders.get(seq + ':' + fate),
206
+ isRecoveredTurn: (turnId) => recovered.has(turnId),
207
+ resolveSnapshot: async (turnId) => {
208
+ const queue = snapshotScript.get(turnId) ?? [];
209
+ const step = queue.shift() ?? { ok: true, items: [] };
210
+ trace.push({ t: 'resolveSnapshot', turnId, ok: step.ok === true });
211
+ if (step.delayMs !== undefined) {
212
+ await sleep(step.delayMs);
213
+ }
214
+ if (step.ok === true) {
215
+ return { items: step.items ?? [] };
216
+ }
217
+ throw new Error(step.message ?? 'scripted snapshot failure');
218
+ },
219
+ onTurnTerminal: (turnId, outcome, reason, retryableEmptyTurn, autoResume, fate) => {
220
+ trace.push({
221
+ t: 'terminal',
222
+ turnId,
223
+ outcome,
224
+ reason: reason ?? null,
225
+ retryableEmptyTurn: retryableEmptyTurn === true,
226
+ autoResumeMidStreamStall: autoResume === true,
227
+ fate: fate ?? null,
228
+ });
229
+ },
230
+ log: (event, fields) => {
231
+ trace.push({ t: 'log', event, fields });
232
+ },
233
+ linzumiAgentSession: caseInput.linzumiAgentSession === true,
234
+ outboxRetryDelaysMs: caseInput.outboxRetryDelaysMs ?? [1, 2],
235
+ outboxMaxInFlightPushes: caseInput.maxInFlightPushes ?? 1,
236
+ snapshotRetryDelaysMs: caseInput.snapshotRetryDelaysMs ?? undefined,
237
+ // Determinism: the periodic stats interval is disabled; the reporter
238
+ // still stops on close in the same order as production.
239
+ statsIntervalMs: 0,
240
+ });
241
+
242
+ for (const op of caseInput.ops ?? []) {
243
+ if (op.op === 'submit') pipeline.submitNotification(op.method, op.params ?? undefined);
244
+ else if (op.op === 'mapTurn') turnSeqs.set(op.turnId, op.seq);
245
+ else if (op.op === 'retryAttempts') retryAttempts.set(op.seq, op.attempts);
246
+ else if (op.op === 'resumeAttemptAt') resumeAttempts.set(op.seq, op.atMs);
247
+ else if (op.op === 'ladder') ladders.set(op.seq + ':' + op.fate, op.ladder);
248
+ else if (op.op === 'recover') recovered.add(op.turnId);
249
+ else if (op.op === 'notifyReady') pipeline.notifyTurnMappingReady(op.turnId);
250
+ else if (op.op === 'notifyFailed') pipeline.notifyTurnMappingFailed(op.turnId, op.reason);
251
+ else if (op.op === 'noteActivity') pipeline.noteTurnActivity(op.turnId, op.kind);
252
+ else if (op.op === 'lifecycle') pipeline.submitLifecycle(op.kind, op.reason);
253
+ else if (op.op === 'pause') pipeline.pause();
254
+ else if (op.op === 'resume') pipeline.resume();
255
+ else if (op.op === 'rebind') pipeline.rebindThreadKey(op.threadKey);
256
+ else if (op.op === 'setWire') wireIndex = op.index;
257
+ else if (op.op === 'sleep') await sleep(op.ms);
258
+ else if (op.op === 'metrics') {
259
+ const metrics = pipeline.metrics();
260
+ trace.push({
261
+ t: 'metrics',
262
+ value: {
263
+ depth: metrics.depth,
264
+ totalEnqueued: metrics.totalEnqueued,
265
+ totalAcked: metrics.totalAcked,
266
+ totalRetried: metrics.totalRetried,
267
+ totalDroppedBestEffort: metrics.totalDroppedBestEffort,
268
+ totalPermanentFailures: metrics.totalPermanentFailures,
269
+ paused: metrics.paused,
270
+ },
271
+ });
272
+ } else if (op.op === 'flush') {
273
+ try {
274
+ await pipeline.flushOutbox(op.timeoutMs ?? undefined);
275
+ trace.push({ t: 'flushed', ok: true });
276
+ } catch (error) {
277
+ trace.push({
278
+ t: 'flushed',
279
+ ok: false,
280
+ message: error instanceof Error ? error.message : String(error),
281
+ });
282
+ }
283
+ } else if (op.op === 'close') {
284
+ await pipeline.close(op.timeoutMs ?? undefined);
285
+ trace.push({ t: 'closed' });
286
+ }
287
+ }
288
+ return { trace };
289
+ }
290
+
291
+ async function runCase(input) {
292
+ switch (input.kind) {
293
+ case 'constants':
294
+ return {
295
+ defaultOutboxMaxInFlightPushes,
296
+ outboxEntryKinds,
297
+ };
298
+ case 'builders':
299
+ return runBuildersCase(input);
300
+ case 'classifier':
301
+ return runClassifierCase(input);
302
+ case 'rawItems':
303
+ return rawSnapshotItemsForTurn(input.response, input.turnId);
304
+ case 'preReduce':
305
+ return preReduceSnapshotItems(input.items);
306
+ case 'merge':
307
+ return mergeSnapshotItems(input.readItems, input.sessionItems);
308
+ case 'sessionRun':
309
+ return runSessionCase(input);
310
+ default:
311
+ return { error: 'unknown case kind ' + String(input.kind) };
312
+ }
313
+ }
314
+
315
+ async function runBatch() {
316
+ const chunks = [];
317
+ for await (const chunk of process.stdin) chunks.push(chunk);
318
+ const cases = JSON.parse(Buffer.concat(chunks).toString('utf8'));
319
+ const results = [];
320
+ for (const testCase of cases) {
321
+ results.push(await runCase(testCase));
322
+ }
323
+ process.stdout.write(JSON.stringify(results), () => {
324
+ process.exit(0);
325
+ });
326
+ }
327
+
328
+ runBatch().then(
329
+ () => {},
330
+ (error) => {
331
+ process.stderr.write(String(error && error.stack ? error.stack : error) + '\\n');
332
+ process.exit(1);
333
+ }
334
+ );
335
+ `;
336
+
337
+ const outDir = join(packageRoot, '.differential');
338
+ const outPath = join(outDir, 'core-integration-parity-oracle.mjs');
339
+
340
+ await mkdir(outDir, { recursive: true });
341
+
342
+ await build({
343
+ stdin: {
344
+ contents: driverSource,
345
+ resolveDir: packageRoot,
346
+ sourcefile: 'core-integration-parity-driver.ts',
347
+ loader: 'ts',
348
+ },
349
+ bundle: true,
350
+ platform: 'node',
351
+ target: 'node20',
352
+ format: 'esm',
353
+ outfile: outPath,
354
+ minify: false,
355
+ sourcemap: false,
356
+ legalComments: 'none',
357
+ logLevel: 'silent',
358
+ external: ['ws', 'undici', 'blessed', '@anthropic-ai/claude-agent-sdk'],
359
+ });
360
+
361
+ process.stdout.write(outPath + '\n');