@linzumi/cli 1.0.265 → 1.0.267
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.
- package/README.md +1 -1
- package/dist/impl-res/cloud-supervisor.mjs +90 -88
- package/dist/impl-res/index.js +293 -286
- package/dist/impl-ts/cloud-supervisor.mjs +90 -88
- package/dist/impl-ts/index.js +493 -485
- package/dist/impl-ts/tcp-tunnel-cli.mjs +2 -2
- package/dist/tcp-tunnel-cli.mjs +2 -2
- package/package.json +1 -1
- package/scripts/build-core-commander-seams-parity-oracle.mjs +111 -17
package/package.json
CHANGED
|
@@ -86,6 +86,9 @@ import {
|
|
|
86
86
|
recoverRetainedTerminalDebt,
|
|
87
87
|
} from './src/channelSession';
|
|
88
88
|
import {adoptAdtStreamBinding, installAdtPublicationBinding} from './src/pipeline/contracts';
|
|
89
|
+
import {createThreadOutbox} from './src/pipeline/outbox';
|
|
90
|
+
import {enqueueTerminalDebtRepair} from './src/pipeline/integration';
|
|
91
|
+
import {createHash} from 'node:crypto';
|
|
89
92
|
|
|
90
93
|
// --- Placeholder + snapshot plumbing --------------------------------------------
|
|
91
94
|
|
|
@@ -534,9 +537,59 @@ async function handleRespawn(testCase) {
|
|
|
534
537
|
|
|
535
538
|
// Spec: spec/commander-recovery-rules.md rule01 and rule05; retained terminal
|
|
536
539
|
// debt is not an unknown provider-start ACK and cannot reset unrelated jobs.
|
|
540
|
+
async function terminalDebtJournal(testCase) {
|
|
541
|
+
const control = testCase.control;
|
|
542
|
+
const logs = [];
|
|
543
|
+
const body = 'Synthetic completed answer.';
|
|
544
|
+
const outbox = createThreadOutbox({threadKey:'synthetic-terminal-debt', persistDir:scratch(),
|
|
545
|
+
push:async()=>{throw new Error('pending repair must not publish or resend provider work');},
|
|
546
|
+
builders:{'adt.terminal_attempt':{build:()=>{throw new Error('synthetic retained failure');}}},
|
|
547
|
+
retryDelaysMs:[], onPermanentFailure:()=>{}, log:(event,fields)=>logs.push({event,fields}),
|
|
548
|
+
});
|
|
549
|
+
try {
|
|
550
|
+
outbox.enqueue({kind:'adt.terminal_attempt',resolution:'must_ack',data:{seq:44,status:'processed',
|
|
551
|
+
turn_id:'synthetic-completed-turn',terminal_frame:{session_id:3600,lease_epoch:2,frame_index:40,
|
|
552
|
+
frame_kind:'terminal',assistant_phase:'final_answer',source_stream_key:'synthetic-rejected-key',body}}});
|
|
553
|
+
await outbox.flush(1000);
|
|
554
|
+
outbox.pause();
|
|
555
|
+
await outbox.journalSettled();
|
|
556
|
+
const gate = Promise.withResolvers();
|
|
557
|
+
const entered = Promise.withResolvers();
|
|
558
|
+
let settled = false;
|
|
559
|
+
let authority = true;
|
|
560
|
+
const barrierOutbox = {...outbox,
|
|
561
|
+
journalSettled:async()=>{entered.resolve();await gate.promise;await outbox.journalSettled();settled=true;},
|
|
562
|
+
terminalPublicationDebt:()=>!settled || control==='write-failure'
|
|
563
|
+
? {kind:'unavailable',reason:'controlled journal not durable'} : outbox.terminalPublicationDebt(),
|
|
564
|
+
};
|
|
565
|
+
const repair = enqueueTerminalDebtRepair(barrierOutbox,{threadId:'synthetic-terminal-debt',sourceSeq:44,
|
|
566
|
+
sessionId:3600,originalLeaseEpoch:2,authoritativeTerminal:false,authorize:()=>authority,
|
|
567
|
+
binding:{session_id:3600,lease_epoch:4,next_frame_index:39,
|
|
568
|
+
checkpoint_config:{version:3,thresholds:{max_bytes:512,max_deltas:1,max_interval_ms:2000}},
|
|
569
|
+
final_checkpoint:{frame_index:38,source_stream_key:'synthetic-canonical-key',
|
|
570
|
+
body_sha256:createHash('sha256').update(body).digest('hex'),byte_len:Buffer.byteLength(body)}}},
|
|
571
|
+
(event,fields)=>logs.push({event,fields}));
|
|
572
|
+
const first = await Promise.race([entered.promise.then(()=>'waiting'),repair.then(()=>'finished')]);
|
|
573
|
+
const before = outbox.pendingTerminalEntries().length;
|
|
574
|
+
authority = control !== 'superseded';
|
|
575
|
+
gate.resolve();
|
|
576
|
+
const result = await repair;
|
|
577
|
+
return {first,before,count:outbox.pendingTerminalEntries().length,ready:result.kind==='ready',result,logs};
|
|
578
|
+
} finally {await outbox.close(0);}
|
|
579
|
+
}
|
|
580
|
+
|
|
537
581
|
async function terminalDebtStorm(testCase) {
|
|
538
|
-
const
|
|
582
|
+
const ackLease = testCase.control === 'newer-ack-lease' ? 2 : testCase.control === 'future-ack' ? 4 : 1;
|
|
583
|
+
const binding = {session_id: 3600, lease_epoch: ackLease, next_frame_index: 39,
|
|
539
584
|
checkpoint_config: {version: 3, thresholds: {max_bytes: 1, max_deltas: 1, max_interval_ms: 2000}}};
|
|
585
|
+
// Spec: commander-recovery-rules authenticated-terminal-evidence. The
|
|
586
|
+
// retained frame and original ACK belong to one attempt across lease churn.
|
|
587
|
+
const retainedLease = testCase.control === 'newer-retained-lease' ? 2 : 1;
|
|
588
|
+
const body = 'Synthetic completed answer.';
|
|
589
|
+
const reconciledBinding = {...binding, lease_epoch: 3, final_checkpoint: {
|
|
590
|
+
frame_index: 38, source_stream_key: 'synthetic-canonical-key',
|
|
591
|
+
body_sha256: createHash('sha256').update(body).digest('hex'), byte_len: Buffer.byteLength(body),
|
|
592
|
+
}};
|
|
540
593
|
const adopted = adoptAdtStreamBinding(binding, 44, 0);
|
|
541
594
|
if (adopted.kind !== 'accepted') throw new Error('terminal debt fixture binding refused');
|
|
542
595
|
const session = adopted.session;
|
|
@@ -544,6 +597,26 @@ async function terminalDebtStorm(testCase) {
|
|
|
544
597
|
let resets = 0;
|
|
545
598
|
let restarts = 0;
|
|
546
599
|
let reconciliations = 0;
|
|
600
|
+
let repairs = 0;
|
|
601
|
+
const outbox = createThreadOutbox({threadKey:'synthetic-terminal-debt',
|
|
602
|
+
persistDir:scratch(),
|
|
603
|
+
push:async()=>{throw new Error('failed builder must not publish');},
|
|
604
|
+
builders:{'adt.terminal_attempt':{build:()=>{throw new Error('synthetic final rejection');}}},
|
|
605
|
+
retryDelaysMs:[], onPermanentFailure:()=>{}, log:(event,fields)=>logs.push({event,fields}),
|
|
606
|
+
});
|
|
607
|
+
try {
|
|
608
|
+
outbox.enqueue({kind:'adt.terminal_attempt',resolution:'must_ack',data:{seq:44,status:'processed',
|
|
609
|
+
turn_id:'synthetic-completed-turn',terminal_frame:{session_id:3600,lease_epoch:retainedLease,
|
|
610
|
+
frame_index:40,frame_kind:'terminal',assistant_phase:'final_answer',source_stream_key:'synthetic-rejected-key',body}}});
|
|
611
|
+
await outbox.flush(1000);
|
|
612
|
+
outbox.pause();
|
|
613
|
+
// Queue drain completion is distinct from durable journal settlement.
|
|
614
|
+
await outbox.journalSettled();
|
|
615
|
+
const durableDebt = outbox.terminalPublicationDebt();
|
|
616
|
+
if (typeof durableDebt !== 'object' || durableDebt.kind !== 'repair_needed' || durableDebt.count !== 1) {
|
|
617
|
+
throw new Error('warm repair fixture must have one durable failed terminal: ' + JSON.stringify(durableDebt));
|
|
618
|
+
}
|
|
619
|
+
const original = JSON.stringify(outbox.failedTerminalEntries());
|
|
547
620
|
const transport = {
|
|
548
621
|
push: async (_topic, event) => {
|
|
549
622
|
if (event === 'adt_binding_ack') return {status: 'ok', response: {ok: true}};
|
|
@@ -551,7 +624,7 @@ async function terminalDebtStorm(testCase) {
|
|
|
551
624
|
reconciliations += 1;
|
|
552
625
|
if(testCase.control === 'repair-unavailable' && reconciliations > 1) return {status:'ok',response:{ok:true,adt:{verdict:'still_unavailable'}}};
|
|
553
626
|
return {status: 'ok', response: {
|
|
554
|
-
ok: true, adt: {verdict: 'already_applied', binding: testCase.control === 'malformed-binding' ? {session_id: 3600} :
|
|
627
|
+
ok: true, adt: {verdict: 'already_applied', binding: testCase.control === 'malformed-binding' ? {session_id: 3600} : reconciledBinding},
|
|
555
628
|
}};
|
|
556
629
|
}
|
|
557
630
|
throw new Error('unexpected terminal-debt fixture event: ' + event);
|
|
@@ -560,7 +633,7 @@ async function terminalDebtStorm(testCase) {
|
|
|
560
633
|
};
|
|
561
634
|
const candidate = registerRequiredAdtCandidate({transport,
|
|
562
635
|
identity: {thread_id: 'synthetic-terminal-debt', source_seq: 44, session_id: 3600,
|
|
563
|
-
lease_epoch:
|
|
636
|
+
lease_epoch: ackLease, checkpoint_config_version: 3},
|
|
564
637
|
installFreshBinding: raw => {
|
|
565
638
|
const fresh = adoptAdtStreamBinding(raw, 44, 0);
|
|
566
639
|
if (fresh.kind !== 'accepted') return false;
|
|
@@ -569,17 +642,23 @@ async function terminalDebtStorm(testCase) {
|
|
|
569
642
|
},
|
|
570
643
|
publicationSession: () => testCase.localState === 'idle' ? undefined : session,
|
|
571
644
|
failedTerminalEntries: () => {
|
|
572
|
-
const entries =
|
|
573
|
-
|
|
574
|
-
terminal_frame:
|
|
575
|
-
|
|
576
|
-
source_stream_key: 'synthetic-rejected-key', body: 'Synthetic completed answer.'}}}];
|
|
645
|
+
const entries = outbox.failedTerminalEntries().map(entry => ({...entry,data:{...entry.data,
|
|
646
|
+
...(testCase.control === 'malformed-repair-presence' ? {terminal_repair:undefined} : {}),
|
|
647
|
+
terminal_frame:{...entry.data.terminal_frame,session_id:testCase.control === 'foreign-debt' ? 3601 : 3600,
|
|
648
|
+
lease_epoch:testCase.control === 'future-debt' ? 4 : testCase.control === 'fractional-debt' ? 1.5 : retainedLease}}}));
|
|
577
649
|
if (testCase.control === 'missing-debt') return [];
|
|
578
650
|
if (testCase.control === 'ambiguous-debt') return [...entries, {...entries[0], entrySeq: 62}];
|
|
579
651
|
return entries;
|
|
580
652
|
},
|
|
653
|
+
repairTerminalDebt:async (fresh,authoritativeTerminal,authorize,evidenceEpoch)=>{
|
|
654
|
+
if(evidenceEpoch !== retainedLease) throw new Error('repair callback received ACK lease instead of retained evidence');
|
|
655
|
+
const result=await enqueueTerminalDebtRepair(outbox,{threadId:'synthetic-terminal-debt',sourceSeq:44,
|
|
656
|
+
sessionId:3600,originalLeaseEpoch:evidenceEpoch,binding:fresh,authoritativeTerminal,authorize},()=>{});
|
|
657
|
+
if(result.kind!=='ready') throw new Error('actual repair selector refused: '+result.message);
|
|
658
|
+
repairs += 1;
|
|
659
|
+
},
|
|
581
660
|
onUnrecoverable: () => {restarts += 1;},
|
|
582
|
-
log: event => logs.push(event),
|
|
661
|
+
log: (event,fields) => logs.push({event,fields}),
|
|
583
662
|
});
|
|
584
663
|
try {
|
|
585
664
|
await acknowledgeRequiredAdtCandidate({topic: 'local_runner:fixture', payload: adopted.ackPayload, ticket: candidate});
|
|
@@ -590,12 +669,16 @@ async function terminalDebtStorm(testCase) {
|
|
|
590
669
|
closeRequiredAdtAdmissionForDisconnect(transport);
|
|
591
670
|
await reconcileRequiredAdtCandidates({transport, topic: 'local_runner:fixture'});
|
|
592
671
|
}
|
|
593
|
-
return {resets, restarts,
|
|
672
|
+
return {resets, restarts, repairs, originalUnchanged:JSON.stringify(outbox.failedTerminalEntries())===original,
|
|
673
|
+
corrections:outbox.pendingTerminalEntries().map(entry=>({originalLease:entry.data.terminal_repair?.original_lease_epoch,
|
|
674
|
+
lease:entry.data.terminal_frame?.lease_epoch,body:entry.data.terminal_frame?.body})),
|
|
675
|
+
retained: findRequiredAdtCandidate(transport,
|
|
594
676
|
identity => identity.thread_id === 'synthetic-terminal-debt' && identity.source_seq === 44) === candidate,
|
|
595
677
|
providerEffect: candidate.providerEffect, verdict: candidate.verdict,
|
|
596
678
|
nextProviderAdmission: consumeRequiredAdtAdmission(candidate).kind,
|
|
597
679
|
admission: requiredTransportFinalAdmission(transport).kind, logs};
|
|
598
680
|
} finally {releaseRequiredAdtCandidate(candidate);}
|
|
681
|
+
} finally {await outbox.close(0);}
|
|
599
682
|
}
|
|
600
683
|
|
|
601
684
|
async function handle(testCase) {
|
|
@@ -603,24 +686,33 @@ async function handle(testCase) {
|
|
|
603
686
|
case 'terminalDebtCold': {
|
|
604
687
|
const events = [];
|
|
605
688
|
let repairs = 0;
|
|
606
|
-
const
|
|
607
|
-
const
|
|
689
|
+
const retainedEpoch = ['ack-before-frame','binding-before-frame'].includes(testCase.control) ? 2 : 1;
|
|
690
|
+
const ackEpoch = ['ack-after-frame','binding-before-ack'].includes(testCase.control) ? 2 : 1;
|
|
691
|
+
const freshEpoch = testCase.control.startsWith('binding-before-') ? 1 : testCase.control.startsWith('ack-') ? 4 : 2;
|
|
692
|
+
const hasAnchor = testCase.control !== 'missing-anchor';
|
|
693
|
+
const ackVersion = ['ready','authoritative-terminal','missing-anchor'].includes(testCase.control) ? 7 : 9;
|
|
694
|
+
const identity = {thread_id:'synthetic-terminal-debt',source_seq:44,session_id:3600,lease_epoch:retainedEpoch,checkpoint_config_version:7};
|
|
695
|
+
const anchor = testCase.control === 'malformed-anchor' ? null : {...identity,
|
|
696
|
+
thread_id:testCase.control === 'foreign-anchor' ? 'foreign-thread' : identity.thread_id,
|
|
697
|
+
lease_epoch:testCase.control === 'fractional-anchor' ? 1.5 : ackEpoch,checkpoint_config_version:ackVersion};
|
|
698
|
+
const binding = {session_id:3600,lease_epoch:freshEpoch,next_frame_index:39,checkpoint_config:{version:8,thresholds:{max_bytes:512,max_deltas:1,max_interval_ms:2000}}};
|
|
608
699
|
const transport = {push:async (_topic,event,payload) => {
|
|
609
700
|
events.push(event);
|
|
610
701
|
if(event === 'terminal_debt_identity') {
|
|
611
702
|
if(testCase.control === 'disconnect') closeRequiredAdtAdmissionForDisconnect(transport);
|
|
612
|
-
return {status:'ok',response:{ok:true,identity:{...identity,...(testCase.control === 'foreign' ? {thread_id:'foreign-thread'} : {})}}};
|
|
703
|
+
return {status:'ok',response:{ok:true,identity:{...identity,...(hasAnchor ? {ack_identity:anchor} : {}),...(testCase.control === 'foreign' ? {thread_id:'foreign-thread'} : {})}}};
|
|
613
704
|
}
|
|
614
705
|
if(event === 'adt_binding_reconcile') {
|
|
615
|
-
if(payload.checkpoint_config_version !==
|
|
616
|
-
return {status:'ok',response:{ok:true,adt:{verdict:'already_applied',binding}}};
|
|
706
|
+
if(payload.checkpoint_config_version !== ackVersion || payload.lease_epoch !== ackEpoch) throw new Error('cold lookup changed durable ACK identity');
|
|
707
|
+
return {status:'ok',response:{ok:true,adt:{verdict:testCase.control === 'authoritative-terminal' ? 'authoritative_terminal' : testCase.control === 'missing-anchor' ? 'applied' : 'already_applied',binding}}};
|
|
617
708
|
}
|
|
618
709
|
throw new Error('cold recovery attempted unexpected event: '+event);
|
|
619
710
|
}};
|
|
620
711
|
const pipeline = {
|
|
621
|
-
failedTerminalEntries:()=>[{entrySeq:61,kind:'adt.terminal_attempt',data:{seq:44,status:'processed',turn_id:'synthetic-completed-turn',terminal_frame:{session_id:3600,lease_epoch:
|
|
712
|
+
failedTerminalEntries:()=>[{entrySeq:61,kind:'adt.terminal_attempt',data:{seq:44,status:'processed',turn_id:'synthetic-completed-turn',terminal_frame:{session_id:3600,lease_epoch:retainedEpoch,frame_index:40,frame_kind:'terminal',assistant_phase:'final_answer',source_stream_key:'wrong-key',body:'Synthetic completed answer.'}}}],
|
|
622
713
|
repairTerminalDebt:async request => {
|
|
623
|
-
|
|
714
|
+
const terminal = testCase.control === 'authoritative-terminal';
|
|
715
|
+
if(request.sessionId !== 3600 || request.originalLeaseEpoch !== retainedEpoch || request.sourceSeq !== 44 || request.binding !== (terminal ? null : binding) || request.authoritativeTerminal !== terminal) throw new Error('cold repair identity mismatch');
|
|
624
716
|
if(!request.authorize({seq:44})) throw new Error('cold repair unexpectedly unauthorized');
|
|
625
717
|
repairs += 1;
|
|
626
718
|
return {kind:'ready',id:'fixture',serializedData:'fixture'};
|
|
@@ -636,6 +728,8 @@ async function handle(testCase) {
|
|
|
636
728
|
}
|
|
637
729
|
case 'terminalDebtStorm':
|
|
638
730
|
return await terminalDebtStorm(testCase);
|
|
731
|
+
case 'terminalDebtJournal':
|
|
732
|
+
return await terminalDebtJournal(testCase);
|
|
639
733
|
case 'controlDispatch':
|
|
640
734
|
return await handleControlDispatch(testCase);
|
|
641
735
|
case 'staleness':
|