@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,296 @@
1
+ // Spec: kandan/plans/2026-07-10-compute-nodes-rescript-commander-zero-ts-program.md
2
+ // (M3 cluster 10, commander core).
3
+ // Relationship: Builds the TS-side PARITY ORACLE for the startup
4
+ // resurrection scan of the ReScript commander port, the sibling of
5
+ // build-queue-parity-oracle.mjs (cluster 5). The oracle bundles the REAL
6
+ // TS module (src/startupResumeScan.ts - the 2026-07-11
7
+ // lease-adopted-no-resurrection incident fix; dossier:
8
+ // kandan/server_v2/test/fixtures/prod-failures/
9
+ // runner_restart_lease_adopted_no_resurrection_2026-07-11.md) behind the
10
+ // cluster 1/2 one-shot batch driver: a JSON array of cases on stdin, a
11
+ // JSON array of results on stdout. The ReScript package's
12
+ // CoreStartupResumeScanParityConformance drives the SAME inputs through
13
+ // the ported module and asserts:
14
+ // - constants parity (terminal statuses, age gate, concurrency /
15
+ // stagger / retry-backoff ladders);
16
+ // - fold parity (foldOutboxTurnSignals over raw journal bytes, encoded
17
+ // in map-insertion order so even the fold's internal ordering is
18
+ // pinned);
19
+ // - classification parity (classifyUnfinishedThreadWork matrices);
20
+ // - scripted SCAN RUNS: runStartupResumeScan with every effect
21
+ // (inspect/drain/respawn/publish/seq-in-flight/shutdown/sleep/log)
22
+ // scripted, a virtual clock advanced only by the scripted sleep, and
23
+ // ONE shared trace of effect calls + log events in order - compared
24
+ // byte-for-byte across impls, so the bounded scheduler's interleaving
25
+ // itself (worker pool, shared stagger chain, retry ladders, shutdown
26
+ // aborts) is the contract.
27
+ //
28
+ // Determinism: nothing in a scan case touches the real clock or timers -
29
+ // sleep records the requested delay, advances the virtual clock, and
30
+ // resolves immediately; scripted effect outcomes resolve in order;
31
+ // shutdown flips on a scripted effect-call count. The driver's effect
32
+ // functions return plain resolved/rejected promises (never async
33
+ // functions) so both impls award identical microtask hops.
34
+ //
35
+ // SECRETS: the oracle only ever sees the conformance suite's synthetic
36
+ // fixtures; nothing here logs case contents.
37
+ //
38
+ // The output is a local test artifact (.differential/ is gitignored,
39
+ // never published) and stays unminified for debuggability.
40
+ import { mkdir } from 'node:fs/promises';
41
+ import { dirname, join } from 'node:path';
42
+ import { fileURLToPath } from 'node:url';
43
+ import { build } from 'esbuild';
44
+
45
+ const packageRoot = dirname(dirname(fileURLToPath(import.meta.url)));
46
+
47
+ const driverSource = `
48
+ import {
49
+ classifyUnfinishedThreadWork,
50
+ defaultResumeSignalMaxAgeMs,
51
+ defaultStartupResumeConcurrency,
52
+ defaultStartupResumeRetryBackoffMs,
53
+ defaultStartupResumeStaggerMs,
54
+ defaultStartupRespawnRetryBackoffMs,
55
+ foldOutboxTurnSignals,
56
+ runStartupResumeScan,
57
+ terminalMessageStateStatuses,
58
+ } from './src/startupResumeScan';
59
+
60
+ // --- Encoding helpers -------------------------------------------------------------
61
+
62
+ // Signals encoded in MAP-INSERTION ORDER: the fold's internal ordering is
63
+ // part of the parity contract (classification iterates the map).
64
+ function encodeSignals(map) {
65
+ return Array.from(map.values()).map((signal) => ({
66
+ sourceSeq: signal.sourceSeq,
67
+ sawActivity: signal.sawActivity,
68
+ ...(signal.lastMessageStateStatus === undefined
69
+ ? {}
70
+ : { lastMessageStateStatus: signal.lastMessageStateStatus }),
71
+ ...(signal.newestAtMs === undefined ? {} : { newestAtMs: signal.newestAtMs }),
72
+ }));
73
+ }
74
+
75
+ function signalMapOf(spec) {
76
+ if (typeof spec.journalRaw === 'string') {
77
+ return foldOutboxTurnSignals(spec.journalRaw);
78
+ }
79
+ const map = new Map();
80
+ for (const signal of spec.signals ?? []) {
81
+ map.set(signal.sourceSeq, {
82
+ sourceSeq: signal.sourceSeq,
83
+ sawActivity: signal.sawActivity ?? false,
84
+ lastMessageStateStatus: signal.lastMessageStateStatus ?? undefined,
85
+ newestAtMs: signal.newestAtMs ?? undefined,
86
+ });
87
+ }
88
+ return map;
89
+ }
90
+
91
+ function inputsOf(spec) {
92
+ return {
93
+ pendingInboundSeqs: spec.pendingInboundSeqs ?? [],
94
+ ackedInboundSeqs: spec.ackedInboundSeqs ?? [],
95
+ inboundHighWaterSeq: spec.inboundHighWaterSeq ?? undefined,
96
+ appliedFloorSeq: spec.appliedFloorSeq ?? undefined,
97
+ outboxTurnSignals: signalMapOf(spec),
98
+ };
99
+ }
100
+
101
+ function encodeWork(work) {
102
+ return {
103
+ unfinished: work.unfinished,
104
+ seqs: work.seqs.map((entry) => ({ sourceSeq: entry.sourceSeq, shape: entry.shape })),
105
+ hasPendingInbound: work.hasPendingInbound,
106
+ loudTerminalSeqs: [...work.loudTerminalSeqs],
107
+ watermarkGapOnly: work.watermarkGapOnly,
108
+ };
109
+ }
110
+
111
+ // --- Case handlers ----------------------------------------------------------------
112
+
113
+ function handleConstants() {
114
+ return {
115
+ terminalMessageStateStatuses: Array.from(terminalMessageStateStatuses),
116
+ defaultResumeSignalMaxAgeMs,
117
+ defaultStartupResumeConcurrency,
118
+ defaultStartupResumeStaggerMs,
119
+ defaultStartupResumeRetryBackoffMs: [...defaultStartupResumeRetryBackoffMs],
120
+ defaultStartupRespawnRetryBackoffMs: [...defaultStartupRespawnRetryBackoffMs],
121
+ };
122
+ }
123
+
124
+ function handleFold(testCase) {
125
+ return { signals: encodeSignals(foldOutboxTurnSignals(testCase.raw ?? '')) };
126
+ }
127
+
128
+ function handleClassify(testCase) {
129
+ return encodeWork(
130
+ classifyUnfinishedThreadWork(inputsOf(testCase.inputs ?? {}), {
131
+ nowMs: testCase.nowMs ?? 0,
132
+ maxSignalAgeMs: testCase.maxSignalAgeMs ?? undefined,
133
+ })
134
+ );
135
+ }
136
+
137
+ // One scripted scan run. Every effect resolves from the case script; the
138
+ // shared events array is the trace both impls must reproduce byte for
139
+ // byte (virtual-time stamps included).
140
+ async function handleScan(testCase) {
141
+ const options = testCase.options ?? {};
142
+ const threads = testCase.threads ?? [];
143
+ const events = [];
144
+ let vnow = 0;
145
+ let effectOps = 0;
146
+ const shutdownAfterOps = options.shutdownAfterOps ?? undefined;
147
+ const scripts = new Map(
148
+ threads.map((thread) => [
149
+ thread.threadId,
150
+ {
151
+ drain: [...(thread.drainScript ?? [])],
152
+ respawn: [...(thread.respawnScript ?? [])],
153
+ publish: [...(thread.publishScript ?? [])],
154
+ inFlight: new Set(thread.inFlightSeqs ?? []),
155
+ },
156
+ ])
157
+ );
158
+
159
+ const summary = await runStartupResumeScan({
160
+ records: threads,
161
+ threadId: (record) => record.threadId,
162
+ inspect: (record) => {
163
+ events.push({ e: 'inspect', vt: vnow, thread: record.threadId });
164
+ const spec = record.inspect ?? {};
165
+ if (typeof spec.throw === 'string') {
166
+ throw new Error(spec.throw);
167
+ }
168
+ return inputsOf(spec);
169
+ },
170
+ resumePendingInbound: (record) => {
171
+ effectOps += 1;
172
+ const step = scripts.get(record.threadId).drain.shift() ?? 'clear';
173
+ if (typeof step === 'object' && step !== null) {
174
+ events.push({
175
+ e: 'drain',
176
+ vt: vnow,
177
+ thread: record.threadId,
178
+ outcome: 'throw:' + step.throw,
179
+ });
180
+ return Promise.reject(new Error(step.throw));
181
+ }
182
+ events.push({ e: 'drain', vt: vnow, thread: record.threadId, outcome: step });
183
+ return Promise.resolve(step);
184
+ },
185
+ respawnWorker: (record) => {
186
+ effectOps += 1;
187
+ const step = scripts.get(record.threadId).respawn.shift() ?? true;
188
+ if (typeof step === 'object' && step !== null) {
189
+ events.push({
190
+ e: 'respawn',
191
+ vt: vnow,
192
+ thread: record.threadId,
193
+ outcome: 'throw:' + step.throw,
194
+ });
195
+ return Promise.reject(new Error(step.throw));
196
+ }
197
+ events.push({ e: 'respawn', vt: vnow, thread: record.threadId, outcome: step });
198
+ return Promise.resolve(step);
199
+ },
200
+ seqInFlight: (record, sourceSeq) => scripts.get(record.threadId).inFlight.has(sourceSeq),
201
+ publishInterruptedTurnState: (record, sourceSeq, shape) => {
202
+ effectOps += 1;
203
+ const step = scripts.get(record.threadId).publish.shift() ?? 'ok';
204
+ if (typeof step === 'object' && step !== null) {
205
+ events.push({
206
+ e: 'publish',
207
+ vt: vnow,
208
+ thread: record.threadId,
209
+ seq: sourceSeq,
210
+ shape,
211
+ outcome: 'throw:' + step.throw,
212
+ });
213
+ return Promise.reject(new Error(step.throw));
214
+ }
215
+ events.push({
216
+ e: 'publish',
217
+ vt: vnow,
218
+ thread: record.threadId,
219
+ seq: sourceSeq,
220
+ shape,
221
+ outcome: step,
222
+ });
223
+ return Promise.resolve(undefined);
224
+ },
225
+ shuttingDown: () => shutdownAfterOps !== undefined && effectOps >= shutdownAfterOps,
226
+ log: (event, fields) => {
227
+ events.push({ e: 'log', vt: vnow, event, fields });
228
+ },
229
+ nowMs: options.nowMs ?? 0,
230
+ maxSignalAgeMs: options.maxSignalAgeMs ?? undefined,
231
+ concurrency: options.concurrency ?? undefined,
232
+ staggerMs: options.staggerMs ?? undefined,
233
+ retryBackoffMs: options.retryBackoffMs ?? undefined,
234
+ respawnRetryBackoffMs: options.respawnRetryBackoffMs ?? undefined,
235
+ sleep: (ms) => {
236
+ effectOps += 1;
237
+ events.push({ e: 'sleep', vt: vnow, ms });
238
+ vnow += ms;
239
+ return Promise.resolve(undefined);
240
+ },
241
+ });
242
+
243
+ return { summary, events };
244
+ }
245
+
246
+ async function handle(testCase) {
247
+ switch (testCase.op) {
248
+ case 'constants':
249
+ return handleConstants();
250
+ case 'fold':
251
+ return handleFold(testCase);
252
+ case 'classify':
253
+ return handleClassify(testCase);
254
+ case 'scan':
255
+ return await handleScan(testCase);
256
+ default:
257
+ return { threw: true, message: 'unknown op ' + String(testCase.op) };
258
+ }
259
+ }
260
+
261
+ let stdin = '';
262
+ process.stdin.setEncoding('utf8');
263
+ for await (const chunk of process.stdin) {
264
+ stdin += chunk;
265
+ }
266
+ const cases = JSON.parse(stdin);
267
+ const results = [];
268
+ for (const testCase of cases) {
269
+ results.push(await handle(testCase));
270
+ }
271
+ // Exit after stdout is fully flushed (the cluster 5 lesson: a bare
272
+ // process.exit(0) truncates large result arrays mid-pipe).
273
+ process.stdout.write(JSON.stringify(results), () => {
274
+ process.exit(0);
275
+ });
276
+ `;
277
+
278
+ await mkdir(join(packageRoot, '.differential'), { recursive: true });
279
+
280
+ await build({
281
+ stdin: {
282
+ contents: driverSource,
283
+ resolveDir: packageRoot,
284
+ sourcefile: 'core-startup-resume-scan-parity-driver.ts',
285
+ loader: 'ts',
286
+ },
287
+ bundle: true,
288
+ platform: 'node',
289
+ target: 'node20',
290
+ format: 'esm',
291
+ outfile: join(packageRoot, '.differential/core-startup-resume-scan-parity-oracle.mjs'),
292
+ minify: false,
293
+ sourcemap: false,
294
+ legalComments: 'none',
295
+ external: ['ws', 'undici', 'blessed', '@anthropic-ai/claude-agent-sdk'],
296
+ });